Bug 33169: Build breadcrumbs and left-hand side menu from routes definition
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@ptfs-europe.com> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
parent
a40c512bf0
commit
13fbc155d2
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
|
||||
<ol>
|
||||
<template v-for="(item, idx) in breadcrumbs" v-bind:key="idx">
|
||||
<NavigationItem
|
||||
v-if="idx < breadcrumbs.length - 1"
|
||||
:item="item"
|
||||
:params="params"
|
||||
></NavigationItem>
|
||||
<NavigationItem
|
||||
v-else
|
||||
:item="{
|
||||
...item,
|
||||
disabled: true,
|
||||
path: undefined,
|
||||
href: undefined,
|
||||
}"
|
||||
:params="params"
|
||||
></NavigationItem>
|
||||
</template>
|
||||
</ol>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { inject } from "vue"
|
||||
import { storeToRefs } from "pinia"
|
||||
import NavigationItem from "./NavigationItem.vue"
|
||||
export default {
|
||||
name: "Breadcrumbs",
|
||||
setup: () => {
|
||||
const navigationStore = inject("navigationStore")
|
||||
const { breadcrumbs } = storeToRefs(navigationStore)
|
||||
const { params } = navigationStore
|
||||
return {
|
||||
breadcrumbs,
|
||||
params,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
NavigationItem,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#breadcrumbs .disabled {
|
||||
padding: 0.6em 0.3em;
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div v-if="initialized && sysprefs.ERMModule == 1">
|
||||
<div id="sub-header">
|
||||
<Breadcrumb />
|
||||
<Breadcrumbs />
|
||||
<Help />
|
||||
</div>
|
||||
<div class="main container-fluid">
|
||||
|
|
@ -14,100 +14,10 @@
|
|||
</div>
|
||||
|
||||
<div class="col-sm-2 col-sm-pull-10">
|
||||
<aside>
|
||||
<div id="navmenu">
|
||||
<div id="navmenulist">
|
||||
<h5>{{ $__("E-resource management") }}</h5>
|
||||
<ul>
|
||||
<li>
|
||||
<router-link
|
||||
:to="{ name: 'AgreementsList' }"
|
||||
>
|
||||
<i class="fa fa-check-circle"></i>
|
||||
{{ $__("Agreements") }}</router-link
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<router-link
|
||||
:to="{ name: 'LicensesList' }"
|
||||
>
|
||||
<i class="fa fa-gavel"></i>
|
||||
{{ $__("Licenses") }}</router-link
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<router-link
|
||||
to="/cgi-bin/koha/erm/eholdings"
|
||||
class="disabled"
|
||||
>
|
||||
<i class="fa fa-crosshairs"></i>
|
||||
{{ $__("eHoldings") }}
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<ul>
|
||||
<li
|
||||
v-for="provider in sysprefs.ERMProviders"
|
||||
:key="provider"
|
||||
>
|
||||
<router-link
|
||||
v-if="provider == 'local'"
|
||||
:to="`/cgi-bin/koha/erm/eholdings/local`"
|
||||
class="disabled"
|
||||
>
|
||||
<i
|
||||
class="fa-solid fa-location-dot"
|
||||
></i>
|
||||
{{
|
||||
$__("Local")
|
||||
}}</router-link
|
||||
>
|
||||
<router-link
|
||||
v-else-if="
|
||||
provider == 'ebsco'
|
||||
"
|
||||
:to="`/cgi-bin/koha/erm/eholdings/ebsco`"
|
||||
class="disabled"
|
||||
>
|
||||
<i class="fa fa-globe"></i>
|
||||
{{
|
||||
$__("EBSCO")
|
||||
}}</router-link
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
<router-link
|
||||
:to="`/cgi-bin/koha/erm/eholdings/${provider}/packages`"
|
||||
>
|
||||
<i
|
||||
class="fa fa-archive"
|
||||
></i>
|
||||
{{
|
||||
$__("Packages")
|
||||
}}</router-link
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<router-link
|
||||
:to="`/cgi-bin/koha/erm/eholdings/${provider}/titles`"
|
||||
>
|
||||
<i
|
||||
class="fa-solid fa-arrow-down-a-z"
|
||||
></i>
|
||||
{{
|
||||
$__("Titles")
|
||||
}}</router-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<LeftMenu
|
||||
:title="$__('E-resource management')"
|
||||
:condition="filterProviders"
|
||||
></LeftMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -119,9 +29,10 @@
|
|||
|
||||
<script>
|
||||
import { inject } from "vue"
|
||||
import Breadcrumb from "../../components/Breadcrumb.vue"
|
||||
import Help from "../../components/Help.vue"
|
||||
import Dialog from "../../components/Dialog.vue"
|
||||
import Breadcrumbs from "../Breadcrumbs.vue"
|
||||
import Help from "../Help.vue"
|
||||
import LeftMenu from "../LeftMenu.vue"
|
||||
import Dialog from "../Dialog.vue"
|
||||
import { APIClient } from "../../fetch/api-client.js"
|
||||
import "vue-select/dist/vue-select.css"
|
||||
import { storeToRefs } from "pinia"
|
||||
|
|
@ -248,10 +159,25 @@ export default {
|
|||
this.initialized = true
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
async filterProviders(navigationTree) {
|
||||
const eHoldings = navigationTree.find(
|
||||
element => element.path === "/cgi-bin/koha/erm/eholdings"
|
||||
)
|
||||
const providers = this.sysprefs.ERMProviders
|
||||
eHoldings.children = eHoldings.children.filter(element =>
|
||||
providers
|
||||
.map(provider => `${eHoldings.path}/${provider}`)
|
||||
.includes(element.path)
|
||||
)
|
||||
return navigationTree
|
||||
},
|
||||
},
|
||||
components: {
|
||||
Breadcrumb,
|
||||
Breadcrumbs,
|
||||
Dialog,
|
||||
Help,
|
||||
LeftMenu,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<aside>
|
||||
<div id="navmenu">
|
||||
<div id="navmenulist">
|
||||
<h5>{{ $__(title) }}</h5>
|
||||
<ul>
|
||||
<NavigationItem
|
||||
v-for="(item, key) in navigationTree"
|
||||
v-bind:key="key"
|
||||
:item="item"
|
||||
></NavigationItem>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { inject } from "vue"
|
||||
import NavigationItem from "./NavigationItem.vue"
|
||||
export default {
|
||||
name: "LeftMenu",
|
||||
data() {
|
||||
return {
|
||||
navigationTree: this.leftNavigation,
|
||||
}
|
||||
},
|
||||
setup: () => {
|
||||
const navigationStore = inject("navigationStore")
|
||||
const { leftNavigation } = navigationStore
|
||||
return {
|
||||
leftNavigation,
|
||||
}
|
||||
},
|
||||
async beforeMount() {
|
||||
if (this.condition)
|
||||
this.navigationTree = await this.condition(this.navigationTree)
|
||||
},
|
||||
props: {
|
||||
title: String,
|
||||
condition: Function,
|
||||
},
|
||||
components: {
|
||||
NavigationItem,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#navmenulist a.router-link-active {
|
||||
font-weight: 700;
|
||||
}
|
||||
#menu ul ul,
|
||||
#navmenulist ul ul {
|
||||
padding-left: 2em;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
#navmenulist ul li a.disabled {
|
||||
color: #666;
|
||||
pointer-events: none;
|
||||
font-weight: 700;
|
||||
}
|
||||
#navmenulist ul li a.disabled.router-link-active {
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<li>
|
||||
<span>
|
||||
<router-link
|
||||
v-if="item.name"
|
||||
:to="{ name: item.name, params }"
|
||||
:class="{ disabled: item.disabled }"
|
||||
>
|
||||
<template v-if="item.icon">
|
||||
<i :class="`fa ${item.icon}`"></i>
|
||||
</template>
|
||||
<span v-if="item.title">{{ $__(item.title) }}</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
v-else-if="item.path"
|
||||
:to="item.path"
|
||||
:class="{ disabled: item.disabled }"
|
||||
>
|
||||
<template v-if="item.icon">
|
||||
<i :class="`fa ${item.icon}`"></i>
|
||||
</template>
|
||||
<span v-if="item.title">{{ $__(item.title) }}</span>
|
||||
</router-link>
|
||||
<a
|
||||
v-else-if="item.href"
|
||||
:href="item.href"
|
||||
:class="{ disabled: item.disabled }"
|
||||
>
|
||||
<template v-if="item.icon">
|
||||
<i :class="`fa ${item.icon}`"></i>
|
||||
</template>
|
||||
<span v-if="item.title">{{ $__(item.title) }}</span>
|
||||
</a>
|
||||
<span v-else :class="{ disabled: item.disabled }">
|
||||
<template v-if="item.icon">
|
||||
<i :class="`fa ${item.icon}`"></i>
|
||||
</template>
|
||||
<span class="item-last" v-if="item.title">{{
|
||||
$__(item.title)
|
||||
}}</span>
|
||||
</span>
|
||||
</span>
|
||||
<ul v-if="item.children && item.children.length">
|
||||
<NavigationItem
|
||||
v-for="(item, key) in item.children"
|
||||
:item="item"
|
||||
></NavigationItem>
|
||||
</ul>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "NavigationItem",
|
||||
props: {
|
||||
item: Object,
|
||||
params: Object,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
span.item-last {
|
||||
padding: 7px 3px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
export const $__ = (key) => {
|
||||
return window["__"](key);
|
||||
};
|
||||
|
||||
export default {
|
||||
install: (app, options) => {
|
||||
app.config.globalProperties.$__ = $__
|
||||
},
|
||||
};
|
||||
|
|
@ -17,28 +17,27 @@ library.add(faPlus, faMinus, faPencil, faTrash, faSpinner);
|
|||
|
||||
import App from "../components/ERM/Main.vue";
|
||||
|
||||
import { routes } from "../routes/erm";
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
linkActiveClass: "current",
|
||||
routes,
|
||||
});
|
||||
import { routes as routesDef } from "../routes/erm";
|
||||
|
||||
import { useMainStore } from "../stores/main";
|
||||
import { useVendorStore } from "../stores/vendors";
|
||||
import { useAVStore } from "../stores/authorised-values";
|
||||
import { useERMStore } from "../stores/erm";
|
||||
import { useNavigationStore } from "../stores/navigation";
|
||||
import i18n from "../i18n";
|
||||
|
||||
const pinia = createPinia();
|
||||
|
||||
const i18n = {
|
||||
install: (app, options) => {
|
||||
app.config.globalProperties.$__ = key => {
|
||||
return window["__"](key);
|
||||
};
|
||||
},
|
||||
};
|
||||
const mainStore = useMainStore(pinia);
|
||||
const AVStore = useAVStore(pinia);
|
||||
const navigationStore = useNavigationStore(pinia);
|
||||
const routes = navigationStore.setRoutes(routesDef);
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
linkExactActiveClass: "current",
|
||||
routes,
|
||||
});
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
|
|
@ -51,10 +50,9 @@ const rootComponent = app
|
|||
|
||||
app.config.unwrapInjectedRef = true;
|
||||
app.provide("vendorStore", useVendorStore(pinia));
|
||||
const mainStore = useMainStore(pinia);
|
||||
app.provide("mainStore", mainStore);
|
||||
const AVStore = useAVStore(pinia);
|
||||
app.provide("AVStore", AVStore);
|
||||
app.provide("navigationStore", navigationStore);
|
||||
const ERMStore = useERMStore(pinia);
|
||||
app.provide("ERMStore", ERMStore);
|
||||
|
||||
|
|
@ -62,6 +60,7 @@ app.mount("#erm");
|
|||
|
||||
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
|
||||
});
|
||||
router.afterEach((to, from) => {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { markRaw } from "vue";
|
||||
|
||||
import Home from "../components/ERM/Home.vue";
|
||||
import AgreementsList from "../components/ERM/AgreementsList.vue";
|
||||
import AgreementsShow from "../components/ERM/AgreementsShow.vue";
|
||||
|
|
@ -19,100 +21,12 @@ import LicensesList from "../components/ERM/LicensesList.vue";
|
|||
import LicensesShow from "../components/ERM/LicensesShow.vue";
|
||||
import LicensesFormAdd from "../components/ERM/LicensesFormAdd.vue";
|
||||
|
||||
const breadcrumbs = {
|
||||
home: {
|
||||
text: "Home", // $t("Home")
|
||||
path: "/cgi-bin/koha/mainpage.pl",
|
||||
},
|
||||
erm_home: {
|
||||
text: "E-resource management", // $t("E-resource management")
|
||||
path: "/cgi-bin/koha/erm/erm.pl",
|
||||
},
|
||||
agreements: {
|
||||
text: "Agreements", // $t("Agreements")
|
||||
path: "/cgi-bin/koha/erm/agreements",
|
||||
},
|
||||
eholdings: {
|
||||
home: {
|
||||
text: "eHoldings", // $t("eHoldings")
|
||||
},
|
||||
local: {
|
||||
home: {
|
||||
text: "Local", // $t("Local")
|
||||
},
|
||||
titles: {
|
||||
text: "Titles", // $t("Titles")
|
||||
path: "/cgi-bin/koha/erm/eholdings/local/titles",
|
||||
},
|
||||
packages: {
|
||||
text: "Packages", // $t("Packages")
|
||||
path: "/cgi-bin/koha/erm/eholdings/local/packages",
|
||||
},
|
||||
},
|
||||
ebsco: {
|
||||
home: {
|
||||
text: "EBSCO", // $t("EBSCO")
|
||||
},
|
||||
titles: {
|
||||
text: "Titles", // $t("Titles")
|
||||
path: "/cgi-bin/koha/erm/eholdings/ebsco/titles",
|
||||
},
|
||||
packages: {
|
||||
text: "Packages", // $t("Packages")
|
||||
path: "/cgi-bin/koha/erm/eholdings/ebsco/packages",
|
||||
},
|
||||
},
|
||||
},
|
||||
licenses: {
|
||||
text: "Licenses", // $t("Licenses")
|
||||
path: "/cgi-bin/koha/erm/licenses",
|
||||
},
|
||||
};
|
||||
const breadcrumb_paths = {
|
||||
agreements: [
|
||||
breadcrumbs.home,
|
||||
breadcrumbs.erm_home,
|
||||
breadcrumbs.agreements,
|
||||
],
|
||||
eholdings: [
|
||||
breadcrumbs.home,
|
||||
breadcrumbs.erm_home,
|
||||
breadcrumbs.eholdings.home,
|
||||
],
|
||||
eholdings_local: [
|
||||
breadcrumbs.home,
|
||||
breadcrumbs.erm_home,
|
||||
breadcrumbs.eholdings.home,
|
||||
breadcrumbs.eholdings.local.home,
|
||||
],
|
||||
eholdings_ebsco: [
|
||||
breadcrumbs.home,
|
||||
breadcrumbs.erm_home,
|
||||
breadcrumbs.eholdings.home,
|
||||
breadcrumbs.eholdings.ebsco.home,
|
||||
],
|
||||
licenses: [breadcrumbs.home, breadcrumbs.erm_home, breadcrumbs.licenses],
|
||||
};
|
||||
|
||||
function build_breadcrumb(parent_breadcrumb, current) {
|
||||
let breadcrumb = parent_breadcrumb.flat(Infinity);
|
||||
if (current) {
|
||||
breadcrumb.push({
|
||||
text: current,
|
||||
});
|
||||
}
|
||||
return breadcrumb;
|
||||
}
|
||||
import { $__ } from "../i18n";
|
||||
|
||||
export const routes = [
|
||||
{
|
||||
path: "/cgi-bin/koha/mainpage.pl",
|
||||
beforeEnter(to, from, next) {
|
||||
window.location.href = "/cgi-bin/koha/mainpage.pl";
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/cgi-bin/koha/admin/background_jobs/:id",
|
||||
is_base: true,
|
||||
beforeEnter(to, from, next) {
|
||||
window.location.href =
|
||||
"/cgi-bin/koha/admin/background_jobs.pl?op=view&id=" +
|
||||
|
|
@ -121,388 +35,221 @@ export const routes = [
|
|||
},
|
||||
{
|
||||
path: "/cgi-bin/koha/erm/erm.pl",
|
||||
name: "Home",
|
||||
component: Home,
|
||||
meta: {
|
||||
breadcrumb: () => [breadcrumbs.home, breadcrumbs.erm_home],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/cgi-bin/koha/erm/agreements",
|
||||
is_default: true,
|
||||
is_base: true,
|
||||
title: $__('E-resource management'),
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "AgreementsList",
|
||||
component: AgreementsList,
|
||||
meta: {
|
||||
breadcrumb: () => breadcrumb_paths.agreements,
|
||||
},
|
||||
name: "Home",
|
||||
component: markRaw(Home),
|
||||
is_navigation_item: false,
|
||||
},
|
||||
{
|
||||
path: ":agreement_id",
|
||||
name: "AgreementsShow",
|
||||
component: AgreementsShow,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
breadcrumb_paths.agreements,
|
||||
"Show agreement" // $t("Show agreement")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "add",
|
||||
name: "AgreementsFormAdd",
|
||||
component: AgreementsFormAdd,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
breadcrumb_paths.agreements,
|
||||
"Add agreement" // $t("Add agreement")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "edit/:agreement_id",
|
||||
name: "AgreementsFormAddEdit",
|
||||
component: AgreementsFormAdd,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
breadcrumb_paths.agreements,
|
||||
"Edit agreement" // $t("Edit agreement")
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/cgi-bin/koha/erm/eholdings",
|
||||
meta: {
|
||||
breadcrumb: () => breadcrumb_paths.eholdings,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
meta: {
|
||||
breadcrumb: () => breadcrumb_paths.eholdings,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "local",
|
||||
path: "/cgi-bin/koha/erm/agreements",
|
||||
title: $__('Agreements'),
|
||||
icon: 'fa-check-circle-o',
|
||||
is_end_node: true,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
meta: {
|
||||
breadcrumb: () => breadcrumb_paths.eholdings_local,
|
||||
},
|
||||
name: "AgreementsList",
|
||||
component: markRaw(AgreementsList),
|
||||
},
|
||||
{
|
||||
path: "packages",
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "EHoldingsLocalPackagesList",
|
||||
component: EHoldingsLocalPackagesList,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb([
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local
|
||||
.packages,
|
||||
]),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: ":package_id",
|
||||
name: "EHoldingsLocalPackagesShow",
|
||||
component: EHoldingsLocalPackagesShow,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local
|
||||
.packages,
|
||||
],
|
||||
"Show package" // $t("Show package")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "add",
|
||||
name: "EHoldingsLocalPackagesFormAdd",
|
||||
component: EHoldingsLocalPackagesFormAdd,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local
|
||||
.packages,
|
||||
],
|
||||
"Add package" // $t("Add package")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "edit/:package_id",
|
||||
name: "EHoldingsLocalPackagesFormAddEdit",
|
||||
component: EHoldingsLocalPackagesFormAdd,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local
|
||||
.packages,
|
||||
],
|
||||
"Edit package" // $t("Edit package")
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
path: ":agreement_id",
|
||||
name: "AgreementsShow",
|
||||
component: markRaw(AgreementsShow),
|
||||
title: $__('Show agreement'),
|
||||
},
|
||||
{
|
||||
path: "titles",
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "EHoldingsLocalTitlesList",
|
||||
component: EHoldingsLocalTitlesList,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb([
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local.titles,
|
||||
]),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: ":title_id",
|
||||
name: "EHoldingsLocalTitlesShow",
|
||||
component: EHoldingsLocalTitlesShow,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local
|
||||
.titles,
|
||||
],
|
||||
"Show title" // $t("Show title")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "add",
|
||||
name: "EHoldingsLocalTitlesFormAdd",
|
||||
component: EHoldingsLocalTitlesFormAdd,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local
|
||||
.titles,
|
||||
],
|
||||
"Add title" // $t("Add title")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "edit/:title_id",
|
||||
name: "EHoldingsLocalTitlesFormAddEdit",
|
||||
component: EHoldingsLocalTitlesFormAdd,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local
|
||||
.titles,
|
||||
],
|
||||
"Edit title" // $t("Edit title")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "import",
|
||||
name: "EHoldingsLocalTitlesFormImport",
|
||||
component: EHoldingsLocalTitlesFormImport,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local
|
||||
.titles,
|
||||
],
|
||||
"Import from a list" // $t("Import from a list")
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
path: "add",
|
||||
name: "AgreementsFormAdd",
|
||||
component: markRaw(AgreementsFormAdd),
|
||||
title: $__('Add agreement'),
|
||||
},
|
||||
{
|
||||
path: "resources/:resource_id",
|
||||
name: "EHoldingsLocalResourcesShow",
|
||||
component: EHoldingsLocalResourcesShow,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_local,
|
||||
breadcrumbs.eholdings.local.titles,
|
||||
],
|
||||
"Resource" // $t("Resource")
|
||||
),
|
||||
},
|
||||
path: "edit/:agreement_id",
|
||||
name: "AgreementsFormAddEdit",
|
||||
component: markRaw(AgreementsFormAdd),
|
||||
title: $__('Edit agreement'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "ebsco",
|
||||
path: "/cgi-bin/koha/erm/licenses",
|
||||
title: $__('Licenses'),
|
||||
icon: "fa-gavel",
|
||||
is_end_node: true,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
meta: {
|
||||
breadcrumb: () => breadcrumb_paths.eholdings_ebsco,
|
||||
},
|
||||
name: "LicensesList",
|
||||
component: markRaw(LicensesList),
|
||||
},
|
||||
{
|
||||
path: "packages",
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "EHoldingsEBSCOPackagesList",
|
||||
component: EHoldingsEBSCOPackagesList,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb([
|
||||
breadcrumb_paths.eholdings_ebsco,
|
||||
breadcrumbs.eholdings.ebsco
|
||||
.packages,
|
||||
]),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: ":package_id",
|
||||
name: "EHoldingsEBSCOPackagesShow",
|
||||
component: EHoldingsEBSCOPackagesShow,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_ebsco,
|
||||
breadcrumbs.eholdings.ebsco
|
||||
.packages,
|
||||
],
|
||||
"Show package" // $t("Show package")
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
path: ":license_id",
|
||||
name: "LicensesShow",
|
||||
component: markRaw(LicensesShow),
|
||||
title: $__('Show license'),
|
||||
},
|
||||
{
|
||||
path: "titles",
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "EHoldingsEBSCOTitlesList",
|
||||
component: EHoldingsEBSCOTitlesList,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb([
|
||||
breadcrumb_paths.eholdings_ebsco,
|
||||
breadcrumbs.eholdings.ebsco.titles,
|
||||
]),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: ":title_id",
|
||||
name: "EHoldingsEBSCOTitlesShow",
|
||||
component: EHoldingsEBSCOTitlesShow,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_ebsco,
|
||||
breadcrumbs.eholdings.ebsco
|
||||
.titles,
|
||||
],
|
||||
"Show title" // $t("Show title")
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
path: "add",
|
||||
name: "LicensesFormAdd",
|
||||
component: markRaw(LicensesFormAdd),
|
||||
title: $__('Add license'),
|
||||
},
|
||||
{
|
||||
path: "resources/:resource_id",
|
||||
name: "EHoldingsEBSCOResourcesShow",
|
||||
component: EHoldingsEBSCOResourcesShow,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
[
|
||||
breadcrumb_paths.eholdings_ebsco,
|
||||
breadcrumbs.eholdings.ebsco.titles,
|
||||
],
|
||||
"Resource" // $t("Resource")
|
||||
),
|
||||
},
|
||||
path: "edit/:license_id",
|
||||
name: "LicensesFormAddEdit",
|
||||
component: markRaw(LicensesFormAdd),
|
||||
title: $__('Edit license'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/cgi-bin/koha/erm/licenses",
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "LicensesList",
|
||||
component: LicensesList,
|
||||
meta: {
|
||||
breadcrumb: () => breadcrumb_paths.licenses,
|
||||
},
|
||||
path: "/cgi-bin/koha/erm/eholdings",
|
||||
title: $__('eHoldings'),
|
||||
icon: 'fa-crosshairs',
|
||||
disabled: true,
|
||||
children: [
|
||||
{
|
||||
path: "local",
|
||||
title: $__('Local'),
|
||||
icon: "fa-map-marker",
|
||||
disabled: true,
|
||||
children: [
|
||||
{
|
||||
path: "packages",
|
||||
title: $__('Packages'),
|
||||
icon: "fa-archive",
|
||||
is_end_node: true,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "EHoldingsLocalPackagesList",
|
||||
component: markRaw(EHoldingsLocalPackagesList),
|
||||
},
|
||||
{
|
||||
path: ":package_id",
|
||||
name: "EHoldingsLocalPackagesShow",
|
||||
component: markRaw(EHoldingsLocalPackagesShow),
|
||||
title: $__('Show package'),
|
||||
},
|
||||
{
|
||||
path: "add",
|
||||
name: "EHoldingsLocalPackagesFormAdd",
|
||||
component: markRaw(EHoldingsLocalPackagesFormAdd),
|
||||
title: $__('Add package'),
|
||||
},
|
||||
{
|
||||
path: "edit/:package_id",
|
||||
name: "EHoldingsLocalPackagesFormAddEdit",
|
||||
component: markRaw(EHoldingsLocalPackagesFormAdd),
|
||||
title: $__('Edit package'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "titles",
|
||||
title: $__('Titles'),
|
||||
icon: "fa-sort-alpha-asc",
|
||||
is_end_node: true,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "EHoldingsLocalTitlesList",
|
||||
component: markRaw(EHoldingsLocalTitlesList),
|
||||
},
|
||||
{
|
||||
path: ":title_id",
|
||||
name: "EHoldingsLocalTitlesShow",
|
||||
component: markRaw(EHoldingsLocalTitlesShow),
|
||||
title: $__('Show title'),
|
||||
},
|
||||
{
|
||||
path: "add",
|
||||
name: "EHoldingsLocalTitlesFormAdd",
|
||||
component: markRaw(EHoldingsLocalTitlesFormAdd),
|
||||
title: $__('Add title'),
|
||||
},
|
||||
{
|
||||
path: "edit/:title_id",
|
||||
name: "EHoldingsLocalTitlesFormAddEdit",
|
||||
component: markRaw(EHoldingsLocalTitlesFormAdd),
|
||||
title: $__('Edit title'),
|
||||
},
|
||||
{
|
||||
path: "import",
|
||||
name: "EHoldingsLocalTitlesFormImport",
|
||||
component: markRaw(EHoldingsLocalTitlesFormImport),
|
||||
title: $__('Import from a list'),
|
||||
},
|
||||
{
|
||||
path: "/cgi-bin/koha/erm/eholdings/local/resources/:resource_id",
|
||||
name: "EHoldingsLocalResourcesShow",
|
||||
component: markRaw(EHoldingsLocalResourcesShow),
|
||||
title: $__('Resource'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "ebsco",
|
||||
title: $__('EBSCO'),
|
||||
icon: 'fa-globe',
|
||||
disabled: true,
|
||||
children: [
|
||||
{
|
||||
path: "packages",
|
||||
title: $__('Packages'),
|
||||
icon: "fa-archive",
|
||||
is_end_node: true,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "EHoldingsEBSCOPackagesList",
|
||||
component: markRaw(EHoldingsEBSCOPackagesList),
|
||||
},
|
||||
{
|
||||
path: ":package_id",
|
||||
name: "EHoldingsEBSCOPackagesShow",
|
||||
component: markRaw(EHoldingsEBSCOPackagesShow),
|
||||
title: $__('Show package'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "titles",
|
||||
title: $__('Titles'),
|
||||
icon: "fa-sort-alpha-asc",
|
||||
is_end_node: true,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "EHoldingsEBSCOTitlesList",
|
||||
component: markRaw(EHoldingsEBSCOTitlesList),
|
||||
},
|
||||
{
|
||||
path: ":title_id",
|
||||
name: "EHoldingsEBSCOTitlesShow",
|
||||
component: markRaw(EHoldingsEBSCOTitlesShow),
|
||||
title: $__('Show title'),
|
||||
},
|
||||
{
|
||||
path: "/cgi-bin/koha/erm/eholdings/ebsco/resources/:resource_id",
|
||||
name: "EHoldingsEBSCOResourcesShow",
|
||||
component: markRaw(EHoldingsEBSCOResourcesShow),
|
||||
title: $__('Resource'),
|
||||
is_navigation_item: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: ":license_id",
|
||||
name: "LicensesShow",
|
||||
component: LicensesShow,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
breadcrumb_paths.licenses,
|
||||
"Show license" // $t("Show license")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "add",
|
||||
name: "LicensesFormAdd",
|
||||
component: LicensesFormAdd,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
breadcrumb_paths.licenses,
|
||||
"Add license" // $t("Add license")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "edit/:license_id",
|
||||
name: "LicensesFormAddEdit",
|
||||
component: LicensesFormAdd,
|
||||
meta: {
|
||||
breadcrumb: () =>
|
||||
build_breadcrumb(
|
||||
breadcrumb_paths.licenses,
|
||||
"Edit license" // $t("Edit license")
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
]
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,207 @@
|
|||
import {
|
||||
defineStore
|
||||
} from "pinia";
|
||||
|
||||
export const useNavigationStore = defineStore("navigation", {
|
||||
state: () => ({
|
||||
routeState: {
|
||||
alt: "Home",
|
||||
href: "/cgi-bin/koha/mainpage.pl",
|
||||
is_navigation_item: false,
|
||||
is_base: true,
|
||||
children: []
|
||||
},
|
||||
current: null,
|
||||
params: {},
|
||||
}),
|
||||
actions: {
|
||||
setRoutes(routesDef) {
|
||||
if (!Array.isArray(routesDef)) {
|
||||
routesDef = [routesDef]
|
||||
}
|
||||
this.routeState.children = routesDef
|
||||
_traverseChildren(this.routeState)
|
||||
|
||||
return this.navigationRoutes
|
||||
|
||||
// Function declarations
|
||||
|
||||
function _traverseChildren(parent) {
|
||||
if (isParent(parent)) {
|
||||
parent.children.forEach(child => {
|
||||
_setChildDefaults(parent, child);
|
||||
_traverseChildren(child)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function _setChildDefaults(parent, child) {
|
||||
child.parent = parent;
|
||||
if (isRoutable(child)) {
|
||||
_setMetadata(child);
|
||||
}
|
||||
if (parent.children.length === 1 && parent.is_base) {
|
||||
_setBaseAndNavigationDefaults(child, {
|
||||
is_base: true,
|
||||
is_navigation_item: false
|
||||
});
|
||||
} else {
|
||||
_setBaseAndNavigationDefaults(child, {
|
||||
is_base: false,
|
||||
is_navigation_item: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function _setBaseAndNavigationDefaults(child, {
|
||||
is_base,
|
||||
is_navigation_item
|
||||
}) {
|
||||
child.is_base = child.is_base !== undefined ? child.is_base : is_base;
|
||||
child.is_navigation_item = child.is_navigation_item !== undefined ? child.is_navigation_item : is_navigation_item;
|
||||
}
|
||||
|
||||
function _setMetadata(child) {
|
||||
if (!child.meta)
|
||||
child.meta = {};
|
||||
child.meta.self = child;
|
||||
}
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
breadcrumbs() {
|
||||
if (this.current)
|
||||
return _buildFromCurrentMatches(this.current, this.routeState)
|
||||
|
||||
return _getBaseElements(this.routeState)
|
||||
|
||||
// Function declarations
|
||||
|
||||
function _getBaseElements(parent) {
|
||||
if (!parent.is_base) return []
|
||||
let next = {}
|
||||
if (isParent(parent)) {
|
||||
next = _defineNextElement(parent)
|
||||
}
|
||||
return [{
|
||||
...parent,
|
||||
children: null
|
||||
}, ..._getBaseElements(next)]
|
||||
}
|
||||
|
||||
function _defineNextElement(parent) {
|
||||
return parent.children.find(child => child.is_default) || parent.children[0];
|
||||
}
|
||||
|
||||
function _buildFromCurrentMatches(currentMatches, routeState) {
|
||||
return [
|
||||
{
|
||||
...routeState,
|
||||
icon: null,
|
||||
children: null
|
||||
},
|
||||
..._mapMatches(currentMatches)
|
||||
];
|
||||
}
|
||||
|
||||
function _isBaseOrNotStub(child) {
|
||||
return child.is_base || (child.path && child.path !== '');
|
||||
}
|
||||
|
||||
function _mapMatches(currentMatches) {
|
||||
return currentMatches
|
||||
.filter((match) => _isBaseOrNotStub(match.meta.self))
|
||||
.map((match) => ({
|
||||
...match.meta.self,
|
||||
icon: null,
|
||||
path: match.path,
|
||||
children: null
|
||||
}));
|
||||
}
|
||||
|
||||
},
|
||||
leftNavigation() {
|
||||
return _getNavigationElements(this.routeState)
|
||||
|
||||
// Function declarations
|
||||
|
||||
function _getNavigationElements(parent, prevPath = '') {
|
||||
if (_isBaseAndNoChildren(parent)) return [];
|
||||
if (parent.is_base)
|
||||
return _buildChildNavigationElements(parent).flat(Infinity)
|
||||
|
||||
const builtPath = _buildPath(prevPath, parent);
|
||||
|
||||
let children = []
|
||||
if (!parent.is_end_node && isParent(parent)) {
|
||||
children = _buildChildNavigationElements(parent, builtPath)
|
||||
}
|
||||
|
||||
return {
|
||||
...parent,
|
||||
path: builtPath ? builtPath : parent.path,
|
||||
children
|
||||
}
|
||||
}
|
||||
|
||||
function _buildPath(prevPath, element) {
|
||||
let builtPath;
|
||||
|
||||
if (isRoutable(element) && isAbsolutePath(element.path)) {
|
||||
builtPath = element.path;
|
||||
} else {
|
||||
if (prevPath)
|
||||
builtPath = '' + prevPath + addSlashIfNotPresent(prevPath);
|
||||
if (isRoutable(element))
|
||||
builtPath = '' + builtPath + element.path;
|
||||
}
|
||||
|
||||
return builtPath;
|
||||
}
|
||||
|
||||
function _buildChildNavigationElements(parent, builtPath) {
|
||||
return parent.children
|
||||
.filter(child => child.is_base || child.is_navigation_item)
|
||||
.map(child => _getNavigationElements(child, builtPath));
|
||||
}
|
||||
|
||||
function _isBaseAndNoChildren(parent) {
|
||||
return parent.is_base && (!parent.children || !parent.children.length);
|
||||
}
|
||||
},
|
||||
navigationRoutes() {
|
||||
let routes = _toRoute(this.routeState)
|
||||
return Array.isArray(routes) ? routes : [routes]
|
||||
|
||||
// Function declarations
|
||||
|
||||
function _toRoute(parent) {
|
||||
if (!isRoutable(parent))
|
||||
return _getRoutableChildren(parent)
|
||||
return parent
|
||||
}
|
||||
|
||||
function _getRoutableChildren(parent) {
|
||||
return parent.children
|
||||
.map(child => _toRoute(child))
|
||||
.flat(Infinity);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function addSlashIfNotPresent(path) {
|
||||
return /\/$/.test(path) ? '' : '/';
|
||||
}
|
||||
|
||||
function isRoutable(element) {
|
||||
return element.path !== undefined || element.name !== undefined;
|
||||
}
|
||||
|
||||
function isParent(parent) {
|
||||
return parent.children && parent.children.length;
|
||||
}
|
||||
|
||||
function isAbsolutePath(path) {
|
||||
return /^\//.test(path);
|
||||
}
|
||||
Loading…
Reference in New Issue