Bugzilla – Attachment 173108 Details for
Bug 35287
Add additional fields support to ERM licenses
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 35287: Vue preparation - AdditionalFields
Bug-35287-Vue-preparation---AdditionalFields.patch (text/plain), 17.19 KB, created by
Victor Grousset/tuxayo
on 2024-10-22 01:47:11 UTC
(
hide
)
Description:
Bug 35287: Vue preparation - AdditionalFields
Filename:
MIME Type:
Creator:
Victor Grousset/tuxayo
Created:
2024-10-22 01:47:11 UTC
Size:
17.19 KB
patch
obsolete
>From a5d8b3df9c14e2f9270e4e8ad7d952bfecf8313b Mon Sep 17 00:00:00 2001 >From: Pedro Amorim <pedro.amorim@ptfs-europe.com> >Date: Wed, 8 Nov 2023 11:34:19 -0100 >Subject: [PATCH] Bug 35287: Vue preparation - AdditionalFields > >New api client: additional-fields-api-client.js to interact with the REST endpoint introduced by bug 35197 >2 new components: >- AdditionalFieldsEntry: Component used to extend the FormAdd component including the corresponding additional fields >- AdditionalFieldsDisplay: Component used to display the additional fields associated to a data record implementing it (makes use of strings_map) > >Signed-off-by: Edith Speller <edith.speller@ukhsa.gov.uk> >Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu> >Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net> >Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de> >--- > .../components/AdditionalFieldsDisplay.vue | 37 +++ > .../vue/components/AdditionalFieldsEntry.vue | 296 ++++++++++++++++++ > .../vue/fetch/additional-fields-api-client.js | 20 ++ > .../prog/js/vue/fetch/api-client.js | 2 + > 4 files changed, 355 insertions(+) > create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/AdditionalFieldsDisplay.vue > create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/AdditionalFieldsEntry.vue > create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/fetch/additional-fields-api-client.js > >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/AdditionalFieldsDisplay.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/AdditionalFieldsDisplay.vue >new file mode 100644 >index 0000000000..a9cda25329 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/AdditionalFieldsDisplay.vue >@@ -0,0 +1,37 @@ >+<template> >+ <fieldset >+ v-if="additional_field_values.length" >+ class="rows" >+ id="additional_fields" >+ > >+ <legend>{{ $__("Additional fields") }}</legend> >+ <ol> >+ <li v-for="additional_field_value in additional_field_values"> >+ <label >+ :for="`additional_field_` + additional_field_value.field_id" >+ > >+ {{ additional_field_value.field_label }}: >+ </label> >+ <span> {{ additional_field_value.value_str }} </span> >+ </li> >+ </ol> >+ </fieldset> >+</template> >+ >+<script> >+import { inject } from "vue" >+import { APIClient } from "../fetch/api-client.js" >+ >+export default { >+ data() { >+ return { >+ fields_to_display: [], >+ } >+ }, >+ name: "AdditionalFieldsDisplay", >+ props: { >+ resource_type: String, >+ additional_field_values: Array, >+ }, >+} >+</script> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/AdditionalFieldsEntry.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/AdditionalFieldsEntry.vue >new file mode 100644 >index 0000000000..71ae8fc0d2 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/AdditionalFieldsEntry.vue >@@ -0,0 +1,296 @@ >+<template> >+ <fieldset >+ v-if="available_fields.length" >+ class="rows" >+ id="additional_fields" >+ > >+ <legend>{{ $__("Additional fields") }}</legend> >+ <ol> >+ <template v-for="available_field in available_fields"> >+ <template >+ v-if=" >+ available_field.authorised_value_category_name && >+ !available_field.repeatable >+ " >+ > >+ <li> >+ <label >+ :for=" >+ `additional_field_` + >+ available_field.extended_attribute_type_id >+ " >+ >{{ available_field.name }}: >+ </label> >+ <v-select >+ :id=" >+ `additional_field_` + >+ available_field.extended_attribute_type_id >+ " >+ :name="available_field.name" >+ v-model=" >+ current_additional_fields_values[ >+ available_field.extended_attribute_type_id >+ ] >+ " >+ :options=" >+ av_options[ >+ available_field >+ .authorised_value_category_name >+ ] >+ " >+ /> >+ </li> >+ </template> >+ <template >+ v-if=" >+ available_field.authorised_value_category_name && >+ available_field.repeatable >+ " >+ > >+ <li> >+ <label >+ :for=" >+ `additional_field_` + >+ available_field.extended_attribute_type_id >+ " >+ >{{ available_field.name }}: >+ </label> >+ <v-select >+ :id=" >+ `additional_field_` + >+ available_field.extended_attribute_type_id >+ " >+ :name="available_field.name" >+ :multiple="available_field.repeatable" >+ v-model=" >+ current_additional_fields_values[ >+ available_field.extended_attribute_type_id >+ ] >+ " >+ :options=" >+ av_options[ >+ available_field >+ .authorised_value_category_name >+ ] >+ " >+ /> >+ </li> >+ </template> >+ >+ <template >+ v-if="!available_field.authorised_value_category_name" >+ > >+ <li >+ v-for="current in current_additional_fields_values[ >+ available_field.extended_attribute_type_id >+ ]" >+ > >+ <label >+ :for=" >+ `additional_field_` + >+ available_field.extended_attribute_type_id >+ " >+ >{{ available_field.name }}: >+ </label> >+ <input type="text" v-model="current.value" /> >+ <a >+ href="#" >+ class="clear_attribute" >+ @click="clearField(current, $event)" >+ > >+ <i class="fa fa-fw fa-trash-can"></i> >+ {{ $__("Clear") }} >+ </a> >+ <template v-if="available_field.repeatable"> >+ <a >+ href="#" >+ class="clone_attribute" >+ @click=" >+ cloneField(available_field, current, $event) >+ " >+ > >+ <i class="fa fa-fw fa-plus"></i> >+ {{ $__("New") }} >+ </a> >+ </template> >+ </li> >+ </template> >+ </template> >+ </ol> >+ </fieldset> >+</template> >+ >+<script> >+import { inject } from "vue" >+import { APIClient } from "../fetch/api-client.js" >+ >+export default { >+ data() { >+ return { >+ available_fields: [], >+ av_options: [], >+ current_additional_fields_values: {}, >+ } >+ }, >+ beforeCreate() { >+ const client = APIClient.additional_fields >+ client.additional_fields.getAll(this.resource_type).then( >+ available_fields => { >+ this.available_fields = available_fields >+ this.initialized = true >+ }, >+ error => {} >+ ) >+ }, >+ watch: { >+ current_additional_fields_values: { >+ deep: true, >+ handler(current_additional_fields_values) { >+ this.updateParentAdditionalFieldValues( >+ current_additional_fields_values >+ ) >+ }, >+ }, >+ available_fields: function (available_fields) { >+ if (available_fields) { >+ const client_av = APIClient.authorised_values >+ let av_cat_array = available_fields >+ .map(field => field.authorised_value_category_name) >+ .filter(field => field) >+ >+ client_av.values >+ .getCategoriesWithValues([ >+ ...new Set( >+ av_cat_array.map(av_cat => '"' + av_cat + '"') >+ ), >+ ]) // unique >+ .then(av_categories => { >+ av_cat_array.forEach(av_cat => { >+ let av_match = av_categories.find( >+ element => element.category_name == av_cat >+ ) >+ this.av_options[av_cat] = >+ av_match.authorised_values.map(av => ({ >+ value: av.value, >+ label: av.description, >+ })) >+ }) >+ >+ // Iterate on available fields >+ available_fields.forEach(available_field => { >+ // Initialize current field as empty array >+ this.current_additional_fields_values[ >+ available_field.extended_attribute_type_id >+ ] = [] >+ >+ // Grab all existing field values of this field >+ let existing_field_values = >+ this.additional_field_values.filter( >+ afv => >+ afv.field_id == >+ available_field.extended_attribute_type_id && >+ afv.value >+ ) >+ >+ // If there are existing field values for this field, add them to current_additional_fields_values >+ if (existing_field_values.length) { >+ existing_field_values.forEach( >+ existing_field_value => { >+ let label = "" >+ if ( >+ available_field.authorised_value_category_name >+ ) { >+ let av_value = this.av_options[ >+ available_field >+ .authorised_value_category_name >+ ].filter( >+ av_option => >+ av_option.value == >+ existing_field_value.value >+ ) >+ label = av_value.length >+ ? av_value[0].label >+ : "" >+ } >+ this.current_additional_fields_values[ >+ existing_field_value.field_id >+ ].push({ >+ value: existing_field_value.value, >+ label: label, >+ }) >+ } >+ ) >+ >+ // Otherwise add them as empty if not AV field >+ } else { >+ if ( >+ !available_field.authorised_value_category_name >+ ) { >+ this.current_additional_fields_values[ >+ available_field.extended_attribute_type_id >+ ] = [ >+ { >+ label: "", >+ value: "", >+ }, >+ ] >+ } >+ } >+ }) >+ }) >+ } >+ }, >+ }, >+ methods: { >+ clearField: function (current_field, event) { >+ event.preventDefault() >+ current_field.value = "" >+ }, >+ cloneField: function (available_field, current, event) { >+ event.preventDefault() >+ this.current_additional_fields_values[ >+ available_field.extended_attribute_type_id >+ ].push({ >+ value: current.value, >+ label: available_field.name, >+ }) >+ }, >+ updateParentAdditionalFieldValues: function ( >+ current_additional_fields_values >+ ) { >+ let updatedAdditionalFields = [] >+ Object.keys(current_additional_fields_values).forEach(field_id => { >+ if ( >+ !Array.isArray( >+ current_additional_fields_values[field_id] >+ ) && >+ current_additional_fields_values[field_id] >+ ) { >+ current_additional_fields_values[field_id] = [ >+ current_additional_fields_values[field_id], >+ ] >+ } >+ if (current_additional_fields_values[field_id]) { >+ let new_extended_attributes = >+ current_additional_fields_values[field_id].map( >+ value => ({ >+ field_id: field_id, >+ value: value.value, >+ }) >+ ) >+ updatedAdditionalFields = updatedAdditionalFields.concat( >+ new_extended_attributes >+ ) >+ } >+ }) >+ >+ this.$emit("additional-fields-changed", updatedAdditionalFields) >+ }, >+ }, >+ name: "AdditionalFieldsEntry", >+ props: { >+ resource_type: String, >+ additional_field_values: Array, >+ }, >+} >+</script> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/additional-fields-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/additional-fields-api-client.js >new file mode 100644 >index 0000000000..19b3895cb2 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/additional-fields-api-client.js >@@ -0,0 +1,20 @@ >+import HttpClient from "./http-client"; >+ >+export class AdditionalFieldsAPIClient extends HttpClient { >+ constructor() { >+ super({ >+ baseURL: "/api/v1/extended_attribute_types", >+ }); >+ } >+ >+ get additional_fields() { >+ return { >+ getAll: resource_type => >+ this.get({ >+ endpoint: "?resource_type=" + resource_type, >+ }), >+ }; >+ } >+} >+ >+export default AdditionalFieldsAPIClient; >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/api-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/api-client.js >index 4bfd3c8dd0..7e10da71ea 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/api-client.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/api-client.js >@@ -1,6 +1,7 @@ > import ERMAPIClient from "./erm-api-client"; > import PatronAPIClient from "./patron-api-client"; > import AcquisitionAPIClient from "./acquisition-api-client"; >+import AdditionalFieldsAPIClient from "./additional-fields-api-client"; > import AVAPIClient from "./authorised-values-api-client"; > import ItemAPIClient from "./item-api-client"; > import RecordSourcesAPIClient from "./record-sources-api-client"; >@@ -11,6 +12,7 @@ export const APIClient = { > erm: new ERMAPIClient(), > patron: new PatronAPIClient(), > acquisition: new AcquisitionAPIClient(), >+ additional_fields: new AdditionalFieldsAPIClient(), > authorised_values: new AVAPIClient(), > item: new ItemAPIClient(), > sysprefs: new SysprefAPIClient(), >-- >2.47.0
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 35287
:
158725
|
158726
|
158727
|
158728
|
158729
|
158730
|
158731
|
158732
|
158733
|
158734
|
159634
|
159635
|
159636
|
159637
|
159638
|
159639
|
159640
|
159641
|
159642
|
159643
|
165451
|
165637
|
165638
|
165639
|
165640
|
165641
|
165642
|
165643
|
165644
|
165645
|
165646
|
165647
|
167681
|
169728
|
169729
|
169730
|
169731
|
169732
|
169733
|
169734
|
169735
|
169736
|
169737
|
170448
|
170753
|
172850
|
172851
|
172852
|
172853
|
172854
|
172855
|
172856
|
172857
|
172858
|
172860
|
172861
|
173022
|
173102
|
173103
|
173104
|
173105
|
173106
|
173107
| 173108 |
173109
|
173110
|
173111
|
173112
|
173113
|
173290