Bug 32030: Display the number of local packages and titles matching the search
authorJonathan Druart <jonathan.druart@bugs.koha-community.org>
Tue, 5 Jul 2022 12:52:11 +0000 (14:52 +0200)
committerTomas Cohen Arazi <tomascohen@theke.io>
Tue, 8 Nov 2022 12:44:12 +0000 (09:44 -0300)
Signed-off-by: Jonathan Field <jonathan.field@ptfs-europe.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
koha-tmpl/intranet-tmpl/prog/en/includes/erm-search.inc
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsEBSCOPackagesList.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsEBSCOTitlesList.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsLocalPackagesList.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/EHoldingsLocalTitlesList.vue
koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/ERMMain.vue
koha-tmpl/intranet-tmpl/prog/js/vue/fetch.js

index 31fe999..761e067 100644 (file)
@@ -12,8 +12,8 @@
 
     <div id="package_search" class="residentsearch">
         <form action="/cgi-bin/koha/erm/eholdings/local/packages" method="get">
-            <label class="tip" for="package_filter">Package search:</label>
-            <input class="head-searchbox" type="text" name="q" id="package_filter" size="40" />
+            <label class="tip" for="package_name_filter">Package search:</label>
+            <input class="head-searchbox" type="text" name="package_name" id="package_name_filter" size="40" />
             <input type="submit" value="OK" class="submit" />
         </form>
     </div>
@@ -21,7 +21,7 @@
     <div id="title_search" class="residentsearch">
         <form action="/cgi-bin/koha/erm/eholdings/local/titles" method="get">
             <label class="tip" for="title_filter">Title search:</label>
-            <input class="head-searchbox" type="text" name="q" id="title_filter" size="40" />
+            <input class="head-searchbox" type="text" name="publication_title" id="title_filter" size="40" />
             <input type="submit" value="OK" class="submit" />
         </form>
     </div>
index 899cd22..25e2a95 100644 (file)
                 :value="$t('Submit')"
             />
         </fieldset>
-        <div id="package_list_result" style="display: none">
-            <table id="package_list"></table>
+
+        <!-- We need to display the table element to initiate DataTable -->
+        <div
+            id="package_list_result"
+            :style="show_table ? 'display: block' : 'display: none'"
+        >
+            <div
+                v-if="
+                    local_count_packages !== undefined &&
+                    local_count_packages !== null
+                "
+            >
+                <router-link
+                    :to="local_packages_url"
+                >
+                    {{
+                        $t("{count} packages found locally", {
+                            count: local_count_packages,
+                        })
+                    }}</router-link
+                >
+            </div>
+            <div id="package_list_result">
+                <table id="package_list"></table>
+            </div>
         </div>
     </div>
 </template>
@@ -43,6 +66,7 @@ import { createVNode, render } from 'vue'
 import { useVendorStore } from "../../stores/vendors"
 import { useAVStore } from "../../stores/authorised_values"
 import { storeToRefs } from "pinia"
+import { fetchCountLocalPackages } from './../../fetch'
 
 export default {
     setup() {
@@ -58,6 +82,7 @@ export default {
             av_package_types,
             av_package_content_types,
             get_lib_from_av,
+            erm_providers,
         }
     },
     data: function () {
@@ -65,12 +90,17 @@ export default {
             packages: [],
             initialized: true,
             filters: {
-                package_name: this.$route.query.q || "",
-                content_type: "",
-                selection_type: "",
+                package_name: this.$route.query.package_name || "",
+                content_type: this.$route.query.content_type || "",
+                selection_type: this.$route.query.selection_type || "",
             },
+            show_table: false,
+            local_count_packages: null,
         }
     },
+    computed: {
+        local_packages_url() { return this.build_url("/cgi-bin/koha/erm/eholdings/local/packages") },
+    },
     beforeRouteEnter(to, from, next) {
         next(vm => {
             vm.build_datatable()
@@ -80,14 +110,34 @@ export default {
         show_package: function (package_id) {
             this.$router.push("/cgi-bin/koha/erm/eholdings/ebsco/packages/" + package_id)
         },
-        filter_table: function () {
-            $("#package_list_result").show()
+        build_url_params: function () {
+            return Object.entries(this.filters)
+                .map(([k, v]) => v ? k + "=" + v : undefined)
+                .filter(e => e !== undefined)
+                .join('&')
+        },
+        build_url: function (base_url) {
+            let params = this.build_url_params()
+            return base_url + (params.length ? '?' + params : '')
+        },
+        filter_table: async function () {
+            let new_route = this.build_url("/cgi-bin/koha/erm/eholdings/ebsco/packages")
+            this.$router.push(new_route)
+            this.show_table = true
+            this.local_count_packages = null
             $("#package_list").DataTable().draw()
+            if (this.erm_providers.includes('local')) {
+                this.local_count_packages = await fetchCountLocalPackages(this.filters)
+            }
         },
         build_datatable: function () {
             let show_package = this.show_package
             let get_lib_from_av = this.get_lib_from_av
+            if (!this.show_table) {
+                this.show_table = this.build_url_params().length ? true : false
+            }
             let filters = this.filters
+            let show_table = this.show_table
 
             window['vendors'] = this.vendors.map(e => {
                 e['_id'] = e['id']
@@ -125,7 +175,7 @@ export default {
                 ordering: false,
                 dom: '<"top pager"<"table_entries"ilp>>tr<"bottom pager"ip>',
                 aLengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]],
-                deferLoading: true,
+                deferLoading: show_table ? false : true,
                 autoWidth: false,
                 columns: [
                     {
index 6eab990..cae6d63 100644 (file)
                 $t("Please enter a search term")
             }}</span>
         </fieldset>
-        <div id="title_list_result" style="display: none">
-            <table id="title_list"></table>
+
+        <!-- We need to display the table element to initiate DataTable -->
+        <div
+            id="title_list_result"
+            :style="show_table ? 'display: block' : 'display: none'"
+        >
+            <div
+                v-if="
+                    local_count_titles !== undefined &&
+                    local_count_titles !== null
+                "
+            >
+                <router-link :to="local_titles_url">
+                    {{
+                        $t("{count} titles found locally", {
+                            count: local_count_titles,
+                        })
+                    }}</router-link
+                >
+            </div>
+            <div id="title_list_result">
+                <table id="title_list"></table>
+            </div>
         </div>
     </div>
 </template>
@@ -49,6 +70,7 @@ import { createVNode, render } from 'vue'
 import { useVendorStore } from "../../stores/vendors"
 import { useAVStore } from "../../stores/authorised_values"
 import { storeToRefs } from "pinia"
+import { fetchCountLocalTitles } from "./../../fetch"
 
 export default {
     setup() {
@@ -63,6 +85,7 @@ export default {
             vendors,
             av_title_publication_types,
             get_lib_from_av,
+            erm_providers,
         }
     },
     data: function () {
@@ -70,13 +93,18 @@ export default {
             titles: [],
             initialized: true,
             filters: {
-                publication_title: this.$route.query.q || "",
-                publication_type: "",
-                selection_type: "",
+                publication_title: this.$route.query.publication_title || "",
+                publication_type: this.$route.query.publication_type || "",
+                selection_type: this.$route.query.selection_type || "",
             },
             cannot_search: false,
+            show_table: false,
+            local_count_titles: null,
         }
     },
+    computed: {
+        local_titles_url() { return this.build_url("/cgi-bin/koha/erm/eholdings/local/titles") },
+    },
     beforeRouteEnter(to, from, next) {
         next(vm => {
             vm.build_datatable()
@@ -86,11 +114,27 @@ export default {
         show_title: function (title_id) {
             this.$router.push("/cgi-bin/koha/erm/eholdings/ebsco/titles/" + title_id)
         },
-        filter_table: function () {
+        build_url_params: function () {
+            return Object.entries(this.filters)
+                .map(([k, v]) => v ? k + "=" + v : undefined)
+                .filter(e => e !== undefined)
+                .join('&')
+        },
+        build_url: function (base_url) {
+            let params = this.build_url_params()
+            return base_url + (params.length ? '?' + params : '')
+        },
+        filter_table: async function () {
             if (this.filters.publication_title.length) {
                 this.cannot_search = false
-                $("#title_list_result").show()
+                let new_route = this.build_url("/cgi-bin/koha/erm/eholdings/ebsco/titles")
+                this.$router.push(new_route)
+                this.show_table = true
+                this.local_count_titles = null
                 $("#title_list").DataTable().draw()
+                if (this.erm_providers.includes('local')) {
+                    this.local_count_titles = await fetchCountLocalTitles(this.filters)
+                }
             } else {
                 this.cannot_search = true
             }
@@ -98,7 +142,11 @@ export default {
         build_datatable: function () {
             let show_title = this.show_title
             let get_lib_from_av = this.get_lib_from_av
+            if (!this.show_table) {
+                this.show_table = this.build_url_params().length ? true : false
+            }
             let filters = this.filters
+            let show_table = this.show_table
 
             window['vendors'] = this.vendors.map(e => {
                 e['_id'] = e['id']
@@ -120,7 +168,7 @@ export default {
                     return filters.publication_title || ""
                 },
                 publication_type: function () {
-                    return filters.content_type_search || ""
+                    return filters.publication_type || ""
                 },
                 selection_type: function () {
                     return filters.selection_type || ""
index 49b2fe9..94a9c9f 100644 (file)
@@ -42,7 +42,8 @@ export default {
             packages: [],
             initialized: false,
             filters: {
-                package_name: this.$route.query.q || "",
+                package_name: this.$route.query.package_name || "",
+                content_type: this.$route.query.content_type || "",
             },
         }
     },
@@ -95,8 +96,15 @@ export default {
                 },
                 embed: ['resources+count', 'vendor.name'],
                 order: [[0, "asc"]],
-                search: { search: filters.package_name },
                 autoWidth: false,
+                searchCols: [
+                    { search: filters.package_name },
+                    null,
+                    null,
+                    { search: filters.content_type },
+                    null,
+                    null,
+                ],
                 columns: [
                     {
                         title: __("Name"),
@@ -200,6 +208,11 @@ export default {
                     $("#" + table_id).find("thead th").eq(3).attr('data-filter', 'av_package_content_types')
                 }
             }, eholdings_packages_table_settings, 1)
+
+            if (filters.package_name) {
+                //$("#package_list").DataTable().column(0).search(filters.package_name).draw()
+            }
+            //myTable.column(0).search(control_id).column(1).search(sample_id).draw();
         },
     },
     components: { Toolbar },
index ffe6c0d..e2c6841 100644 (file)
@@ -41,7 +41,8 @@ export default {
             titles: [],
             initialized: false,
             filters: {
-                publication_title: this.$route.query.q || "",
+                publication_title: this.$route.query.publication_title || "",
+                publication_type: this.$route.query.publication_type || "",
             },
             cannot_search: false,
         }
@@ -94,8 +95,13 @@ export default {
                 },
                 embed: ["resources.package"],
                 order: [[0, "asc"]],
-                search: { search: filters.publication_title },
                 autoWidth: false,
+                searchCols: [
+                    { search: filters.publication_title },
+                    null,
+                    { search: filters.publication_type },
+                    null,
+                ],
                 columns: [
                     {
                         title: __("Title"),
index 7a58cae..f005507 100644 (file)
     <div v-else>
         {{
             $t(
-                "The E-Resource management module is disabled. Turn on 'ERMModule' to use it."
+                "The E-Resource management module is disabled, turn on 'ERMModule' to use it"
             )
         }}
     </div>
index 6818526..f578f6f 100644 (file)
@@ -207,6 +207,30 @@ export const fetchEBSCOPackages = function () {
     return _fetchPackages(apiUrl);
 };
 
+export const fetchCountLocalPackages = async function (filters) {
+    const q = {
+        "me.name": { like: "%" + filters.package_name + "%" },
+        ...(filters.content_type
+            ? { "me.content_type": filters.content_type }
+            : {}),
+    };
+
+    const params = {
+        _page: 1,
+        _per_page: 1,
+        q: JSON.stringify(q),
+    };
+    let count_local_packages;
+    var apiUrl = "/api/v1/erm/eholdings/local/packages";
+    await fetch(apiUrl + "?" + new URLSearchParams(params))
+        //.then(checkError)
+        .then(
+            (response) =>
+                (count_local_packages = response.headers.get("X-Total-Count"))
+        );
+    return count_local_packages;
+};
+
 export const _fetchTitle = async function (apiUrl, title_id) {
     if (!title_id) return;
     let title;
@@ -258,6 +282,31 @@ export const fetchEBSCOTitles = function () {
     return _fetchTitles(apiUrl);
 };
 
+export const fetchCountLocalTitles = async function (filters) {
+    const q = {
+        "me.publication_title": {
+            like: "%" + filters.publication_title + "%",
+        },
+        ...(filters.publication_type
+            ? { "me.publication_type": filters.publication_type }
+            : {}),
+    };
+    const params = {
+        _page: 1,
+        _per_page: 1,
+        q: JSON.stringify(q),
+    };
+    let count_local_titles;
+    var apiUrl = "/api/v1/erm/eholdings/local/titles";
+    await fetch(apiUrl + "?" + new URLSearchParams(params))
+        //.then(checkError)
+        .then(
+            (response) =>
+                (count_local_titles = response.headers.get("X-Total-Count"))
+        );
+    return count_local_titles;
+};
+
 export const _fetchResource = async function (apiUrl, resource_id) {
     if (!resource_id) return;
     let resource;