From 6dab32ee0264294d70ae596d99019ff185e439a6 Mon Sep 17 00:00:00 2001 From: Pedro Amorim Date: Wed, 6 Aug 2025 10:13:47 +0000 Subject: [PATCH] Bug 37762: VueJS ILL Module Signed-off-by: Jason Robb Signed-off-by: Lisette Scheer Signed-off-by: Lucas Gass --- debian/templates/apache-shared-intranet.conf | 2 + etc/koha-httpd.conf | 2 + ill/ill.pl | 36 + .../intranet-tmpl/prog/en/includes/header.inc | 2 +- .../prog/en/modules/ill/ill-requests.tt | 3 + .../intranet-tmpl/prog/en/modules/ill/ill.tt | 35 + .../prog/en/modules/intranet-main.tt | 2 +- .../prog/js/fetch/ill-api-client.js | 92 ++ .../prog/js/vue/components/ILL/Home.vue | 19 + .../prog/js/vue/components/ILL/ISO18626.js | 376 ++++++++ .../components/ILL/ISO18626MessageDisplay.vue | 238 +++++ .../prog/js/vue/components/ILL/Main.vue | 129 +++ .../js/vue/components/ILL/ProgressRequest.vue | 221 +++++ .../ILL/RequestingAgencyResource.vue | 201 ++++ .../vue/components/ILL/SupplyingResource.vue | 877 ++++++++++++++++++ .../prog/js/vue/components/LinkWrapper.vue | 4 +- .../ModuleDashboard/Widgets/ILLRequests.vue | 200 ++++ .../prog/js/vue/fetch/api-client.js | 2 + .../intranet-tmpl/prog/js/vue/modules/ill.ts | 110 +++ .../intranet-tmpl/prog/js/vue/routes/ill.js | 130 +++ .../intranet-tmpl/prog/js/vue/stores/ill.js | 17 + rspack.config.js | 4 + 22 files changed, 2699 insertions(+), 3 deletions(-) create mode 100755 ill/ill.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill.tt create mode 100644 koha-tmpl/intranet-tmpl/prog/js/fetch/ill-api-client.js create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/Home.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ISO18626.js create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ISO18626MessageDisplay.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/Main.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ProgressRequest.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/RequestingAgencyResource.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/SupplyingResource.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/components/ModuleDashboard/Widgets/ILLRequests.vue create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/modules/ill.ts create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/routes/ill.js create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/stores/ill.js diff --git a/debian/templates/apache-shared-intranet.conf b/debian/templates/apache-shared-intranet.conf index 54155faef8..30c1bddbc6 100644 --- a/debian/templates/apache-shared-intranet.conf +++ b/debian/templates/apache-shared-intranet.conf @@ -24,6 +24,8 @@ RewriteRule ^(.*)_[0-9]{2}\.[0-9]{7}\.(js|css)$ $1.$2 [L] RewriteRule ^/cgi-bin/koha/erm/.*$ /cgi-bin/koha/erm/erm.pl [PT] RewriteRule ^/cgi-bin/koha/sip2/.*$ /cgi-bin/koha/sip2/sip2.pl [PT] +RewriteCond %{REQUEST_URI} !ill-requests\.pl$ +RewriteRule ^/cgi-bin/koha/ill/.*$ /cgi-bin/koha/ill/ill.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] diff --git a/etc/koha-httpd.conf b/etc/koha-httpd.conf index 367d3bce8f..3f2da86d68 100644 --- a/etc/koha-httpd.conf +++ b/etc/koha-httpd.conf @@ -236,6 +236,8 @@ RewriteRule ^/cgi-bin/koha/erm/.*$ /cgi-bin/koha/erm/erm.pl [PT] RewriteRule ^/cgi-bin/koha/sip2/.*$ /cgi-bin/koha/sip2/sip2.pl [PT] + RewriteCond %{REQUEST_URI} !ill-requests\.pl$ + RewriteRule ^/cgi-bin/koha/ill/.*$ /cgi-bin/koha/ill/ill.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] diff --git a/ill/ill.pl b/ill/ill.pl new file mode 100755 index 0000000000..7d3d3ca483 --- /dev/null +++ b/ill/ill.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl + +# 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 CGI qw ( -utf8 ); +use C4::Context; +use C4::Auth qw( get_template_and_user ); +use C4::Output qw( output_html_with_http_headers ); + +my $input = CGI->new; + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "ill/ill.tt", + query => $input, + type => "intranet", + flagsrequired => { ill => '*' }, + } +); + +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc index 6cedc17f39..2f0ae2b269 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc @@ -56,7 +56,7 @@ [% END %]
  • Authorities
  • [% IF Koha.Preference('ILLModule') && CAN_user_ill %] -
  • ILL requests
  • +
  • Interlibrary loans
  • [% END %] [% IF ( CAN_user_serials ) %]
  • Serials
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt index fbca03db93..302b9054f2 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt @@ -32,6 +32,9 @@ [% WRAPPER 'sub-header.inc' %] [% WRAPPER breadcrumbs %] + [% WRAPPER breadcrumb_item %] + Interlibrary loans + [% END %] [% WRAPPER breadcrumb_item bc_active = (op == 'illlist' || op == 'batch_list' ? 1 : 0) %] [% IF op == 'batch_list' %] ILL batch requests diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill.tt new file mode 100644 index 0000000000..ec0c6a43c4 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill.tt @@ -0,0 +1,35 @@ +[% 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("Interlibrary loans") | html %] + › [% t("Koha") | html %] + [% END %] +[% INCLUDE 'doc-head-close.inc' %] + + + +[% WRAPPER 'header.inc' %] + [% INCLUDE 'cat-search.inc' %] +[% END %] + +
    + +[% MACRO jsinclude BLOCK %] + [% INCLUDE 'calendar.inc' %] + [% INCLUDE 'datatables.inc' %] + [% INCLUDE 'js-date-format.inc' %] + + [% Asset.js("js/vue/dist/ill.js") | $raw %] +[% END %] +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt index afa39d0021..c6a6d6d69a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt @@ -115,7 +115,7 @@ [% IF Koha.Preference('ILLModule') && CAN_user_ill %]
  • - ILL requests + Interlibrary loans
  • [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/ill-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/ill-api-client.js new file mode 100644 index 0000000000..bb7b20cd49 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/ill-api-client.js @@ -0,0 +1,92 @@ +export class ILLAPIClient { + constructor(HttpClient) { + this.httpClient = new HttpClient({ + baseURL: "/api/v1/ill/", + }); + } + + get config() { + return { + get: () => { + ILLModule: 1; + }, // TODO: Fetch from API + }; + } + + get supplying() { + return { + get: id => + this.httpClient.get({ + endpoint: "iso18626_requests/" + id, + headers: { + "x-koha-embed": "requesting_agency,messages,hold", + }, + }), + getAll: (query, params) => + this.httpClient.getAll({ + endpoint: "iso18626_requests", + query, + params, + }), + patch: (iso18626_request, id) => + this.httpClient.patch({ + endpoint: "iso18626_requests/" + id, + body: iso18626_request, + }), + count: (query = {}) => + this.httpClient.count({ + endpoint: + "iso18626_requests?" + + new URLSearchParams({ + _page: 1, + _per_page: 20, + ...(query && { q: JSON.stringify(query) }), + }), + }), + }; + } + + get requesting_agencies() { + return { + get: id => + this.httpClient.get({ + endpoint: "iso18626_requesting_agencies/" + id, + headers: { + "x-koha-embed": "ill_partner", + }, + }), + getAll: (query, params) => + this.httpClient.getAll({ + endpoint: "iso18626_requesting_agencies", + query, + params, + }), + delete: id => + this.httpClient.delete({ + endpoint: "iso18626_requesting_agencies/" + id, + }), + create: iso18626_requesting_agency => + this.httpClient.post({ + endpoint: "iso18626_requesting_agencies", + body: iso18626_requesting_agency, + }), + update: (iso18626_requesting_agency, id) => + this.httpClient.put({ + endpoint: "iso18626_requesting_agencies/" + id, + body: iso18626_requesting_agency, + }), + count: (query = {}) => + this.httpClient.count({ + endpoint: + "iso18626_requesting_agencies?" + + new URLSearchParams({ + _page: 1, + _per_page: 1, + ...(query && { q: JSON.stringify(query) }), + }), + }), + }; + } +} + +export default ILLAPIClient; diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/Home.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/Home.vue new file mode 100644 index 0000000000..c8a08cbdb3 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/Home.vue @@ -0,0 +1,19 @@ + + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ISO18626.js b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ISO18626.js new file mode 100644 index 0000000000..bcb7faf1d9 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ISO18626.js @@ -0,0 +1,376 @@ +import { $__ } from "@koha-vue/i18n"; + +export function ISO18626() { + const getCodesForElement = element => { + const codes = [ + { + element: "courierName", + values: [ + { + value: "DB Schenker", + description: $__("DB Schenker"), + }, + { + value: "DHL", + description: $__("DHL"), + }, + { + value: "Fedex", + description: $__("Fedex"), + }, + { + value: "PostNord AB", + description: $__("PostNord AB"), + }, + { + value: "UPS", + description: $__("UPS"), + }, + ], + }, + { + element: "deliveryMethod", + values: [ + { + value: "ArticleExchange", + description: $__("Article Exchange"), + }, + { + value: "Courier", + description: $__("Courier"), + }, + { + value: "Email", + description: $__("Email"), + }, + { + value: "FTP", + description: $__("FTP – File Transfer Protocol"), + }, + { + value: "Mail", + description: $__("Mail"), + }, + { + value: "Odyssey", + description: $__("Odyssey"), + }, + { + value: "URL", + description: $__("Website to download from"), + }, + ], + }, + { + element: "itemFormat", + values: [ + { + value: "CassetteTape", + description: $__("Cassette tape"), + }, + { + value: "CD", + description: $__("CD"), + }, + { + value: "CD-ROM", + description: $__("CD-ROM"), + }, + { + value: "Daisy-ROM", + description: $__("Daisy-ROM"), + }, + { + value: "DVD", + description: $__("DVD"), + }, + { + value: "EPUB", + description: $__("EPUB"), + }, + { + value: "EPUB2", + description: $__("EPUB2"), + }, + { + value: "EPUB3", + description: $__("EPUB3"), + }, + { + value: "JPEG", + description: $__("JPEG"), + }, + { + value: "LargePrint", + description: $__("Large print"), + }, + { + value: "LP", + description: $__("LP"), + }, + { + value: "Microform", + description: $__("Microform"), + }, + { + value: "MP3", + description: $__("MP3"), + }, + { + value: "Multimedia", + description: $__("Multimedia"), + }, + { + value: "PaperCopy", + description: $__("Paper copy"), + }, + { + value: "PDF", + description: $__("PDF"), + }, + { + value: "Printed", + description: $__("Printed"), + }, + { + value: "Tape", + description: $__("Tape"), + }, + { + value: "TIFF", + description: $__("TIFF"), + }, + { + value: "UltraHD", + description: $__("Ultra HD"), + }, + { + value: "VHS", + description: $__("VHS"), + }, + ], + }, + { + element: "loanCondition", + values: [ + { + value: "LibraryUseOnly", + description: $__("Use in library only"), + }, + { + value: "WatchLibraryUseOnly", + description: $__("Supervised use in library only"), + }, + { + value: "NoReproduction", + description: $__("No reproduction"), + }, + { + value: "SignatureRequired", + description: $__("Signature required"), + }, + { + value: "SpecCollSupervReq", + description: $__( + "Special collections supervision required" + ), + }, + ], + }, + { + element: "paymentMethod", + values: [ + { + value: "BankTransfer", + description: $__("Bank transfer"), + }, + { + value: "CreditCard", + description: $__("Credit card"), + }, + { + value: "DebitCard", + description: $__("Debit card"), + }, + { + value: "EFTS", + description: $__("Electronic Fund Transfer System"), + }, + { + value: "IBS", + description: $__( + "Interloan Billing System (New Zealand)" + ), + }, + { + value: "IIBS", + description: $__( + "International Interloan Billing System (New Zealand)" + ), + }, + { + value: "IFLAVoucher", + description: $__("IFLA Voucher"), + }, + { + value: "IFM", + description: $__("OCLC fee management system"), + }, + { + value: "LAPS", + description: $__("Libraries Australia Payment Service"), + }, + { + value: "Paypal", + description: $__("Paypal"), + }, + ], + }, + { + element: "reasonRetry", + values: [ + { + value: "AtBindery", + description: $__("At bindery"), + }, + { + value: "CostExceedsMaxCost", + description: $__("Cost exceeds max cost"), + }, + { + value: "CourierNotSupp", + description: $__("Courier not supported"), + }, + { + value: "MultiVolAvail", + description: $__( + "More than one volume can fulfil the request" + ), + }, + { + value: "MustMeetLoanCondition", + description: $__("Loan condition shall be met"), + }, + { + value: "NotCurrentAvailableForILL", + description: $__("Not currently available for ILL"), + }, + { + value: "NotFoundAsCited", + description: $__("Not found as cited"), + }, + { + value: "OnLoan", + description: $__("On loan"), + }, + { + value: "OnOrder", + description: $__("On order"), + }, + { + value: "ReqDelDateNotPossible", + description: $__( + "Requested delivery date not possible" + ), + }, + { + value: "ReqDelMethodNotSupp", + description: $__( + "Requested delivery method not supported" + ), + }, + { + value: "ReqEditionNotPossible", + description: $__( + "Requested edition cannot be provided" + ), + }, + { + value: "ReqFormatNotPossible", + description: $__("Requested format not possible"), + }, + { + value: "ReqPayMethodNotSupported", + description: $__( + "Requested payment method not supported" + ), + }, + { + value: "ReqServLevelNotSupp", + description: $__( + "Requested service level not supported" + ), + }, + { + value: "ReqServTypeNotPossible", + description: $__("Requested service type not possible"), + }, + ], + }, + { + element: "reasonUnfilled", + values: [ + { + value: "NonCirculating", + description: $__("Non-circulating (e.g. handbook)"), + }, + { + value: "NotAvailableForILL", + description: $__("Not available for ILL"), + }, + { + value: "NotHeld", + description: $__("Not held"), + }, + { + value: "NotOnShelf", + description: $__("Not on shelf"), + }, + { + value: "PolicyProblem", + description: $__("Policy problem"), + }, + { + value: "PoorCondition", + description: $__("Poor condition"), + }, + ], + }, + { + element: "serviceLevel", + values: [ + { + value: "Express", + description: $__("Express (Australia)"), + }, + { + value: "Normal", + description: $__("Normal (Prioritaire A)"), + }, + { + value: "Rush", + description: $__("Rush (Australia)"), + }, + { + value: "SecondaryMail", + description: $__("Secondary mail (Prioritaire B)"), + }, + { + value: "Standard", + description: $__("Standard (Australia)"), + }, + { + value: "Urgent", + description: $__("Urgent"), + }, + ], + }, + ]; + + return codes.find(code => code.element === element).values; + }; + + return { + getCodesForElement, + }; +} diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ISO18626MessageDisplay.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ISO18626MessageDisplay.vue new file mode 100644 index 0000000000..f0bbdaf9d3 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ISO18626MessageDisplay.vue @@ -0,0 +1,238 @@ + + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/Main.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/Main.vue new file mode 100644 index 0000000000..77c80939b3 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/Main.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ProgressRequest.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ProgressRequest.vue new file mode 100644 index 0000000000..2b98a9f3e8 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/ProgressRequest.vue @@ -0,0 +1,221 @@ + + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/RequestingAgencyResource.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/RequestingAgencyResource.vue new file mode 100644 index 0000000000..93847d6774 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/RequestingAgencyResource.vue @@ -0,0 +1,201 @@ + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/SupplyingResource.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/SupplyingResource.vue new file mode 100644 index 0000000000..cdae7bb322 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ILL/SupplyingResource.vue @@ -0,0 +1,877 @@ + + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/LinkWrapper.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/LinkWrapper.vue index df207c4140..6ee627ef74 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/LinkWrapper.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/LinkWrapper.vue @@ -15,7 +15,9 @@ > - + 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 2906a9c296..96ae25422a 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 HttpClient from "./http-client"; import ERMAPIClient from "@fetch/erm-api-client"; +import ILLAPIClient from "@fetch/ill-api-client"; import PatronAPIClient from "@fetch/patron-api-client"; import AcquisitionAPIClient from "@fetch/acquisition-api-client"; import AdditionalFieldsAPIClient from "@fetch/additional-fields-api-client"; @@ -14,6 +15,7 @@ import PreservationAPIClient from "@fetch/preservation-api-client"; export const APIClient = { erm: new ERMAPIClient(HttpClient), + ill: new ILLAPIClient(HttpClient), patron: new PatronAPIClient(HttpClient), acquisition: new AcquisitionAPIClient(HttpClient), additional_fields: new AdditionalFieldsAPIClient(HttpClient), diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/ill.ts b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/ill.ts new file mode 100644 index 0000000000..89e412abcd --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/ill.ts @@ -0,0 +1,110 @@ +import { createApp } from "vue"; +import { createWebHistory, createRouter } from "vue-router"; +import { createPinia } from "pinia"; + +import { library } from "@fortawesome/fontawesome-svg-core"; +import { + faList, + faPlus, + faMinus, + faPencil, + faTrash, + faSpinner, + faGlobe, + faUpload, + faDownload, + faBuildingColumns, + faCheck, + faXmark, + faRepeat, + faBox, + faCalendarDays, + faBan, + faCog, + faEllipsisVertical, + faArrowRight, + faArrowLeft, + faArrowUp, + faArrowDown, + faSearch, +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; +import vSelect from "vue-select"; + +library.add( + faList, + faPlus, + faMinus, + faPencil, + faTrash, + faSpinner, + faGlobe, + faUpload, + faDownload, + faBuildingColumns, + faCheck, + faXmark, + faRepeat, + faBox, + faCalendarDays, + faBan, + faCog, + faEllipsisVertical, + faArrowRight, + faArrowLeft, + faArrowUp, + faArrowDown, + faSearch +); + +import App from "../components/ILL/Main.vue"; + +import { routes as routesDef } from "../routes/ill"; + +import { useMainStore } from "../stores/main"; +import { useVendorStore } from "../stores/vendors"; +import { useILLStore } from "../stores/ill"; +import { useNavigationStore } from "../stores/navigation"; +import i18n from "@koha-vue/i18n"; + +const pinia = createPinia(); + +const mainStore = useMainStore(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("navigationStore", navigationStore); +const ILLStore = useILLStore(pinia); +app.provide("ILLStore", ILLStore); + +const { removeMessages } = mainStore; +router.beforeEach((to, from) => { + navigationStore.$patch({ + current: to.matched, + params: to.params || {}, + from, + }); + removeMessages(); +}); + +router.isReady().then(() => { + app.mount("#ill"); +}); diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/ill.js b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/ill.js new file mode 100644 index 0000000000..c50009d75c --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/ill.js @@ -0,0 +1,130 @@ +import { markRaw } from "vue"; + +import Home from "../components/ILL/Home.vue"; +import ProgressRequest from "../components/ILL/ProgressRequest.vue"; +import ResourceWrapper from "../components/ResourceWrapper.vue"; + +import { $__ } from "@koha-vue/i18n"; + +export const routes = [ + { + path: "/cgi-bin/koha/ill/ill.pl", + redirect: "/cgi-bin/koha/ill/home", + is_default: true, + is_base: true, + title: $__("Interlibrary loans"), + children: [ + { + path: "/cgi-bin/koha/ill/home", + name: "Home", + component: markRaw(Home), + title: $__("Home"), + icon: "fa fa-home", + }, + { + path: "/cgi-bin/koha/ill", + title: $__("Borrowing"), + icon: "fa fa-arrow-circle-down", + disabled: true, + children: [ + { + path: "/cgi-bin/koha/ill/ill-requests.pl", + title: $__("Requests"), + icon: "fa fa-download", + is_external: true, + is_navigation_item: true, + }, + { + path: "/cgi-bin/koha/ill/ill-requests.pl?method=batch_list", + title: $__("Batches"), + icon: "fa fa-clone", + is_external: true, + is_navigation_item: true, + }, + ], + }, + { + path: "/cgi-bin/koha/ill", + title: $__("Lending"), + icon: "fa fa-arrow-circle-up", + disabled: true, + children: [ + { + path: "/cgi-bin/koha/ill/iso18626_requests", + title: $__("Supplying ILLs"), + icon: "fa fa-upload", + is_end_node: true, + resource: "ILL/SupplyingResource.vue", + children: [ + { + path: "", + name: "SupplyingList", + component: markRaw(ResourceWrapper), + }, + { + path: ":iso18626_request_id", + name: "SupplyingShow", + component: markRaw(ResourceWrapper), + title: "{iso18626_request_id}", + }, + { + path: "progress-request/:iso18626_request_id", + name: "ProgressRequest", + component: markRaw(ProgressRequest), + title: $__( + "Progress request {iso18626_request_id}" + ), + }, + ], + }, + { + path: "/cgi-bin/koha/ill/iso18626_requesting_agencies", + title: $__("Requesting Agencies"), + icon: "fa fa-building-columns", + is_end_node: true, + resource: "ILL/RequestingAgencyResource.vue", + children: [ + { + path: "", + name: "RequestingAgenciesList", + component: markRaw(ResourceWrapper), + }, + { + path: ":iso18626_requesting_agency_id", + name: "RequestingAgenciesShow", + component: markRaw(ResourceWrapper), + title: "{name}", + }, + { + path: "add", + name: "RequestingAgenciesFormAdd", + component: markRaw(ResourceWrapper), + title: $__("Add requesting agency"), + }, + { + path: "edit/:iso18626_requesting_agency_id", + name: "RequestingAgenciesFormAddEdit", + component: markRaw(ResourceWrapper), + title: "{name}", + breadcrumbFormat: ({ + match, + params, + query, + }) => { + match.name = "RequestingAgenciesShow"; + return match; + }, + additionalBreadcrumbs: [ + { + title: $__("Modify requesting agency"), + disabled: true, + }, + ], + }, + ], + }, + ], + }, + ], + }, +]; diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/ill.js b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/ill.js new file mode 100644 index 0000000000..74d2d233bd --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/ill.js @@ -0,0 +1,17 @@ +import { defineStore } from "pinia"; +import { reactive, toRefs } from "vue"; + +export const useILLStore = defineStore("ill", () => { + const store = reactive({ + config: { + settings: { + ILLModule: 1, + ILLPartnerCode: "IL", + }, + }, + }); + + return { + ...toRefs(store), + }; +}); diff --git a/rspack.config.js b/rspack.config.js index df276cfb4d..e94b383ca4 100644 --- a/rspack.config.js +++ b/rspack.config.js @@ -133,6 +133,10 @@ module.exports = [ "./koha-tmpl/intranet-tmpl/prog/js/vue/csp-nonce.js", "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/sip2.ts", ], + ill: [ + "./koha-tmpl/intranet-tmpl/prog/js/vue/csp-nonce.js", + "./koha-tmpl/intranet-tmpl/prog/js/vue/modules/ill.ts", + ], }, output: { filename: "[name].js",