Bug 32983: ERM - Retrieve AVs from an endpoint
Bug 32981 let us retrieve the authorised values from a REST API route, instead of injecting them from the template. Let us that for the ERM module! Test plan: You will notice a "Loading" screen when refreshing the ERM module Then you should not notice any other UI changes. Dropdown list should be populated like before this patch. Some technical notes: I am expecting this to be slower than before, but it feels better to use a REST API route to retrieve the AV Future improvement will be to lazy load the AVs, to speed up the landing page. However it needs more changes, and this gets big enough. I would like to see a follow-up that move the code from ERM/Main.vue to the authorised value store (I've failed at that), but that should certainly be done after the lazy loading is implemented anyway) Signed-off-by: Matt Blenkinsop <matt.blenkinsop@ptfs-europe.com> Signed-off-by: Nick Clemens <nick@bywatersolutions.com> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
parent
611a77ca51
commit
5d8c6a36b8
18 changed files with 149 additions and 89 deletions
|
@ -3,7 +3,6 @@
|
|||
[% USE Asset %]
|
||||
[% USE KohaDates %]
|
||||
[% USE TablesSettings %]
|
||||
[% USE AuthorisedValues %]
|
||||
[% SET footerjs = 1 %]
|
||||
[% PROCESS 'i18n.inc' %]
|
||||
[% INCLUDE 'doc-head-open.inc' %]
|
||||
|
@ -29,23 +28,6 @@
|
|||
|
||||
<script>
|
||||
|
||||
const agreement_statuses = [% To.json(AuthorisedValues.Get('ERM_AGREEMENT_STATUS')) | $raw %];
|
||||
|
||||
const agreement_closure_reasons = [% To.json(AuthorisedValues.Get('ERM_AGREEMENT_CLOSURE_REASON')) | $raw %];
|
||||
const agreement_renewal_priorities = [% To.json(AuthorisedValues.Get('ERM_AGREEMENT_RENEWAL_PRIORITY')) | $raw %];
|
||||
const user_roles = [% To.json(AuthorisedValues.Get('ERM_USER_ROLES')) | $raw %];
|
||||
|
||||
const license_types = [% To.json(AuthorisedValues.Get('ERM_LICENSE_TYPE')) | $raw %];
|
||||
const license_statuses = [% To.json(AuthorisedValues.Get('ERM_LICENSE_STATUS')) | $raw %];
|
||||
|
||||
const agreement_license_statuses = [% To.json(AuthorisedValues.Get('ERM_AGREEMENT_LICENSE_STATUS')) | $raw %];
|
||||
const agreement_license_location = [% To.json(AuthorisedValues.Get('ERM_AGREEMENT_LICENSE_LOCATION')) | $raw %];
|
||||
|
||||
const package_types = [% To.json(AuthorisedValues.Get('ERM_PACKAGE_TYPE')) | $raw %];
|
||||
const package_content_types = [% To.json(AuthorisedValues.Get('ERM_PACKAGE_CONTENT_TYPE')) | $raw %];
|
||||
|
||||
const title_publication_types = [% To.json(AuthorisedValues.Get('ERM_TITLE_PUBLICATION_TYPE')) | $raw %];
|
||||
|
||||
const agreement_table_settings = [% TablesSettings.GetTableSettings( 'erm', 'agreements', 'agreements', 'json' ) | $raw %];
|
||||
const license_table_settings = [% TablesSettings.GetTableSettings( 'erm', 'licenses', 'licenses', 'json' ) | $raw %];
|
||||
const eholdings_packages_table_settings = [% TablesSettings.GetTableSettings( 'erm', 'eholdings', 'packages', 'json' ) | $raw %];
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
<div class="modal_centered" v-if="is_submitting">
|
||||
<div class="spinner dialog alert">{{ $__("Submitting...") }}</div>
|
||||
</div>
|
||||
<div class="modal_centered" v-if="is_loading">
|
||||
<div class="spinner dialog message">{{ $__("Loading...") }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -24,10 +27,17 @@ import { storeToRefs } from "pinia"
|
|||
export default {
|
||||
setup() {
|
||||
const mainStore = inject("mainStore")
|
||||
const { message, error, warning, is_submitting } =
|
||||
const { message, error, warning, is_submitting, is_loading } =
|
||||
storeToRefs(mainStore)
|
||||
const { removeMessages } = mainStore
|
||||
return { message, error, warning, is_submitting, removeMessages }
|
||||
return {
|
||||
message,
|
||||
error,
|
||||
warning,
|
||||
is_submitting,
|
||||
is_loading,
|
||||
removeMessages,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
<v-select
|
||||
:id="`license_status_${counter}`"
|
||||
v-model="agreement_license.status"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_agreement_license_statuses"
|
||||
>
|
||||
<template #search="{ attributes, events }">
|
||||
|
@ -66,8 +66,8 @@
|
|||
<v-select
|
||||
:id="`license_location_${counter}`"
|
||||
v-model="agreement_license.physical_location"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_agreement_license_location"
|
||||
/>
|
||||
</li>
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
<v-select
|
||||
:id="`related_agreement_relationship_${counter}`"
|
||||
v-model="relationship.relationship"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_agreement_relationships"
|
||||
>
|
||||
<template #search="{ attributes, events }">
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
<v-select
|
||||
id="agreement_status"
|
||||
v-model="agreement.status"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_agreement_statuses"
|
||||
@option:selected="onStatusChanged"
|
||||
:required="!agreement.status"
|
||||
|
@ -81,8 +81,8 @@
|
|||
<v-select
|
||||
id="agreement_closure_reason"
|
||||
v-model="agreement.closure_reason"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_agreement_closure_reasons"
|
||||
:disabled="
|
||||
agreement.status == 'closed'
|
||||
|
@ -125,8 +125,8 @@
|
|||
<v-select
|
||||
id="agreement_renewal_priority"
|
||||
v-model="agreement.renewal_priority"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_agreement_renewal_priorities"
|
||||
/>
|
||||
</li>
|
||||
|
@ -391,7 +391,7 @@ export default {
|
|||
}
|
||||
},
|
||||
onStatusChanged(e) {
|
||||
if (e.authorised_value != "closed") {
|
||||
if (e.value != "closed") {
|
||||
this.agreement.closure_reason = ""
|
||||
}
|
||||
},
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
<option value="">{{ $__("All") }}</option>
|
||||
<option
|
||||
v-for="type in av_title_publication_types"
|
||||
:key="type.authorised_values"
|
||||
:value="type.authorised_value"
|
||||
:key="type.value"
|
||||
:value="type.value"
|
||||
>
|
||||
{{ type.lib }}
|
||||
{{ type.description }}
|
||||
</option>
|
||||
</select>
|
||||
</li>
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
<option value="">{{ $__("All") }}</option>
|
||||
<option
|
||||
v-for="type in av_title_publication_types"
|
||||
:key="type.authorised_values"
|
||||
:value="type.authorised_value"
|
||||
:key="type.value"
|
||||
:value="type.value"
|
||||
>
|
||||
{{ type.lib }}
|
||||
{{ type.description }}
|
||||
</option>
|
||||
</select>
|
||||
{{ $__("Selection status") }}:
|
||||
|
@ -194,8 +194,8 @@ export default {
|
|||
}, {})
|
||||
window["av_title_publication_types"] =
|
||||
this.av_title_publication_types.map(e => {
|
||||
e["_id"] = e["authorised_value"]
|
||||
e["_str"] = e["lib"]
|
||||
e["_id"] = e["value"]
|
||||
e["_str"] = e["description"]
|
||||
return e
|
||||
})
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
<v-select
|
||||
id="package_type"
|
||||
v-model="erm_package.package_type"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_package_types"
|
||||
/>
|
||||
</li>
|
||||
|
@ -50,8 +50,8 @@
|
|||
<v-select
|
||||
id="package_content_type"
|
||||
v-model="erm_package.content_type"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_package_content_types"
|
||||
/>
|
||||
</li>
|
||||
|
|
|
@ -232,8 +232,8 @@
|
|||
<v-select
|
||||
id="title_publication_type"
|
||||
v-model="title.publication_type"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_title_publication_types"
|
||||
/>
|
||||
</li>
|
||||
|
|
|
@ -59,8 +59,8 @@
|
|||
<v-select
|
||||
id="license_type"
|
||||
v-model="license.type"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_license_types"
|
||||
>
|
||||
<template #search="{ attributes, events }">
|
||||
|
@ -83,9 +83,9 @@
|
|||
<v-select
|
||||
id="license_status"
|
||||
v-model="license.status"
|
||||
:reduce="av => av.authorised_value"
|
||||
:reduce="av => av.value"
|
||||
:options="av_license_statuses"
|
||||
label="lib"
|
||||
label="description"
|
||||
>
|
||||
<template #search="{ attributes, events }">
|
||||
<input
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<div v-if="ERMModule">
|
||||
<div v-if="is_loading">
|
||||
<Dialog />
|
||||
</div>
|
||||
<div v-else-if="ERMModule">
|
||||
<Breadcrumb />
|
||||
<div class="main container-fluid">
|
||||
<div class="row">
|
||||
|
@ -124,28 +127,27 @@ import Breadcrumb from "../../components/Breadcrumb.vue"
|
|||
import Dialog from "../../components/Dialog.vue"
|
||||
import { APIClient } from "../../fetch/api-client.js"
|
||||
import "vue-select/dist/vue-select.css"
|
||||
import { storeToRefs } from "pinia"
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const AVStore = inject("AVStore")
|
||||
AVStore.av_agreement_statuses = agreement_statuses
|
||||
AVStore.av_agreement_closure_reasons = agreement_closure_reasons
|
||||
AVStore.av_agreement_renewal_priorities = agreement_renewal_priorities
|
||||
AVStore.av_user_roles = user_roles
|
||||
AVStore.av_license_types = license_types
|
||||
AVStore.av_license_statuses = license_statuses
|
||||
AVStore.av_agreement_license_statuses = agreement_license_statuses
|
||||
AVStore.av_agreement_license_location = agreement_license_location
|
||||
AVStore.av_package_types = package_types
|
||||
AVStore.av_package_content_types = package_content_types
|
||||
AVStore.av_title_publication_types = title_publication_types
|
||||
|
||||
const vendorStore = inject("vendorStore")
|
||||
|
||||
const AVStore = inject("AVStore")
|
||||
|
||||
const mainStore = inject("mainStore")
|
||||
|
||||
// Note that we cannot use loading and loaded from messages
|
||||
// Pinia is not initiated yet there
|
||||
const { is_loading } = storeToRefs(mainStore)
|
||||
|
||||
return {
|
||||
vendorStore,
|
||||
AVStore,
|
||||
mainStore,
|
||||
erm_providers,
|
||||
ERMModule,
|
||||
is_loading,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -154,14 +156,40 @@ export default {
|
|||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
const client = APIClient.acquisition
|
||||
client.vendors.getAll().then(
|
||||
this.mainStore.is_loading = true
|
||||
|
||||
const acq_client = APIClient.acquisition
|
||||
acq_client.vendors.getAll().then(
|
||||
vendors => {
|
||||
this.vendorStore.vendors = vendors
|
||||
this.initialized = true
|
||||
},
|
||||
error => {}
|
||||
)
|
||||
|
||||
const av_client = APIClient.authorised_values
|
||||
const authorised_values = {
|
||||
av_agreement_statuses: "ERM_AGREEMENT_STATUS",
|
||||
av_agreement_closure_reasons: "ERM_AGREEMENT_CLOSURE_REASON",
|
||||
av_agreement_renewal_priorities: "ERM_AGREEMENT_RENEWAL_PRIORITY",
|
||||
av_user_roles: "ERM_USER_ROLES",
|
||||
av_license_types: "ERM_LICENSE_TYPE",
|
||||
av_license_statuses: "ERM_LICENSE_STATUS",
|
||||
av_agreement_license_statuses: "ERM_AGREEMENT_LICENSE_STATUS",
|
||||
av_agreement_license_location: "ERM_AGREEMENT_LICENSE_LOCATION",
|
||||
av_package_types: "ERM_PACKAGE_TYPE",
|
||||
av_package_content_types: "ERM_PACKAGE_CONTENT_TYPE",
|
||||
av_title_publication_types: "ERM_TITLE_PUBLICATION_TYPE",
|
||||
}
|
||||
let promises = []
|
||||
Object.entries(authorised_values).forEach(([av_var, av_cat]) => {
|
||||
promises.push(
|
||||
av_client.values.getAll(av_cat).then(av => {
|
||||
this.AVStore[av_var] = av
|
||||
})
|
||||
)
|
||||
})
|
||||
Promise.all(promises).then(() => (this.mainStore.is_loading = false))
|
||||
},
|
||||
components: {
|
||||
Breadcrumb,
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
<v-select
|
||||
:id="`user_role_${counter}`"
|
||||
v-model="user_role.role"
|
||||
label="lib"
|
||||
:reduce="av => av.authorised_value"
|
||||
label="description"
|
||||
:reduce="av => av.value"
|
||||
:options="av_user_roles"
|
||||
>
|
||||
<template #search="{ attributes, events }">
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import ERMAPIClient from "./erm-api-client";
|
||||
import PatronAPIClient from "./patron-api-client";
|
||||
import AcquisitionAPIClient from "./acquisition-api-client";
|
||||
import AVAPIClient from "./authorised-values";
|
||||
|
||||
export const APIClient = {
|
||||
erm: new ERMAPIClient(),
|
||||
patron: new PatronAPIClient(),
|
||||
acquisition: new AcquisitionAPIClient(),
|
||||
};
|
||||
authorised_values: new AVAPIClient(),
|
||||
};
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import HttpClient from "./http-client";
|
||||
|
||||
export class AVAPIClient extends HttpClient {
|
||||
constructor() {
|
||||
super({
|
||||
baseURL: "/api/v1/authorised_value_categories/",
|
||||
});
|
||||
}
|
||||
|
||||
get values() {
|
||||
return {
|
||||
getAll: (category_name, query) =>
|
||||
this.get({
|
||||
endpoint: category_name + "/values?" + (query || "_per_page=-1"),
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default AVAPIClient;
|
|
@ -31,4 +31,14 @@ export const submitted = function () {
|
|||
const mainStore = useMainStore();
|
||||
const { submitted } = mainStore;
|
||||
submitted();
|
||||
};
|
||||
export const loading = function () {
|
||||
const mainStore = useMainStore();
|
||||
const { loading } = mainStore;
|
||||
loading();
|
||||
};
|
||||
export const loaded = function () {
|
||||
const mainStore = useMainStore();
|
||||
const { loaded } = mainStore;
|
||||
loaded();
|
||||
};
|
|
@ -27,7 +27,7 @@ const router = createRouter({
|
|||
|
||||
import { useMainStore } from "../stores/main";
|
||||
import { useVendorStore } from "../stores/vendors";
|
||||
import { useAVStore } from "../stores/authorised_values";
|
||||
import { useAVStore } from "../stores/authorised-values";
|
||||
|
||||
const pinia = createPinia();
|
||||
|
||||
|
@ -52,7 +52,8 @@ app.config.unwrapInjectedRef = true;
|
|||
app.provide("vendorStore", useVendorStore(pinia));
|
||||
const mainStore = useMainStore(pinia);
|
||||
app.provide("mainStore", mainStore);
|
||||
app.provide("AVStore", useAVStore(pinia));
|
||||
const AVStore = useAVStore(pinia);
|
||||
app.provide("AVStore", AVStore);
|
||||
|
||||
app.mount("#erm");
|
||||
|
||||
|
|
|
@ -11,27 +11,27 @@ export const useAVStore = defineStore("authorised_values", {
|
|||
av_agreement_license_statuses: [],
|
||||
av_agreement_license_location: [],
|
||||
av_agreement_relationships: [
|
||||
{ authorised_value: "supersedes", lib: __("supersedes") },
|
||||
{ authorised_value: "is-superseded-by", lib: __("is superseded by") },
|
||||
{ value: "supersedes", description: __("supersedes") },
|
||||
{ value: "is-superseded-by", description: __("is superseded by") },
|
||||
{
|
||||
authorised_value: "provides_post-cancellation_access_for",
|
||||
lib: __("provides post-cancellation access for"),
|
||||
value: "provides_post-cancellation_access_for",
|
||||
description: __("provides post-cancellation access for"),
|
||||
},
|
||||
{
|
||||
authorised_value: "has-post-cancellation-access-in",
|
||||
lib: __("has post-cancellation access in"),
|
||||
value: "has-post-cancellation-access-in",
|
||||
description: __("has post-cancellation access in"),
|
||||
},
|
||||
{
|
||||
authorised_value: "tracks_demand-driven_acquisitions_for",
|
||||
lib: __("tracks demand-driven acquisitions for"),
|
||||
value: "tracks_demand-driven_acquisitions_for",
|
||||
description: __("tracks demand-driven acquisitions for"),
|
||||
},
|
||||
{
|
||||
authorised_value: "has-demand-driven-acquisitions-in",
|
||||
lib: __("has demand-driven acquisitions in"),
|
||||
value: "has-demand-driven-acquisitions-in",
|
||||
description: __("has demand-driven acquisitions in"),
|
||||
},
|
||||
{ authorised_value: "has_backfile_in", lib: __("has backfile in") },
|
||||
{ authorised_value: "has_frontfile_in", lib: __("has frontfile in") },
|
||||
{ authorised_value: "related_to", lib: __("related to") },
|
||||
{ value: "has_backfile_in", description: __("has backfile in") },
|
||||
{ value: "has_frontfile_in", description: __("has frontfile in") },
|
||||
{ value: "related_to", description: __("related to") },
|
||||
],
|
||||
av_package_types: [],
|
||||
av_package_content_types: [],
|
||||
|
@ -47,13 +47,13 @@ export const useAVStore = defineStore("authorised_values", {
|
|||
);
|
||||
return;
|
||||
}
|
||||
let o = this[arr_name].find((e) => e.authorised_value == av);
|
||||
return o ? o.lib : av;
|
||||
let o = this[arr_name].find((e) => e.value == av);
|
||||
return o ? o.description : av;
|
||||
},
|
||||
map_av_dt_filter(arr_name) {
|
||||
return this[arr_name].map((e) => {
|
||||
e["_id"] = e["authorised_value"];
|
||||
e["_str"] = e["lib"];
|
||||
e["_id"] = e["value"];
|
||||
e["_str"] = e["description"];
|
||||
return e;
|
||||
});
|
||||
},
|
|
@ -9,6 +9,7 @@ export const useMainStore = defineStore("main", {
|
|||
previousError: null,
|
||||
displayed_already: false,
|
||||
is_submitting: false,
|
||||
is_loading: false,
|
||||
}),
|
||||
actions: {
|
||||
setMessage(message) {
|
||||
|
@ -41,5 +42,11 @@ export const useMainStore = defineStore("main", {
|
|||
submitted(){
|
||||
this.is_submitting = false;
|
||||
},
|
||||
loading(){
|
||||
this.is_loading = true;
|
||||
},
|
||||
loaded(){
|
||||
this.is_loading = false;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue