Bugzilla – Attachment 193846 Details for
Bug 37829
Allow additional fields for bookings
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 37829: Add additional fields support to modal, tables
Bug-37829-Add-additional-fields-support-to-modal-t.patch (text/plain), 26.29 KB, created by
Thibaud Guillot (thibaud_g)
on 2026-02-25 10:41:19 UTC
(
hide
)
Description:
Bug 37829: Add additional fields support to modal, tables
Filename:
MIME Type:
Creator:
Thibaud Guillot (thibaud_g)
Created:
2026-02-25 10:41:19 UTC
Size:
26.29 KB
patch
obsolete
>From 166f7d56c6ddbf9aa1e64defeee73df097eb77a5 Mon Sep 17 00:00:00 2001 >From: Paul Derscheid <paul.derscheid@lmscloud.de> >Date: Wed, 16 Apr 2025 15:41:05 +0000 >Subject: [PATCH] Bug 37829: Add additional fields support to modal, tables > >To test: >1) Setup: > a) Apply the db seed provided: > koha-mysql < test_bug_37829.sql > > --- or --- > > b) Setup authorised values and additional fields manually: > i) Navigate to Administration -> Authorized Values and click '+ New Category'. > ii) Define a new authorised value category (e.g., prefix with BOOKINGS_ for easy identification). > iii) Click '+ Add a new authorized value'. > iv) Add a value, filling in at least 'Authorized Value' and 'Description'. > v) Save the value. > vi) Navigate to Administration -> Additional Fields. > vii) Click 'Bookings (bookings)'. > viii)Click '+ New field'. > ix) Add a plain text field (fill 'Name' and save). > x) Add a repeatable text field. > xi) Add a field tied to your previously created authorized value category. > xii) Add another field tied to any authorised value (e.g., YES_NO) and make it repeatable. > >2) Item Configuration: > Make an item bookable. Either: > a) Navigate to Administration -> Item types, select an item type (e.g., BK), and check 'bookable'. > b) Navigate to the 'Items' view for a specific item (catalogue/moredetail.pl) and set Priority -> Bookable -> 'Yes'. > >3) Create Booking: > Click the 'Place booking' button on the item's record. The configured additional fields should load dynamically in the modal. > >4) Fill and Save Booking: > Fill out the default booking fields and then the additional fields. Use the 'Remove' and 'New' buttons for repeatable fields. Save the booking. > >5) Verify Display in Tables: > Confirm that the additional fields for the booking are displayed correctly in the following locations: > a) The bookings table within the bibliographic record's detail view. > b) The 'Check out' view (circ/circulation.pl -> Bookings tab). > c) The 'Patron's details' view (members/moremember.pl -> Bookings tab). > d) The 'Bookings to collect' view (circ/pendingbookings.pl) (adjust filters if necessary). > >6) Verify Edit/Move Functionality: > Return to the bookings view of the bibliographic record. > a) Verify the additional fields are correctly pre-filled and saved when you move the booking using the timeline component. > b) Verify the additional fields are correctly pre-filled and saved when you edit the booking using the edit button in the bookings table. > >7) Repeat Testing: > Repeat steps 4 through 6.b with additional bookings to ensure consistency. > >8) Sign-off and/or give your feedback. > >Here's some things I'd would still like to improve/try: >- Incorporate the neighboring additional-fields-entry.js to have a single library for additional fields >- Restructure the buttons to be consistent with other usage of additional fields in Koha (noticed this way to late) >- Test this with the freshly added support for additional fields on branches (libraries) >- Make the additional field values searchable in the table >- Clean up and DRY some of the JSDoc types (but this could easily become its own tree of bugs if done from the source :D) >- Use mockData.js for the mocha tests instead of hardcoding them > >I actually need this for a customer and the current state will be alright for that, but now it's good enough to work and improve it together. >--- > .../prog/en/modules/bookings/list.tt | 85 +++++++++++++------ > .../prog/en/modules/catalogue/ISBDdetail.tt | 1 + > .../prog/en/modules/catalogue/MARCdetail.tt | 1 + > .../prog/en/modules/catalogue/detail.tt | 1 + > .../prog/en/modules/catalogue/imageviewer.tt | 1 + > .../en/modules/catalogue/labeledMARCdetail.tt | 2 + > .../prog/en/modules/catalogue/moredetail.tt | 2 + > .../prog/en/modules/circ/circulation.tt | 1 + > .../prog/en/modules/circ/pendingbookings.tt | 35 +++++++- > .../prog/en/modules/members/moremember.tt | 1 + > .../prog/js/modals/place_booking.js | 42 ++++++++- > .../intranet-tmpl/prog/js/tables/bookings.js | 32 ++++++- > 12 files changed, 172 insertions(+), 32 deletions(-) > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt >index b744f730a4a..227ed55e43b 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/bookings/list.tt >@@ -62,6 +62,7 @@ > <script> > dayjs.extend(window.dayjs_plugin_isSameOrBefore); > </script> >+ [% Asset.js("js/additional-fields.js") | $raw %] > [% Asset.js("js/modals/place_booking.js") | $raw %] > [% Asset.js("js/cancel_booking_modal.js") | $raw %] > [% Asset.js("js/combobox.js") | $raw %] >@@ -84,12 +85,24 @@ > type: "GET", > }); > var bookings = $.ajax({ >- url: "/api/v1/biblios/%s/bookings?_per_page=-1".format(biblionumber), >- headers: { "x-koha-embed": "patron" }, >- dataType: "json", >- type: "GET", >+ url: '/api/v1/biblios/%s/bookings?_per_page=-1'.format(biblionumber), >+ headers: { 'x-koha-embed': ['patron', 'extended_attributes'] }, >+ dataType: 'json', >+ type: 'GET', > }); >- >+ var extended_attribute_types; >+ var authorised_values; >+ AdditionalFields.fetchAndProcessExtendedAttributes("booking") >+ .then(types => { >+ extended_attribute_types = types; >+ const catArray = Object.values(types) >+ .map(attr => attr.authorised_value_category_name) >+ .filter(Boolean); >+ return AdditionalFields.fetchAndProcessAuthorizedValues(catArray); >+ }) >+ .then(values => { >+ authorised_values = values; >+ }); > $.when(items, bookings).then( > function (items, bookings) { > var itemsSet = new vis.DataSet([ >@@ -122,6 +135,7 @@ > pickup_library: booking.pickup_library_id, > start: $toDisplayDate(startServerTz), > end: $toDisplayDate(endServerTz), >+ extended_attributes: booking.extended_attributes, > content: !isActive ? `<s>${patronContent}</s>` : patronContent, > className: booking.status === "cancelled" ? "cancelled" : "", > ...(permissions.CAN_user_circulate_manage_bookings ? { editable: !["cancelled", "completed"].includes(booking.status) ? { remove: true, updateTime: true } : false } : { editable: false }), >@@ -175,26 +189,23 @@ > // set end datetime hours and minutes to the end of the day > let endDate = dayjs(data.end).endOf("day"); > >- $("#placeBookingModal").modal( >- "show", >- $( >- '<button data-booking="' + >- data.id + >- '" data-biblionumber="' + >- biblionumber + >- '" data-itemnumber="' + >- data.group + >- '" data-patron="' + >- data.patron + >- '" data-pickup_library="' + >- data.pickup_library + >- '" data-start_date="' + >- startDate.toISOString() + >- '" data-end_date="' + >- endDate.toISOString() + >- '">' >- ) >- ); >+ // Get the current booking to preserve extended attributes >+ let currentBooking = bookingsSet.get(data.id); >+ let extendedAttributes = currentBooking.extended_attributes || []; >+ >+ $('#placeBookingModal').modal('show', $(`<button >+ data-booking="${data.id}" >+ data-biblionumber="[% biblionumber | uri %]" >+ data-itemnumber="${data.group}" >+ data-patron="${data.patron}" >+ data-pickup_library="${data.pickup_library}" >+ data-start_date="${startDate.toISOString()}" >+ data-end_date="${endDate.toISOString()}" >+ data-extended_attributes='${JSON.stringify(extendedAttributes.map(attribute => ({ >+ field_id: attribute.field_id, >+ value: attribute.value >+ })))}' >+ >`)); > $("#placeBookingModal").on("hide.bs.modal", function (e) { > if (update_success) { > update_success = 0; >@@ -255,7 +266,7 @@ > ajax: { > url: bookings_table_url, > }, >- embed: ["item", "patron", "pickup_library"], >+ embed: ["item", "patron", "pickup_library", "extended_attributes"], > columns: [ > { > data: "booking_id", >@@ -365,6 +376,20 @@ > return $date(row.end_date); > }, > }, >+ { >+ data: "extended_attributes", >+ title: _("Additional fields"), >+ searchable: false, >+ orderable: false, >+ render: function (data, type, row, meta) { >+ return AdditionalFields.renderExtendedAttributesValues( >+ data, >+ extended_attribute_types, >+ authorised_values, >+ row.booking_id >+ ).join("<br>"); >+ }, >+ }, > { > data: "", > title: _("Actions"), >@@ -387,6 +412,7 @@ > data-start_date="%s" > data-end_date="%s" > data-item_type_id="%s" >+ data-extended_attributes='%s' > > > <i class="fa fa-pencil" aria-hidden="true"></i> %s > </button> >@@ -399,6 +425,13 @@ > escape_str(row.start_date), > escape_str(row.end_date), > escape_str(row.item.item_type_id), >+ escape_str(JSON.stringify(row.extended_attributes >+ .filter(attribute => attribute.record_id == row.booking_id) >+ .map(attribute => ({ >+ field_id: attribute.field_id, >+ value: attribute.value >+ })) >+ )), > _("Edit") > ); > result += ` >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/ISBDdetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/ISBDdetail.tt >index 85c511aa8a3..9c88cc74fb7 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/ISBDdetail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/ISBDdetail.tt >@@ -87,6 +87,7 @@ > [% IF Koha.Preference('EnableBooking') %] > [% INCLUDE 'calendar.inc' %] > [% INCLUDE 'select2.inc' %] >+ [% Asset.js("js/additional-fields.js") | $raw %] > [% Asset.js("js/modals/place_booking.js") | $raw %] > [% END %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt >index 66a5774709d..cba194021a1 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/MARCdetail.tt >@@ -211,6 +211,7 @@ > [% IF Koha.Preference('EnableBooking') %] > [% INCLUDE 'calendar.inc' %] > [% INCLUDE 'select2.inc' %] >+ [% Asset.js("js/additional-fields.js") | $raw %] > [% Asset.js("js/modals/place_booking.js") | $raw %] > [% END %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >index 763cda06baf..547b6af23de 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt >@@ -1735,6 +1735,7 @@ > [% Asset.js("js/browser.js") | $raw %] > > [% IF Koha.Preference('EnableBooking') %] >+ [% Asset.js("js/additional-fields.js") | $raw %] > [% Asset.js("js/modals/place_booking.js") | $raw %] > [% END %] > <script> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/imageviewer.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/imageviewer.tt >index ef094d22889..ea9fcb0968c 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/imageviewer.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/imageviewer.tt >@@ -141,6 +141,7 @@ > [% IF Koha.Preference('EnableBooking') %] > [% INCLUDE 'calendar.inc' %] > [% INCLUDE 'select2.inc' %] >+ [% Asset.js("js/additional-fields.js") | $raw %] > [% Asset.js("js/modals/place_booking.js") | $raw %] > [% END %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/labeledMARCdetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/labeledMARCdetail.tt >index aff14ecbb70..a6c5d8d428b 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/labeledMARCdetail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/labeledMARCdetail.tt >@@ -96,6 +96,8 @@ > dayjs.extend(window.dayjs_plugin_isSameOrBefore); > </script> > [% Asset.js("js/catalog.js") | $raw %] >+ [% Asset.js("js/additional-fields.js") | $raw %] >+ [% Asset.js("js/modals/place_booking.js") | $raw %] > [% Asset.js("js/browser.js") | $raw %] > > [% IF Koha.Preference('EnableBooking') %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt >index f9313d0dd20..c7549338162 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/moredetail.tt >@@ -593,6 +593,8 @@ > dayjs.extend(window.dayjs_plugin_isSameOrBefore); > </script> > [% Asset.js("js/catalog.js") | $raw %] >+ [% Asset.js("js/additional-fields.js") | $raw %] >+ [% Asset.js("js/modals/place_booking.js") | $raw %] > [% Asset.js("js/browser.js") | $raw %] > [% Asset.js("js/checkout_renewals_modal.js") | $raw %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >index 672d27da176..f7b3ecb038f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >@@ -1111,6 +1111,7 @@ > [% END %] > [% Asset.js("js/holds.js") | $raw %] > [% INCLUDE 'calendar.inc' %] >+ [% Asset.js("js/additional-fields.js") | $raw %] > [% Asset.js("js/cancel_booking_modal.js") | $raw %] > [% Asset.js("js/combobox.js") | $raw %] > [% INCLUDE 'js-biblio-format.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt >index 6b008e35045..2e006736c09 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/pendingbookings.tt >@@ -115,6 +115,8 @@ > [% INCLUDE 'datatables.inc' %] > [% INCLUDE 'js-biblio-format.inc' %] > [% INCLUDE 'js-date-format.inc' %] >+ [% INCLUDE 'js-patron-format.inc' %] >+ [% Asset.js("js/additional-fields.js") | $raw %] > <script> > let table_settings = [% TablesSettings.GetTableSettings( 'circ', 'bookings', 'bookings-to-collect', 'json' ) | $raw %]; > >@@ -132,6 +134,19 @@ > libraries: all_libraries, > }; > $(document).ready(function() { >+ var extended_attribute_types; >+ var authorised_values; >+ AdditionalFields.fetchAndProcessExtendedAttributes("booking") >+ .then(types => { >+ extended_attribute_types = types; >+ const catArray = Object.values(types) >+ .map(attr => attr.authorised_value_category_name) >+ .filter(Boolean); >+ return AdditionalFields.fetchAndProcessAuthorizedValues(catArray); >+ }) >+ .then(values => { >+ authorised_values = values; >+ }); > > let additional_filters = { > start_date: function() { >@@ -177,7 +192,8 @@ > "item+strings", > "item.checkout", > "patron", >- "pickup_library" >+ "pickup_library", >+ "extended_attributes" > ], > order: [[ 7, "asc" ]], > columns: [{ >@@ -273,7 +289,22 @@ > render: function(data, type, row, meta) { > return $date(row.start_date) + ' - ' + $date(row.end_date); > } >- }] >+ }, >+ { >+ data: "extended_attributes", >+ title: _("Additional fields"), >+ searchable: false, >+ orderable: false, >+ render: function (data, type, row, meta) { >+ return AdditionalFields.renderExtendedAttributesValues( >+ data, >+ extended_attribute_types, >+ authorised_values, >+ row.booking_id >+ ).join("<br>"); >+ }, >+ }, >+ ] > }, table_settings, 1, additional_filters, filters_options); > > /** Date filtering */ >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >index cc59617307f..38fa6eed605 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >@@ -829,6 +829,7 @@ > [% Asset.js("js/holds.js") | $raw %] > [% INCLUDE 'calendar.inc' %] > [% IF Koha.Preference('EnableBooking') %] >+ [% Asset.js("js/additional-fields.js") | $raw %] > [% Asset.js("js/cancel_booking_modal.js") | $raw %] > [% Asset.js("js/tables/bookings.js") | $raw %] > [% END %] >diff --git a/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js b/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js >index a991215046c..432692fda7e 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/modals/place_booking.js >@@ -57,6 +57,16 @@ function datesOverlap(start1, end1, start2, end2) { > // Ranges overlap if neither is completely before or after the other > return !(e1.isBefore(s2, "day") || s1.isAfter(e2, "day")); > } >+// Initialize AdditionalFields module >+const additionalFields = AdditionalFields.init({ >+ containerId: "booking_extended_attributes", >+ resourceType: "booking", >+ selectors: { >+ repeatableFieldClass: "repeatable-field", >+ inputClass: "extended-attribute", >+ fieldPrefix: "extended_attributes", >+ }, >+}); > > /** > * Check if a date falls within a date range (inclusive) >@@ -117,6 +127,7 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { > let start_date = button.data("start_date"); > let end_date = button.data("end_date"); > let item_type_id = button.data("item_type_id"); >+ let extended_attributes = button.data("extended_attributes"); > > // Get booking id if this is an edit > booking_id = button.data("booking"); >@@ -129,6 +140,15 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { > $("#booking_id").val(""); > } > >+ additionalFields >+ .fetchExtendedAttributes("booking") >+ .then(response => >+ additionalFields.renderExtendedAttributes( >+ response, >+ extended_attributes >+ ) >+ ); >+ > // Patron select2 > $("#booking_patron_id").kohaSelect({ > dropdownParent: $(".modal-content", "#placeBookingModal"), >@@ -423,6 +443,9 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { > biblionumber + > "&_per_page=-1" + > '&q={"status":{"-in":["new","pending","active"]}}', >+ headers: { >+ "x-koha-embed": ["extended_attributes"], >+ }, > dataType: "json", > type: "GET", > }); >@@ -2130,7 +2153,8 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { > item_type_id, > start_date, > end_date, >- periodPicker >+ periodPicker, >+ extended_attributes > ); > }, > function (jqXHR, textStatus, errorThrown) { >@@ -2144,7 +2168,8 @@ $("#placeBookingModal").on("show.bs.modal", function (e) { > item_type_id, > start_date, > end_date, >- periodPicker >+ periodPicker, >+ extended_attributes > ); > } > }); >@@ -2167,7 +2192,8 @@ function setFormValues( > item_type_id, > start_date, > end_date, >- periodPicker >+ periodPicker, >+ extended_attributes > ) { > // Set itemtype first if provided (needed for edit mode before setting dates) > if (item_type_id) { >@@ -2219,6 +2245,11 @@ function setFormValues( > } else { > periodPicker.redraw(); > } >+ >+ // If passed extended attributes, set them >+ if (extended_attributes) { >+ additionalFields.setValues(extended_attributes); >+ } > } > > /** >@@ -2281,6 +2312,7 @@ function createTimelineItem(data) { > patron: data.patron_id, > start: $toDisplayDate(startServerTz), > end: $toDisplayDate(endServerTz), >+ extended_attributes: additionalFields.getValues(), > content: $patron_to_html(booking_patron, { > display_cardnumber: true, > url: false, >@@ -2339,6 +2371,7 @@ $("#placeBookingForm").on("submit", function (e) { > pickup_library_id: $("#pickup_library_id").val(), > biblio_id: $("#booking_biblio_id").val(), > patron_id: $("#booking_patron_id").find(":selected").val(), >+ extended_attributes: additionalFields.getValues(), > }; > > const payload = buildBookingPayload( >@@ -2433,4 +2466,7 @@ $("#placeBookingModal").on("hidden.bs.modal", function (e) { > $("#booking_start_date").val(""); > $("#booking_end_date").val(""); > $("#booking_id").val(""); >+ >+ // Clear additional fields >+ additionalFields.clear(); > }); >diff --git a/koha-tmpl/intranet-tmpl/prog/js/tables/bookings.js b/koha-tmpl/intranet-tmpl/prog/js/tables/bookings.js >index 21c1b94ac75..3dd65b81892 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/tables/bookings.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/tables/bookings.js >@@ -26,13 +26,29 @@ $(document).ready(function () { > }; > > if (!bookings_table) { >+ var extended_attribute_types; >+ var authorised_values; >+ AdditionalFields.fetchAndProcessExtendedAttributes("booking") >+ .then(types => { >+ extended_attribute_types = types; >+ const catArray = Object.values(types) >+ .map(attr => attr.authorised_value_category_name) >+ .filter(Boolean); >+ return AdditionalFields.fetchAndProcessAuthorizedValues( >+ catArray >+ ); >+ }) >+ .then(values => { >+ authorised_values = values; >+ }); >+ > var bookings_table_url = "/api/v1/bookings"; > bookings_table = $("#bookings_table").kohaTable( > { > ajax: { > url: bookings_table_url, > }, >- embed: ["biblio", "item", "patron"], >+ embed: ["biblio", "item", "patron", "extended_attributes"], > columns: [ > { > data: "booking_id", >@@ -94,6 +110,20 @@ $(document).ready(function () { > return $date(row.end_date); > }, > }, >+ { >+ data: "extended_attributes", >+ title: _("Additional fields"), >+ searchable: false, >+ orderable: false, >+ render: function (data, type, row, meta) { >+ return AdditionalFields.renderExtendedAttributesValues( >+ data, >+ extended_attribute_types, >+ authorised_values, >+ row.booking_id >+ ).join("<br>"); >+ }, >+ }, > { > data: "", > title: __("Actions"), >-- >2.39.5
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 37829
:
181034
|
181035
|
181036
|
181037
|
181038
|
181039
|
181040
|
181041
|
181042
|
181043
|
193769
|
193840
|
193841
|
193842
|
193843
|
193844
|
193845
| 193846 |
193847
|
193848
|
193849