Bugzilla – Attachment 190218 Details for
Bug 14962
Temp Shelving Location
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14962: On Display code for REST API
Bug-14962-On-Display-code-for-REST-API.patch (text/plain), 51.25 KB, created by
Jake Deery
on 2025-12-05 14:51:14 UTC
(
hide
)
Description:
Bug 14962: On Display code for REST API
Filename:
MIME Type:
Creator:
Jake Deery
Created:
2025-12-05 14:51:14 UTC
Size:
51.25 KB
patch
obsolete
>From 3e5a3b9899c0b9fbea89c16fa6794d468a09a61f Mon Sep 17 00:00:00 2001 >From: Jake Deery <jake.deery@openfifth.co.uk> >Date: Mon, 1 Dec 2025 13:12:59 +0000 >Subject: [PATCH] Bug 14962: On Display code for REST API > >This patch adds all the various API endpoints, and modifies a few >existing API endpoints, in preparation for the On Display Vue app >Please see the test files commit for instructions on how to test this >bundle of patches. >--- > Koha/REST/V1/DisplayItems.pm | 259 ++++++++++++ > Koha/REST/V1/Displays.pm | 250 +++++++++++ > api/v1/swagger/definitions/display.yaml | 97 +++++ > .../swagger/definitions/display_config.yaml | 7 + > api/v1/swagger/definitions/displayitem.yaml | 31 ++ > api/v1/swagger/definitions/item.yaml | 20 + > api/v1/swagger/paths/displayitems.yaml | 395 ++++++++++++++++++ > api/v1/swagger/paths/displays.yaml | 273 ++++++++++++ > api/v1/swagger/paths/displays_config.yaml | 38 ++ > api/v1/swagger/paths/public_displayitems.yaml | 94 +++++ > api/v1/swagger/paths/public_displays.yaml | 124 ++++++ > api/v1/swagger/swagger.yaml | 38 ++ > 12 files changed, 1626 insertions(+) > create mode 100644 Koha/REST/V1/DisplayItems.pm > create mode 100644 Koha/REST/V1/Displays.pm > create mode 100644 api/v1/swagger/definitions/display.yaml > create mode 100644 api/v1/swagger/definitions/display_config.yaml > create mode 100644 api/v1/swagger/definitions/displayitem.yaml > create mode 100644 api/v1/swagger/paths/displayitems.yaml > create mode 100644 api/v1/swagger/paths/displays.yaml > create mode 100644 api/v1/swagger/paths/displays_config.yaml > create mode 100644 api/v1/swagger/paths/public_displayitems.yaml > create mode 100644 api/v1/swagger/paths/public_displays.yaml > >diff --git a/Koha/REST/V1/DisplayItems.pm b/Koha/REST/V1/DisplayItems.pm >new file mode 100644 >index 00000000000..d01696cad4e >--- /dev/null >+++ b/Koha/REST/V1/DisplayItems.pm >@@ -0,0 +1,259 @@ >+package Koha::REST::V1::DisplayItems; >+ >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Mojo::Base 'Mojolicious::Controller'; >+ >+use Koha::DisplayItem; >+use Koha::DisplayItems; >+use Koha::Displays; >+ >+use Try::Tiny qw( catch try ); >+use Scalar::Util qw( blessed ); >+ >+use Koha::BackgroundJob::BatchAddDisplayItems; >+use Koha::BackgroundJob::BatchDeleteDisplayItems; >+ >+=head1 API >+ >+=head2 Methods >+ >+=head3 list >+ >+=cut >+ >+sub list { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $displayitems = $c->objects->search( Koha::DisplayItems->new ); >+ return $c->render( status => 200, openapi => $displayitems ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+ >+} >+ >+=head3 get >+ >+=cut >+ >+sub get { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $displayitem = Koha::DisplayItems->find( >+ { >+ display_item_id => $c->param('display_item_id'), >+ display_id => $c->param('display_id'), >+ itemnumber => $c->param('item_id') >+ } >+ ); >+ return $c->render_resource_not_found("Display item") >+ unless $displayitem; >+ >+ return $c->render( status => 200, openapi => $c->objects->to_api($displayitem), ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 add >+ >+=cut >+ >+sub add { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $displayitem = Koha::DisplayItem->new_from_api( $c->req->json ); >+ $displayitem->store; >+ $c->res->headers->location( >+ $c->req->url->to_string . '/' . $displayitem->display_id . '/' . $displayitem->itemnumber ); >+ return $c->render( >+ status => 201, >+ openapi => $c->objects->to_api($displayitem), >+ ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 update >+ >+=cut >+ >+sub update { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $displayitem = Koha::DisplayItems->find( >+ { >+ display_item_id => $c->param('display_item_id'), >+ display_id => $c->param('display_id'), >+ itemnumber => $c->param('item_id') >+ } >+ ); >+ >+ return $c->render_resource_not_found("Display item") >+ unless $displayitem; >+ >+ return try { >+ $displayitem->set_from_api( $c->req->json ); >+ $displayitem->store(); >+ return $c->render( status => 200, openapi => $c->objects->to_api($displayitem), ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 delete >+ >+=cut >+ >+sub delete { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $displayitem = Koha::DisplayItems->find( >+ { >+ display_item_id => $c->param('display_item_id'), >+ display_id => $c->param('display_id'), >+ itemnumber => $c->param('item_id') >+ } >+ ); >+ >+ return $c->render_resource_not_found("Display item") >+ unless $displayitem; >+ >+ return try { >+ $displayitem->delete; >+ return $c->render_resource_deleted; >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 list_public >+ >+=cut >+ >+sub list_public { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $displayitems = $c->objects->search( Koha::DisplayItems->new ); >+ return $c->render( status => 200, openapi => $displayitems ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 get_public >+ >+=cut >+ >+sub get_public { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $displayitem = Koha::DisplayItems->find( >+ { >+ display_item_id => $c->param('display_item_id'), >+ display_id => $c->param('display_id'), >+ itemnumber => $c->param('item_id') >+ } >+ ); >+ return $c->render_resource_not_found("Display item") >+ unless $displayitem; >+ >+ return $c->render( status => 200, openapi => $c->objects->to_api($displayitem), ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 batch_add >+ >+Add multiple items to a display >+ >+=cut >+ >+sub batch_add { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $body = $c->req->json; >+ >+ # Validate that display exists >+ my $display = Koha::Displays->find( $body->{display_id} ); >+ return $c->render_resource_not_found("Display") >+ unless $display; >+ >+ # Enqueue background job for batch processing >+ my $job_id = Koha::BackgroundJob::BatchAddDisplayItems->new->enqueue( >+ { >+ display_id => $body->{display_id}, >+ item_ids => $body->{item_ids}, >+ date_remove => $body->{date_remove} // undef, >+ } >+ ); >+ >+ return $c->render( >+ status => 202, >+ openapi => { >+ job_id => $job_id, >+ message => "Batch add operation queued" >+ } >+ ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 batch_delete >+ >+Remove multiple items from displays >+ >+=cut >+ >+sub batch_delete { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $body = $c->req->json; >+ >+ # Enqueue background job for batch processing >+ my $job_id = Koha::BackgroundJob::BatchDeleteDisplayItems->new->enqueue( >+ { >+ item_ids => $body->{item_ids}, >+ display_id => $body->{display_id} // undef, >+ } >+ ); >+ >+ return $c->render( >+ status => 202, >+ openapi => { >+ job_id => $job_id, >+ message => "Batch delete operation queued" >+ } >+ ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+1; >diff --git a/Koha/REST/V1/Displays.pm b/Koha/REST/V1/Displays.pm >new file mode 100644 >index 00000000000..dc537825287 >--- /dev/null >+++ b/Koha/REST/V1/Displays.pm >@@ -0,0 +1,250 @@ >+package Koha::REST::V1::Displays; >+ >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Mojo::Base 'Mojolicious::Controller'; >+ >+use Koha::Display; >+use Koha::Displays; >+use Koha::DateUtils qw( dt_from_string ); >+ >+use Try::Tiny qw( catch try ); >+ >+=head1 API >+ >+=head2 Methods >+ >+=head3 config >+ >+Return the configuration options needed for the Display Vue app >+ >+=cut >+ >+sub config { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $patron = $c->stash('koha.user'); >+ >+ return $c->render( >+ status => 200, >+ openapi => { >+ settings => { >+ enabled => C4::Context->preference('UseDisplayModule'), >+ }, >+ }, >+ ); >+} >+ >+=head3 list >+ >+=cut >+ >+sub list { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $displays_set = Koha::Displays->new; >+ >+ my $active = $c->param('active'); >+ if ( defined $active && $active ) { >+ $displays_set = $displays_set->active; >+ } >+ >+ # Filter displays based on user's library permissions >+ my $patron = $c->stash('koha.user'); >+ if ($patron) { >+ my @restricted_branchcodes = $patron->libraries_where_can_edit_displays; >+ if (@restricted_branchcodes) { >+ >+ # User can only see displays from specific libraries >+ $displays_set = $displays_set->search( { 'me.display_branch' => { -in => \@restricted_branchcodes } } ); >+ } >+ >+ # If @restricted_branchcodes is empty, user has access to all displays >+ } >+ >+ my $displays = $c->objects->search($displays_set); >+ return $c->render( status => 200, openapi => $displays ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+ >+} >+ >+=head3 get >+ >+=cut >+ >+sub get { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $display = Koha::Displays->find( $c->param('display_id') ); >+ return $c->render_resource_not_found("Display") >+ unless $display; >+ >+ # Check if user has permission to view this display >+ my $patron = $c->stash('koha.user'); >+ if ($patron) { >+ my @restricted_branchcodes = $patron->libraries_where_can_edit_displays; >+ if (@restricted_branchcodes) { >+ >+ # User can only see displays from specific libraries >+ unless ( grep { $_ eq $display->display_branch } @restricted_branchcodes ) { >+ return $c->render_resource_not_found("Display"); >+ } >+ } >+ >+ # If @restricted_branchcodes is empty, user has access to all displays >+ } >+ >+ return $c->render( status => 200, openapi => $c->objects->to_api($display), ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 add >+ >+=cut >+ >+sub add { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $body = $c->req->json; >+ >+ my $display_items = delete $body->{display_items} || []; >+ >+ my $display = Koha::Display->new_from_api($body)->store; >+ $display->display_items($display_items); >+ >+ $c->res->headers->location( $c->req->url->to_string . '/' . $display->display_id ); >+ return $c->render( >+ status => 201, >+ openapi => $c->objects->to_api($display), >+ ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 update >+ >+=cut >+ >+sub update { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $display = Koha::Displays->find( $c->param('display_id') ); >+ >+ return $c->render_resource_not_found("Display") >+ unless $display; >+ >+ return try { >+ my $body = $c->req->json; >+ >+ my $display_items = delete $body->{display_items} || []; >+ >+ $display->set_from_api($body)->store; >+ $display->display_items($display_items); >+ >+ return $c->render( status => 200, openapi => $c->objects->to_api($display), ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 delete >+ >+=cut >+ >+sub delete { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $display = Koha::Displays->find( $c->param('display_id') ); >+ >+ return $c->render_resource_not_found("Display") >+ unless $display; >+ >+ return try { >+ $display->delete; >+ return $c->render_resource_deleted; >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 list_public >+ >+=cut >+ >+sub list_public { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $displays_set = Koha::Displays->new; >+ >+ my $active = $c->param('active'); >+ if ( defined $active && $active ) { >+ $displays_set = $displays_set->active; >+ } else { >+ my $today = dt_from_string->truncate( to => 'day' ); >+ $displays_set = $displays_set->search( >+ { >+ -or => [ >+ { end_date => { '>=' => $today } }, >+ { end_date => undef } >+ ] >+ } >+ ); >+ } >+ >+ my $displays = $c->objects->search($displays_set); >+ return $c->render( status => 200, openapi => $displays ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 get_public >+ >+=cut >+ >+sub get_public { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $display = Koha::Displays->find( $c->param('display_id') ); >+ >+ return $c->render_resource_not_found("Display") >+ unless $display; >+ >+ my $today = dt_from_string->truncate( to => 'day' )->ymd; >+ >+ if ( $display->end_date && $display->end_date < $today ) { >+ return $c->render_resource_not_found("Display"); >+ } >+ >+ return $c->render( status => 200, openapi => $c->objects->to_api($display), ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+1; >diff --git a/api/v1/swagger/definitions/display.yaml b/api/v1/swagger/definitions/display.yaml >new file mode 100644 >index 00000000000..6f135d650ce >--- /dev/null >+++ b/api/v1/swagger/definitions/display.yaml >@@ -0,0 +1,97 @@ >+--- >+type: object >+properties: >+ display_id: >+ type: integer >+ description: internally assigned display identifier >+ readOnly: true >+ display_name: >+ description: display name >+ type: string >+ start_date: >+ description: display start date >+ type: >+ - string >+ - "null" >+ format: date >+ end_date: >+ description: display end date >+ type: >+ - string >+ - "null" >+ format: date >+ enabled: >+ description: determines whether the display is active >+ type: boolean >+ display_location: >+ description: shelving location for the display >+ type: >+ - string >+ - "null" >+ display_code: >+ description: collection code for the display >+ type: >+ - string >+ - "null" >+ display_branch: >+ description: home branch for items while on display >+ type: >+ - string >+ - "null" >+ display_holding_branch: >+ description: holding branch for items while on display >+ type: >+ - string >+ - "null" >+ display_itype: >+ description: item type for items while on display >+ type: >+ - string >+ - "null" >+ staff_note: >+ description: staff note for the display >+ type: >+ - string >+ - "null" >+ public_note: >+ description: public note for the display >+ type: >+ - string >+ - "null" >+ display_days: >+ description: default number of days items will remain on display >+ type: >+ - integer >+ - "null" >+ display_return_over: >+ description: should the item be removed from the display when it is returned >+ type: string >+ enum: >+ - "yes - any library" >+ - "yes - except at home library" >+ - "no" >+ default: "no" >+ display_items: >+ type: >+ - array >+ - "null" >+ description: The object representing the display items >+ library: >+ type: >+ - object >+ - "null" >+ description: The object representing the display library >+ item_type: >+ type: >+ - object >+ - "null" >+ description: The object representing the display item type >+ _strings: >+ type: >+ - object >+ - "null" >+additionalProperties: false >+required: >+ - display_name >+ - enabled >+ - display_return_over >diff --git a/api/v1/swagger/definitions/display_config.yaml b/api/v1/swagger/definitions/display_config.yaml >new file mode 100644 >index 00000000000..535228aa01e >--- /dev/null >+++ b/api/v1/swagger/definitions/display_config.yaml >@@ -0,0 +1,7 @@ >+--- >+type: object >+properties: >+ settings: >+ type: object >+ description: List of sysprefs used for the Displays module >+additionalProperties: false >diff --git a/api/v1/swagger/definitions/displayitem.yaml b/api/v1/swagger/definitions/displayitem.yaml >new file mode 100644 >index 00000000000..2f75c59eca4 >--- /dev/null >+++ b/api/v1/swagger/definitions/displayitem.yaml >@@ -0,0 +1,31 @@ >+--- >+type: object >+properties: >+ display_item_id: >+ type: integer >+ description: primary key >+ display_id: >+ type: integer >+ description: foreign key to link to displays.display_id >+ itemnumber: >+ type: integer >+ description: items.itemnumber for the item on display >+ biblionumber: >+ type: integer >+ description: biblio.biblionumber for the bibliographic record on display >+ date_added: >+ description: the date the item was added to the display >+ type: >+ - string >+ - "null" >+ format: date >+ date_remove: >+ description: the date the item should be removed from the display >+ type: >+ - string >+ - "null" >+ format: date >+additionalProperties: false >+required: >+ - display_id >+ - itemnumber >diff --git a/api/v1/swagger/definitions/item.yaml b/api/v1/swagger/definitions/item.yaml >index 42dcd36e3e5..e0b7f3a4943 100644 >--- a/api/v1/swagger/definitions/item.yaml >+++ b/api/v1/swagger/definitions/item.yaml >@@ -38,6 +38,11 @@ properties: > - "null" > description: Internal library id for the library the item belongs to > maxLength: 10 >+ effective_home_library_id: >+ type: >+ - string >+ - "null" >+ description: Effective home library id - shows display branch if item is on an active display, otherwise regular home branch > purchase_price: > type: > - number >@@ -153,6 +158,11 @@ properties: > - "null" > description: Library that is currently in possession item > maxLength: 10 >+ effective_holding_library_id: >+ type: >+ - string >+ - "null" >+ description: Effective holding library id - shows display holding branch if item is on an active display, otherwise regular holding branch > timestamp: > type: string > format: date-time >@@ -197,6 +207,11 @@ properties: > - "null" > description: Authorized value for the collection code associated with this item > maxLength: 80 >+ effective_collection_code: >+ type: >+ - string >+ - "null" >+ description: Effective collection code - shows display collection code if item is on an active display, otherwise regular collection code > materials_notes: > type: > - string >@@ -223,6 +238,11 @@ properties: > - string > - "null" > description: Effective itemtype defining the type for this item_id >+ effective_location: >+ type: >+ - string >+ - "null" >+ description: Effective location code - shows display location if item is on an active display, otherwise regular location > extended_subfields: > type: > - string >diff --git a/api/v1/swagger/paths/displayitems.yaml b/api/v1/swagger/paths/displayitems.yaml >new file mode 100644 >index 00000000000..5b41a6abb79 >--- /dev/null >+++ b/api/v1/swagger/paths/displayitems.yaml >@@ -0,0 +1,395 @@ >+--- >+/display/items: >+ get: >+ x-mojo-to: DisplayItems#list >+ operationId: listDisplayItems >+ tags: >+ - displayitems >+ summary: List display items >+ produces: >+ - application/json >+ parameters: >+ - name: display_item_id >+ in: query >+ description: Filter by display item ID >+ required: false >+ type: integer >+ - name: display_id >+ in: query >+ description: Filter by display ID >+ required: false >+ type: integer >+ - name: itemnumber >+ in: query >+ description: Filter by item number >+ required: false >+ type: integer >+ - name: biblionumber >+ in: query >+ description: Filter by bibliographic record number >+ required: false >+ type: integer >+ - name: date_added >+ in: query >+ description: Filter by date added >+ required: false >+ type: string >+ format: date >+ - name: date_remove >+ in: query >+ description: Filter by date to remove >+ required: false >+ type: string >+ format: date >+ - $ref: "../swagger.yaml#/parameters/match" >+ - $ref: "../swagger.yaml#/parameters/order_by" >+ - $ref: "../swagger.yaml#/parameters/page" >+ - $ref: "../swagger.yaml#/parameters/per_page" >+ - $ref: "../swagger.yaml#/parameters/q_param" >+ - $ref: "../swagger.yaml#/parameters/q_body" >+ - $ref: "../swagger.yaml#/parameters/request_id_header" >+ responses: >+ "200": >+ description: A list of display items >+ schema: >+ type: array >+ items: >+ $ref: "../swagger.yaml#/definitions/displayitem" >+ "400": >+ description: | >+ Bad request. Possible `error_code` attribute values: >+ >+ * `invalid_query` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ displays: "*" >+ post: >+ x-mojo-to: DisplayItems#add >+ operationId: addDisplayItem >+ tags: >+ - displayitems >+ summary: Add display item >+ parameters: >+ - name: body >+ in: body >+ description: A JSON object containing information about the new display item >+ required: true >+ schema: >+ $ref: "../swagger.yaml#/definitions/displayitem" >+ produces: >+ - application/json >+ responses: >+ "201": >+ description: Display item added >+ schema: >+ $ref: "../swagger.yaml#/definitions/displayitem" >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "401": >+ description: Authentication required >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ displays: add_items_to_display >+"/display/items/{display_id}/{item_id}": >+ get: >+ x-mojo-to: DisplayItems#get >+ operationId: getDisplayItem >+ tags: >+ - displayitems >+ summary: Get display item >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/display_id_pp" >+ - $ref: "../swagger.yaml#/parameters/item_id_pp" >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A display item >+ schema: >+ $ref: "../swagger.yaml#/definitions/displayitem" >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Display item not found >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ displays: "*" >+ put: >+ x-mojo-to: DisplayItems#update >+ operationId: updateDisplayItem >+ tags: >+ - displayitems >+ summary: Update display item >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/display_id_pp" >+ - $ref: "../swagger.yaml#/parameters/item_id_pp" >+ - name: body >+ in: body >+ description: A display item object >+ required: true >+ schema: >+ $ref: "../swagger.yaml#/definitions/displayitem" >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A display item >+ schema: >+ $ref: "../swagger.yaml#/definitions/displayitem" >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "401": >+ description: Authentication required >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Display item 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: >+ displays: add_items_to_display >+ delete: >+ x-mojo-to: DisplayItems#delete >+ operationId: deleteDisplayItem >+ tags: >+ - displayitems >+ summary: Delete display item >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/display_id_pp" >+ - $ref: "../swagger.yaml#/parameters/item_id_pp" >+ produces: >+ - application/json >+ responses: >+ "204": >+ description: Display item deleted >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "401": >+ description: Authentication required >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Display item 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: >+ displays: remove_items_from_display >+/display/items/batch: >+ post: >+ x-mojo-to: DisplayItems#batch_add >+ operationId: batchAddDisplayItems >+ tags: >+ - displayitems >+ summary: Add multiple items to a display >+ parameters: >+ - name: body >+ in: body >+ description: A JSON object containing display and item information >+ required: true >+ schema: >+ type: object >+ properties: >+ display_id: >+ description: ID of the display to add items to >+ type: integer >+ item_ids: >+ description: Array of item numbers to add to the display >+ type: array >+ items: >+ type: integer >+ minItems: 1 >+ date_remove: >+ description: Optional date when items should be removed from display >+ type: string >+ format: date >+ required: >+ - display_id >+ - item_ids >+ additionalProperties: false >+ produces: >+ - application/json >+ responses: >+ "202": >+ description: Batch operation queued >+ schema: >+ type: object >+ properties: >+ job_id: >+ type: integer >+ description: ID of the background job processing this request >+ message: >+ type: string >+ description: Confirmation message >+ additionalProperties: false >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "401": >+ description: Authentication required >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Display not found >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: Internal server error >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ displays: add_items_to_display >+ delete: >+ x-mojo-to: DisplayItems#batch_delete >+ operationId: batchDeleteDisplayItems >+ tags: >+ - displayitems >+ summary: Remove multiple items from displays >+ parameters: >+ - name: body >+ in: body >+ description: A JSON object containing item information >+ required: true >+ schema: >+ type: object >+ properties: >+ item_ids: >+ description: Array of item numbers to remove from displays >+ type: array >+ items: >+ type: integer >+ minItems: 1 >+ display_id: >+ description: Optional display ID - if specified, only remove items from this display >+ type: integer >+ required: >+ - item_ids >+ additionalProperties: false >+ produces: >+ - application/json >+ responses: >+ "202": >+ description: Batch operation queued >+ schema: >+ type: object >+ properties: >+ job_id: >+ type: integer >+ description: ID of the background job processing this request >+ message: >+ type: string >+ description: Confirmation message >+ additionalProperties: false >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "401": >+ description: Authentication required >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: Internal server error >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ displays: remove_items_from_display >diff --git a/api/v1/swagger/paths/displays.yaml b/api/v1/swagger/paths/displays.yaml >new file mode 100644 >index 00000000000..c861062d876 >--- /dev/null >+++ b/api/v1/swagger/paths/displays.yaml >@@ -0,0 +1,273 @@ >+--- >+/displays: >+ get: >+ x-mojo-to: Displays#list >+ operationId: listDisplays >+ tags: >+ - displays >+ summary: List displays >+ produces: >+ - application/json >+ parameters: >+ - name: display_name >+ in: query >+ description: Case insensitive search on display name >+ required: false >+ type: string >+ - name: enabled >+ in: query >+ description: Filter by enabled status >+ required: false >+ type: boolean >+ - name: active >+ in: query >+ description: Filter by active status (not expired, end_date >= today or null) >+ required: false >+ type: boolean >+ - name: display_branch >+ in: query >+ description: Filter by display branch >+ required: false >+ type: string >+ - name: display_type >+ in: query >+ description: Filter by display type >+ required: false >+ type: string >+ - $ref: "../swagger.yaml#/parameters/match" >+ - $ref: "../swagger.yaml#/parameters/order_by" >+ - $ref: "../swagger.yaml#/parameters/page" >+ - $ref: "../swagger.yaml#/parameters/per_page" >+ - $ref: "../swagger.yaml#/parameters/q_param" >+ - $ref: "../swagger.yaml#/parameters/q_body" >+ - $ref: "../swagger.yaml#/parameters/request_id_header" >+ - name: x-koha-embed >+ in: header >+ required: false >+ description: Embed list sent as a request header >+ type: array >+ items: >+ type: string >+ enum: >+ - display_items >+ - library >+ - item_type >+ - +strings >+ collectionFormat: csv >+ responses: >+ "200": >+ description: A list of displays >+ schema: >+ type: array >+ items: >+ $ref: "../swagger.yaml#/definitions/display" >+ "400": >+ description: | >+ Bad request. Possible `error_code` attribute values: >+ >+ * `invalid_query` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ displays: "*" >+ post: >+ x-mojo-to: Displays#add >+ operationId: addDisplay >+ tags: >+ - displays >+ summary: Add display >+ parameters: >+ - name: body >+ in: body >+ description: A JSON object containing information about the new display >+ required: true >+ schema: >+ $ref: "../swagger.yaml#/definitions/display" >+ produces: >+ - application/json >+ responses: >+ "201": >+ description: Display added >+ schema: >+ $ref: "../swagger.yaml#/definitions/display" >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "401": >+ description: Authentication required >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ displays: add_display >+"/displays/{display_id}": >+ get: >+ x-mojo-to: Displays#get >+ operationId: getDisplay >+ tags: >+ - displays >+ summary: Get display >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/display_id_pp" >+ - name: x-koha-embed >+ in: header >+ required: false >+ description: Embed list sent as a request header >+ type: array >+ items: >+ type: string >+ enum: >+ - display_items >+ - library >+ - item_type >+ - +strings >+ collectionFormat: csv >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A display >+ schema: >+ $ref: "../swagger.yaml#/definitions/display" >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Display not found >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ displays: "*" >+ put: >+ x-mojo-to: Displays#update >+ operationId: updateDisplay >+ tags: >+ - displays >+ summary: Update display >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/display_id_pp" >+ - name: body >+ in: body >+ description: A display object >+ required: true >+ schema: >+ $ref: "../swagger.yaml#/definitions/display" >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A display >+ schema: >+ $ref: "../swagger.yaml#/definitions/display" >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "401": >+ description: Authentication required >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Display 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: >+ displays: edit_display >+ delete: >+ x-mojo-to: Displays#delete >+ operationId: deleteDisplay >+ tags: >+ - displays >+ summary: Delete display >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/display_id_pp" >+ produces: >+ - application/json >+ responses: >+ "204": >+ description: Display deleted >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "401": >+ description: Authentication required >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Display 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: >+ displays: delete_display >diff --git a/api/v1/swagger/paths/displays_config.yaml b/api/v1/swagger/paths/displays_config.yaml >new file mode 100644 >index 00000000000..b2ebbea3da4 >--- /dev/null >+++ b/api/v1/swagger/paths/displays_config.yaml >@@ -0,0 +1,38 @@ >+--- >+/displays/config: >+ get: >+ x-mojo-to: Displays#config >+ operationId: getDisplaysConfig >+ description: This resource returns a list of options needed for the Displays Vue app. EXPERIMENTAL - DO NOT RELY on this, it is subject to change! >+ summary: get the Displays Config >+ tags: >+ - displays >+ produces: >+ - application/json >+ responses: >+ 200: >+ description: The Displays module config >+ schema: >+ $ref: "../swagger.yaml#/definitions/display_config" >+ 400: >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 403: >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 500: >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 503: >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ displays: "*" >diff --git a/api/v1/swagger/paths/public_displayitems.yaml b/api/v1/swagger/paths/public_displayitems.yaml >new file mode 100644 >index 00000000000..f31a8ef56be >--- /dev/null >+++ b/api/v1/swagger/paths/public_displayitems.yaml >@@ -0,0 +1,94 @@ >+--- >+"/public/display/items": >+ get: >+ x-mojo-to: DisplayItems#list_public >+ operationId: listDisplayItemsPublic >+ tags: >+ - displayitems >+ summary: List display items (public) >+ produces: >+ - application/json >+ parameters: >+ - name: display_id >+ in: query >+ description: Filter by display ID >+ required: false >+ type: integer >+ - name: itemnumber >+ in: query >+ description: Filter by item number >+ required: false >+ type: integer >+ - name: biblionumber >+ in: query >+ description: Filter by bibliographic record number >+ required: false >+ type: integer >+ - $ref: "../swagger.yaml#/parameters/match" >+ - $ref: "../swagger.yaml#/parameters/order_by" >+ - $ref: "../swagger.yaml#/parameters/page" >+ - $ref: "../swagger.yaml#/parameters/per_page" >+ - $ref: "../swagger.yaml#/parameters/q_param" >+ - $ref: "../swagger.yaml#/parameters/q_body" >+ - $ref: "../swagger.yaml#/parameters/request_id_header" >+ responses: >+ "200": >+ description: A list of display items >+ schema: >+ type: array >+ items: >+ $ref: "../swagger.yaml#/definitions/displayitem" >+ "400": >+ description: | >+ Bad request. Possible `error_code` attribute values: >+ >+ * `invalid_query` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+"/public/display/items/{display_id}/{item_id}": >+ get: >+ x-mojo-to: DisplayItems#get_public >+ operationId: getDisplayItemPublic >+ tags: >+ - displayitems >+ summary: Get display item (public) >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/display_id_pp" >+ - $ref: "../swagger.yaml#/parameters/item_id_pp" >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A display item >+ schema: >+ $ref: "../swagger.yaml#/definitions/displayitem" >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Display item not found >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >diff --git a/api/v1/swagger/paths/public_displays.yaml b/api/v1/swagger/paths/public_displays.yaml >new file mode 100644 >index 00000000000..35bf8640644 >--- /dev/null >+++ b/api/v1/swagger/paths/public_displays.yaml >@@ -0,0 +1,124 @@ >+--- >+"/public/displays": >+ get: >+ x-mojo-to: Displays#list_public >+ operationId: listDisplaysPublic >+ tags: >+ - displays >+ summary: List displays (public) >+ produces: >+ - application/json >+ parameters: >+ - name: active >+ in: query >+ description: Filter by active status (enabled and within start/end date range) >+ required: false >+ type: boolean >+ - name: enabled >+ in: query >+ description: Filter by enabled status >+ required: false >+ type: boolean >+ - name: display_branch >+ in: query >+ description: Filter by display branch >+ required: false >+ type: string >+ - name: display_type >+ in: query >+ description: Filter by display type >+ required: false >+ type: string >+ - $ref: "../swagger.yaml#/parameters/match" >+ - $ref: "../swagger.yaml#/parameters/order_by" >+ - $ref: "../swagger.yaml#/parameters/page" >+ - $ref: "../swagger.yaml#/parameters/per_page" >+ - $ref: "../swagger.yaml#/parameters/q_param" >+ - $ref: "../swagger.yaml#/parameters/q_body" >+ - $ref: "../swagger.yaml#/parameters/request_id_header" >+ - name: x-koha-embed >+ in: header >+ required: false >+ description: Embed list sent as a request header >+ type: array >+ items: >+ type: string >+ enum: >+ - display_items >+ - library >+ - item_type >+ - +strings >+ collectionFormat: csv >+ responses: >+ "200": >+ description: A list of displays >+ schema: >+ type: array >+ items: >+ $ref: "../swagger.yaml#/definitions/display" >+ "400": >+ description: | >+ Bad request. Possible `error_code` attribute values: >+ >+ * `invalid_query` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+"/public/displays/{display_id}": >+ get: >+ x-mojo-to: Displays#get_public >+ operationId: getDisplayPublic >+ tags: >+ - displays >+ summary: Get display (public) >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/display_id_pp" >+ - name: x-koha-embed >+ in: header >+ required: false >+ description: Embed list sent as a request header >+ type: array >+ items: >+ type: string >+ enum: >+ - display_items >+ - library >+ - item_type >+ - +strings >+ collectionFormat: csv >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A display >+ schema: >+ $ref: "../swagger.yaml#/definitions/display" >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Display not found >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "500": >+ description: | >+ Internal server error. Possible `error_code` attribute values: >+ >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "503": >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml >index dcb0a3cc66e..4758daefd78 100644 >--- a/api/v1/swagger/swagger.yaml >+++ b/api/v1/swagger/swagger.yaml >@@ -42,6 +42,12 @@ definitions: > $ref: ./definitions/circ-rule-kind.yaml > city: > $ref: ./definitions/city.yaml >+ display_config: >+ $ref: ./definitions/display_config.yaml >+ display: >+ $ref: ./definitions/display.yaml >+ displayitem: >+ $ref: ./definitions/displayitem.yaml > credit: > $ref: ./definitions/credit.yaml > debit: >@@ -325,6 +331,18 @@ paths: > $ref: ./paths/cities.yaml#/~1cities > "/cities/{city_id}": > $ref: "./paths/cities.yaml#/~1cities~1{city_id}" >+ /displays/config: >+ $ref: ./paths/displays_config.yaml#/~1displays~1config >+ /displays: >+ $ref: ./paths/displays.yaml#/~1displays >+ "/displays/{display_id}": >+ $ref: "./paths/displays.yaml#/~1displays~1{display_id}" >+ /display/items: >+ $ref: ./paths/displayitems.yaml#/~1display~1items >+ /display/items/batch: >+ $ref: ./paths/displayitems.yaml#/~1display~1items~1batch >+ /display/items/{display_id}/{item_id}: >+ $ref: ./paths/displayitems.yaml#/~1display~1items~1{display_id}~1{item_id} > "/clubs/{club_id}/holds": > $ref: "./paths/clubs.yaml#/~1clubs~1{club_id}~1holds" > /config/smtp_servers: >@@ -551,6 +569,14 @@ paths: > $ref: "./paths/biblios.yaml#/~1public~1biblios~1{biblio_id}" > "/public/checkouts/availability": > $ref: ./paths/checkouts.yaml#/~1public~1checkouts~1availability >+ "/public/display/items": >+ $ref: "./paths/public_displayitems.yaml#/~1public~1display~1items" >+ "/public/display/items/{display_id}/{item_id}": >+ $ref: "./paths/public_displayitems.yaml#/~1public~1display~1items~1{display_id}~1{item_id}" >+ "/public/displays": >+ $ref: "./paths/public_displays.yaml#/~1public~1displays" >+ "/public/displays/{display_id}": >+ $ref: "./paths/public_displays.yaml#/~1public~1displays~1{display_id}" > "/public/items": > $ref: "./paths/items.yaml#/~1public~1items" > "/public/biblios/{biblio_id}/items": >@@ -745,6 +771,12 @@ parameters: > name: city_id > required: true > type: integer >+ display_id_pp: >+ description: Display internal identifier >+ in: path >+ name: display_id >+ required: true >+ type: integer > club_id_pp: > description: Internal club identifier > in: path >@@ -1240,6 +1272,12 @@ tags: > - description: "Manage cities\n" > name: cities > x-displayName: Cities >+ - description: "Manage displays\n" >+ name: displays >+ x-displayName: Displays >+ - description: "Manage display items\n" >+ name: displayitems >+ x-displayName: Display items > - description: "Manage patron clubs\n" > name: clubs > x-displayName: Clubs >-- >2.50.1 (Apple Git-155)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 14962
:
190216
|
190217
| 190218 |
190219
|
190220
|
190221
|
190222
|
190223
|
190224
|
190225
|
190226
|
190227
|
190228
|
190229
|
190230
|
190231
|
190232