From e8ea2734d363958342a1f0f413adae0270eb9808 Mon Sep 17 00:00:00 2001 From: Matt Blenkinsop Date: Wed, 11 Sep 2024 09:11:32 +0000 Subject: [PATCH] Bug 38010: Add vue app and list component This patch adds the base vue app as well as the component to list vendors --- acqui/booksellers.pl | 10 + acqui/vendors.pl | 54 ++++ api/v1/swagger/definitions/vendor.yaml | 3 + .../swagger/paths/acquisitions_vendors.yaml | 1 + debian/templates/apache-shared-intranet.conf | 1 + .../prog/en/includes/acquisitions-toolbar.inc | 2 +- .../prog/en/modules/acqui/acqui-home.tt | 8 +- .../prog/en/modules/acqui/booksellers.tt | 2 +- .../prog/en/modules/acqui/vendors.tt | 47 ++++ .../prog/js/vue/components/Vendors/Home.vue | 9 + .../prog/js/vue/components/Vendors/Main.vue | 154 +++++++++++ .../js/vue/components/Vendors/VendorList.vue | 250 ++++++++++++++++++ .../js/vue/fetch/acquisition-api-client.js | 33 ++- .../prog/js/vue/modules/vendors.ts | 62 +++++ .../prog/js/vue/routes/vendors.js | 43 +++ .../prog/js/vue/stores/authorised-values.js | 2 + .../prog/js/vue/stores/vendors.js | 7 + rspack.config.js | 3 +- webpack.config.js | 1 + 19 files changed, 682 insertions(+), 10 deletions(-) create mode 100755 acqui/vendors.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/acqui/vendors.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Home.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorList.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/routes/vendors.js diff --git a/acqui/booksellers.pl b/acqui/booksellers.pl index beaf0e7b0bc..e2784430329 100755 --- a/acqui/booksellers.pl +++ b/acqui/booksellers.pl @@ -172,4 +172,14 @@ $template->param( ); $template->{VARS}->{'allbaskets'} = $allbaskets; + + +$template->param( + loop_suppliers => $loop_suppliers, + supplier => ( $booksellerid || $supplier ), + count => $supplier_count, + has_budgets => $has_budgets, +); +$template->{VARS}->{'allbaskets'} = $allbaskets; + output_html_with_http_headers $query, $cookie, $template->output; diff --git a/acqui/vendors.pl b/acqui/vendors.pl new file mode 100755 index 00000000000..a160284308c --- /dev/null +++ b/acqui/vendors.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl + +# Copyright 2024 PTFS Europe +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; +use C4::Auth qw( get_template_and_user haspermission ); +use C4::Output qw( output_html_with_http_headers ); +use CGI qw ( -utf8 ); + +use C4::Context; + +use Koha::Acquisition::Currencies; + +my $query = CGI->new; +my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user( + { + template_name => 'acqui/vendors.tt', + query => $query, + type => 'intranet', + flagsrequired => { acquisition => '*' }, + } +); + +my $user_permissions = {}; +my $var_data = $template->{VARS}; +foreach my $key ( keys %{$var_data} ) { + $user_permissions->{$key} = $var_data->{$key} if ( $key =~ /CAN_user_(.*)/ ); +} + +my @gst_values = map { option => $_ + 0.0 }, split( '\|', C4::Context->preference("TaxRates") ); + +$template->param( + user_permissions => $user_permissions, + currencies => Koha::Acquisition::Currencies->search->unblessed, + gst_values => \@gst_values, + edifact => C4::Context->preference('EDIFACT') +); + +output_html_with_http_headers $query, $cookie, $template->output; diff --git a/api/v1/swagger/definitions/vendor.yaml b/api/v1/swagger/definitions/vendor.yaml index 6918d004696..87a5c4440dc 100644 --- a/api/v1/swagger/definitions/vendor.yaml +++ b/api/v1/swagger/definitions/vendor.yaml @@ -119,6 +119,9 @@ properties: description: List of aliases items: $ref: "vendor_alias.yaml" + baskets: + type: array + description: List of baskets subscriptions: type: array description: List of subscriptions diff --git a/api/v1/swagger/paths/acquisitions_vendors.yaml b/api/v1/swagger/paths/acquisitions_vendors.yaml index aaaed8c534b..e671dea9742 100644 --- a/api/v1/swagger/paths/acquisitions_vendors.yaml +++ b/api/v1/swagger/paths/acquisitions_vendors.yaml @@ -35,6 +35,7 @@ type: string enum: - aliases + - baskets - subscriptions collectionFormat: csv responses: diff --git a/debian/templates/apache-shared-intranet.conf b/debian/templates/apache-shared-intranet.conf index 49b742f868a..da68e9dfb4d 100644 --- a/debian/templates/apache-shared-intranet.conf +++ b/debian/templates/apache-shared-intranet.conf @@ -24,6 +24,7 @@ RewriteRule ^/cgi-bin/koha/erm/.*$ /cgi-bin/koha/erm/erm.pl [PT] RewriteCond %{REQUEST_URI} !^/cgi-bin/koha/preservation/.*.pl$ RewriteRule ^/cgi-bin/koha/preservation/.*$ /cgi-bin/koha/preservation/home.pl [PT] RewriteRule ^/cgi-bin/koha/admin/record_sources(.*)?$ /cgi-bin/koha/admin/record_sources.pl$1 [PT] +RewriteRule ^/cgi-bin/koha/vendors(.*)?$ /cgi-bin/koha/acqui/vendors.pl$1 [PT] Alias "/api" "/usr/share/koha/api" diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-toolbar.inc index d6b6ff9f98b..470bbb9212f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/acquisitions-toolbar.inc @@ -30,7 +30,7 @@ [% END %] [% ELSE %] - + [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/acqui-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/acqui-home.tt index 533cc7285e8..c8e18c09156 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/acqui-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/acqui-home.tt @@ -49,12 +49,8 @@
- Search vendors -
-

- -

-
+ View vendors + Vendor list
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/booksellers.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/booksellers.tt index 726e10188ab..3b4d5e03929 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/booksellers.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/booksellers.tt @@ -13,7 +13,7 @@ [% INCLUDE 'doc-head-close.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/vendors.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/vendors.tt new file mode 100644 index 00000000000..4497e3362a1 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/vendors.tt @@ -0,0 +1,47 @@ +[% USE raw %] +[% USE To %] +[% USE Asset %] +[% USE KohaDates %] +[% USE TablesSettings %] +[% PROCESS 'i18n.inc' %] +[% SET footerjs = 1 %] +[% PROCESS 'patron-search.inc' %] +[% INCLUDE 'doc-head-open.inc' %] +[% FILTER collapse %] + [% t("Vendors") | html %] › + [% t("Koha") | html %] +[% END %] +[% INCLUDE 'doc-head-close.inc' %] + + + +[% WRAPPER 'header.inc' %] + [% INCLUDE 'acquisitions-search.inc' %] +[% END %] + +
+ +[% MACRO jsinclude BLOCK %] + [% INCLUDE 'calendar.inc' %] + [% INCLUDE 'datatables.inc' %] + [% INCLUDE 'columns_settings.inc' %] + [% INCLUDE 'js-patron-format.inc' %] + [% INCLUDE 'js-date-format.inc' %] + + + + + [% Asset.js("js/vue/dist/acquisitions.js") | $raw %] + [% INCLUDE 'select2.inc' %] + [% SET columns = ['cardnumber','name','category','branch','action'] %] + [% PROCESS patron_search_modal columns => columns, modal_title => t("Select user") %] + [% PROCESS patron_search_js columns => columns, filter => erm_users, actions => ["select"], preview_on_name_click => 1 %] + +[% END %] +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Home.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Home.vue new file mode 100644 index 00000000000..df90ee491ad --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Home.vue @@ -0,0 +1,9 @@ + + + + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue new file mode 100644 index 00000000000..b6cb622e039 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorList.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorList.vue new file mode 100644 index 00000000000..e4d3416a583 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorList.vue @@ -0,0 +1,250 @@ + + + + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/acquisition-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/acquisition-api-client.js index 72f1a1d79c8..2f1417fe4c2 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/acquisition-api-client.js +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/acquisition-api-client.js @@ -9,15 +9,46 @@ export class AcquisitionAPIClient extends HttpClient { get vendors() { return { + get: id => + this.get({ + endpoint: "vendors/" + id, + headers: { + "x-koha-embed": "aliases", + }, + }), getAll: (query, params) => this.getAll({ endpoint: "vendors", query, params, headers: { - "x-koha-embed": "aliases", + "x-koha-embed": "aliases,baskets", }, }), + delete: id => + this.delete({ + endpoint: "vendors/" + id, + }), + create: vendor => + this.post({ + endpoint: "vendors", + body: vendor, + }), + update: (vendor, id) => + this.put({ + endpoint: "vendors/" + id, + body: vendor, + }), + count: (query = {}) => + this.count({ + endpoint: + "vendors?" + + new URLSearchParams({ + _page: 1, + _per_page: 1, + ...(query && { q: JSON.stringify(query) }), + }), + }), }; } } diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts new file mode 100644 index 00000000000..26e61adf75f --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts @@ -0,0 +1,62 @@ +import { createApp } from "vue"; +import { createWebHistory, createRouter } from "vue-router"; +import { createPinia } from "pinia"; + +import { library } from "@fortawesome/fontawesome-svg-core"; +import { + faPlus, + faMinus, + faPencil, + faTrash, + faSpinner, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; +import vSelect from "vue-select"; + +library.add(faPlus, faMinus, faPencil, faTrash, faSpinner); + +import App from "../components/Vendors/Main.vue"; + +import { routes as routesDef } from "../routes/vendors"; + +import { useMainStore } from "../stores/main"; +import { useVendorStore } from "../stores/vendors"; +import { useAVStore } from "../stores/authorised-values"; +import { useNavigationStore } from "../stores/navigation"; +import i18n from "../i18n"; + +const pinia = createPinia(); + +const mainStore = useMainStore(pinia); +const AVStore = useAVStore(pinia); +const navigationStore = useNavigationStore(pinia); +const routes = navigationStore.setRoutes(routesDef); + +const router = createRouter({ + history: createWebHistory(), + linkActiveClass: "current", + routes, +}); + +const app = createApp(App); + +const rootComponent = app + .use(i18n) + .use(pinia) + .use(router) + .component("font-awesome-icon", FontAwesomeIcon) + .component("v-select", vSelect); + +app.config.unwrapInjectedRef = true; +app.provide("vendorStore", useVendorStore(pinia)); +app.provide("mainStore", mainStore); +app.provide("AVStore", AVStore); +app.provide("navigationStore", navigationStore); + +app.mount("#__vendors"); + +const { removeMessages } = mainStore; +router.beforeEach((to, from) => { + navigationStore.$patch({ current: to.matched, params: to.params || {} }); + removeMessages(); // This will actually flag the messages as displayed already +}); diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/vendors.js b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/vendors.js new file mode 100644 index 00000000000..8a2908e57cb --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/vendors.js @@ -0,0 +1,43 @@ +import { markRaw } from "vue"; + +import Home from "../components/Vendors/Home.vue"; +import VendorList from "../components/Vendors/VendorList.vue"; +import VendorShow from "../components/Vendors/VendorShow.vue"; + +import { $__ } from "../i18n"; + +export const routes = [ + { + path: "/cgi-bin/koha/acqui/booksellers.pl", + is_default: true, + is_base: true, + title: $__("Vendors"), + children: [ + { + path: "", + name: "Home", + component: markRaw(Home), + is_navigation_item: false, + }, + { + path: "/cgi-bin/koha/vendors", + title: $__("Vendor list"), + icon: "fa fa-check-circle", + is_end_node: true, + children: [ + { + path: "", + name: "VendorList", + component: markRaw(VendorList), + }, + { + path: ":vendor_id", + name: "VendorShow", + component: markRaw(VendorShow), + title: $__("Show vendor"), + }, + ], + }, + ], + }, +]; diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/authorised-values.js b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/authorised-values.js index ef77373d689..ebe6a80b5fc 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/authorised-values.js +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/authorised-values.js @@ -42,6 +42,8 @@ export const useAVStore = defineStore("authorised_values", { av_database_reports_metrics: [], av_title_reports_metrics: [], av_item_reports_metrics: [], + av_vendor_types: [], + av_vendor_interface_types: [], }), actions: { get_lib_from_av(arr_name, av) { diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/vendors.js b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/vendors.js index 3f8fdfdfc2c..34b3351af89 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/vendors.js +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/vendors.js @@ -3,5 +3,12 @@ import { defineStore } from "pinia"; export const useVendorStore = defineStore("vendors", { state: () => ({ vendors: [], + currencies: [], + gstValues: [], + config: { + settings: { + edifact: false, + }, + }, }), }); diff --git a/rspack.config.js b/rspack.config.js index 6a8e40c4f6e..3fa96ce5f91 100644 --- a/rspack.config.js +++ b/rspack.config.js @@ -13,6 +13,7 @@ module.exports = { "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/preservation.ts", "admin/record_sources": "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/admin/record_sources.ts", + vendors: "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts", }, output: { filename: "[name].js", @@ -72,4 +73,4 @@ module.exports = { "datatables.net-buttons/js/buttons.print": "DataTable", "datatables.net-buttons/js/buttons.colVis": "DataTable", }, -}; +}; \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index ae87653c244..b80cebdb653 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,6 +8,7 @@ module.exports = { erm: "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/erm.ts", preservation: "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/preservation.ts", "admin/record_sources": "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/admin/record_sources.ts", + vendors: "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts", }, output: { filename: "[name].js", -- 2.39.3 (Apple Git-146)