@@ -, +, @@
---
.../prog/js/vue/components/Breadcrumbs.vue | 9 +-
.../prog/js/vue/components/NavigationItem.vue | 3 +-
.../intranet-tmpl/prog/js/vue/i18n/index.js | 9 +
.../intranet-tmpl/prog/js/vue/modules/erm.ts | 9 +-
.../intranet-tmpl/prog/js/vue/routes/erm.js | 107 ++++---
.../prog/js/vue/stores/navigation.js | 303 ++++++++++++------
6 files changed, 276 insertions(+), 164 deletions(-)
create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/i18n/index.js
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Breadcrumbs.vue
+++ a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Breadcrumbs.vue
@@ -8,7 +8,7 @@
>
@@ -35,9 +35,10 @@ export default {
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/NavigationItem.vue
+++ a/koha-tmpl/intranet-tmpl/prog/js/vue/components/NavigationItem.vue
@@ -21,7 +21,8 @@
{{ $__(item.title) }}
-
+
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/i18n/index.js
+++ a/koha-tmpl/intranet-tmpl/prog/js/vue/i18n/index.js
@@ -0,0 +1,9 @@
+export const $__ = (key) => {
+ return window["__"](key);
+};
+
+export default {
+ install: (app, options) => {
+ app.config.globalProperties.$__ = $__
+ },
+};
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/erm.ts
+++ a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/erm.ts
@@ -23,17 +23,10 @@ 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 i18n = {
- install: (app, options) => {
- app.config.globalProperties.$__ = (key) => {
- return window["__"](key);
- };
- },
-};
-
const mainStore = useMainStore(pinia);
const AVStore = useAVStore(pinia);
const navigationStore = useNavigationStore(pinia);
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/erm.js
+++ a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/erm.js
@@ -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,6 +21,8 @@ import LicensesList from "../components/ERM/LicensesList.vue";
import LicensesShow from "../components/ERM/LicensesShow.vue";
import LicensesFormAdd from "../components/ERM/LicensesFormAdd.vue";
+import { $__ } from "../i18n";
+
export const routes = [
{
path: "/cgi-bin/koha/admin/background_jobs/:id",
@@ -31,143 +35,142 @@ export const routes = [
},
{
path: "/cgi-bin/koha/erm/erm.pl",
- component: {template: ''},
is_default: true,
is_base: true,
- title: 'E-resource management',
+ title: $__('E-resource management'),
children: [
{
path: "",
- component: Home,
+ component: markRaw(Home),
is_navigation_item: false,
},
{
path: "/cgi-bin/koha/erm/agreements",
- title: 'Agreements',
+ title: $__('Agreements'),
icon: 'fa-check-circle-o',
is_end_node: true,
children: [
{
path: "",
- component: AgreementsList,
+ component: markRaw(AgreementsList),
},
{
path: ":agreement_id",
- component: AgreementsShow,
- title: "Show agreement",
+ component: markRaw(AgreementsShow),
+ title: $__('Show agreement'),
},
{
path: "add",
- component: AgreementsFormAdd,
- title: "Add agreement",
+ component: markRaw(AgreementsFormAdd),
+ title: $__('Add agreement'),
},
{
path: "edit/:agreement_id",
- component: AgreementsFormAdd,
- title: "Edit agreement",
+ component: markRaw(AgreementsFormAdd),
+ title: $__('Edit agreement'),
},
],
},
{
path: "/cgi-bin/koha/erm/licenses",
- title: "Licenses",
+ title: $__('Licenses'),
icon: "fa-gavel",
is_end_node: true,
children: [
{
path: "",
- component: LicensesList,
+ component: markRaw(LicensesList),
},
{
path: ":license_id",
- component: LicensesShow,
- title: "Show license",
+ component: markRaw(LicensesShow),
+ title: $__('Show license'),
},
{
path: "add",
- component: LicensesFormAdd,
- title: "Add license",
+ component: markRaw(LicensesFormAdd),
+ title: $__('Add license'),
},
{
path: "edit/:license_id",
- component: LicensesFormAdd,
- title: "Edit license",
+ component: markRaw(LicensesFormAdd),
+ title: $__('Edit license'),
},
],
},
{
path: "/cgi-bin/koha/erm/eholdings",
- title: "eHoldings",
+ title: $__('eHoldings'),
icon: 'fa-crosshairs',
disabled: true,
children: [
{
path: "local",
- title: "Local",
+ title: $__('Local'),
icon: "fa-map-marker",
disabled: true,
children: [
{
path: "packages",
- title: "Packages",
+ title: $__('Packages'),
icon: "fa-archive",
is_end_node: true,
children: [
{
path: "",
- component: EHoldingsLocalPackagesList,
+ component: markRaw(EHoldingsLocalPackagesList),
},
{
path: ":package_id",
- component: EHoldingsLocalPackagesShow,
- title: "Show package",
+ component: markRaw(EHoldingsLocalPackagesShow),
+ title: $__('Show package'),
},
{
path: "add",
- component: EHoldingsLocalPackagesFormAdd,
- title: "Add package",
+ component: markRaw(EHoldingsLocalPackagesFormAdd),
+ title: $__('Add package'),
},
{
path: "edit/:package_id",
- component: EHoldingsLocalPackagesFormAdd,
- title: "Edit package",
+ component: markRaw(EHoldingsLocalPackagesFormAdd),
+ title: $__('Edit package'),
},
],
},
{
path: "titles",
- title: "Titles",
+ title: $__('Titles'),
icon: "fa-sort-alpha-asc",
is_end_node: true,
children: [
{
path: "",
- component: EHoldingsLocalTitlesList,
+ component: markRaw(EHoldingsLocalTitlesList),
},
{
path: ":title_id",
- component: EHoldingsLocalTitlesShow,
- title: "Show title",
+ component: markRaw(EHoldingsLocalTitlesShow),
+ title: $__('Show title'),
},
{
path: "add",
- component: EHoldingsLocalTitlesFormAdd,
- title: "Add title",
+ component: markRaw(EHoldingsLocalTitlesFormAdd),
+ title: $__('Add title'),
},
{
path: "edit/:title_id",
- component: EHoldingsLocalTitlesFormAdd,
- title: "Edit title",
+ component: markRaw(EHoldingsLocalTitlesFormAdd),
+ title: $__('Edit title'),
},
{
path: "import",
- component: EHoldingsLocalTitlesFormImport,
- title: "Import from a list",
+ component: markRaw(EHoldingsLocalTitlesFormImport),
+ title: $__('Import from a list'),
},
{
path: "/cgi-bin/koha/erm/eholdings/local/resources/:resource_id",
- component: EHoldingsLocalResourcesShow,
- title: "Resource",
+ component: markRaw(EHoldingsLocalResourcesShow),
+ title: $__('Resource'),
},
],
},
@@ -175,46 +178,46 @@ export const routes = [
},
{
path: "ebsco",
- title: "EBSCO",
+ title: $__('EBSCO'),
icon: 'fa-globe',
disabled: true,
children: [
{
path: "packages",
- title: "Packages",
+ title: $__('Packages'),
icon: "fa-archive",
is_end_node: true,
children: [
{
path: "",
- component: EHoldingsEBSCOPackagesList,
+ component: markRaw(EHoldingsEBSCOPackagesList),
},
{
path: ":package_id",
- component: EHoldingsEBSCOPackagesShow,
- title: "Show package",
+ component: markRaw(EHoldingsEBSCOPackagesShow),
+ title: $__('Show package'),
},
],
},
{
path: "titles",
- title: "Titles",
+ title: $__('Titles'),
icon: "fa-sort-alpha-asc",
is_end_node: true,
children: [
{
path: "",
- component: EHoldingsEBSCOTitlesList,
+ component: markRaw(EHoldingsEBSCOTitlesList),
},
{
path: ":title_id",
- component: EHoldingsEBSCOTitlesShow,
- title: "Show title",
+ component: markRaw(EHoldingsEBSCOTitlesShow),
+ title: $__('Show title'),
},
{
path: "/cgi-bin/koha/erm/eholdings/ebsco/resources/:resource_id",
- component: EHoldingsEBSCOResourcesShow,
- title: "Resource",
+ component: markRaw(EHoldingsEBSCOResourcesShow),
+ title: $__('Resource'),
is_navigation_item: false,
},
],
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js
+++ a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js
@@ -1,106 +1,211 @@
-import { defineStore } from "pinia";
+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,
- }),
- actions: {
- setRoutes(routesDef) {
- const _traverse_children = (parent) => {
- if(parent.children && parent.children.length) {
- parent.children.forEach(child => {
- child.parent = parent;
- if(child.path !== undefined) {
- if(!child.meta) child.meta = {};
- child.meta.self = child;
- }
- if(parent.children.length === 1 && parent.is_base) {
- child.is_base = child.is_base !== undefined ? child.is_base : true;
- child.is_navigation_item = child.is_navigation_item !== undefined ? child.is_navigation_item : false;
- } else if (parent.children.length > 1 || !parent.is_base) {
- child.is_base = child.is_base !== undefined ? child.is_base : false;
- child.is_navigation_item = child.is_navigation_item !== undefined ? child.is_navigation_item : true;
- }
- _traverse_children(child)
- })
- }
- }
- if(!Array.isArray(routesDef)) {
- routesDef = [routesDef]
- }
- this.routeState.children = routesDef
- _traverse_children(this.routeState)
- return this.navigationRoutes
- }
- },
- getters: {
- breadcrumbs() {
- const _traverse_parent = (child) => {
- let breadcrumbs = []
- let builtPath = child.path
- if(child.parent) {
- breadcrumbs = _traverse_parent(child.parent)
- if(builtPath !== undefined && !/^\//.test(builtPath)) {
- const {path:parentPath} = breadcrumbs[breadcrumbs.length - 1]
- if(parentPath !== undefined) {
- builtPath = `${parentPath}${/\/$/.test(parentPath)?'':'/'}${builtPath}`
- }
- }
- }
- if (child.is_base || (child.path && child.path !== '')) breadcrumbs.push({...child, icon: null, path: builtPath, children: null})
- return breadcrumbs
- }
- if(this.current)
- return _traverse_parent(this.current)
-
- const _get_base_elements = (parent) => {
- if(!parent.is_base) return []
- let next = {}
- if(parent.children && parent.children.length) {
- next = parent.children.find(child => child.is_default) || parent.children[0]
- }
- return [{...parent, children: null}, ..._get_base_elements(next)]
- }
+ state: () => ({
+ routeState: {
+ alt: "Home",
+ href: "/cgi-bin/koha/mainpage.pl",
+ is_navigation_item: false,
+ is_base: true,
+ children: []
+ },
+ current: null,
+ }),
+ actions: {
+ setRoutes(routesDef) {
+ if (!Array.isArray(routesDef)) {
+ routesDef = [routesDef]
+ }
+ this.routeState.children = routesDef
+ _traverseChildren(this.routeState)
- return _get_base_elements(this.routeState)
- },
- leftNavigation() {
- const _get_navigation_elements = (parent, builtPath = '') => {
- if (parent.is_base && (!parent.children || !parent.children.length)) return [];
- if (parent.is_base) return parent.children.filter(child => child.is_base || child.is_navigation_item).map(_get_navigation_elements).flat(Infinity)
- let items = []
- if(builtPath) builtPath = `${builtPath}${/\/$/.test(builtPath)?'':'/'}`
- if(parent.path !== undefined && /^\//.test(parent.path)) {
- builtPath = parent.path
- } else if (parent.path !== undefined) {
- builtPath = `${builtPath}${parent.path}`
- } else {
- builtPath = ''
- }
- if (!parent.is_end_node && parent.children && parent.children.length) {
- items = parent.children
- .filter(child => child.is_navigation_item)
- .map(child => _get_navigation_elements(child, builtPath))
+ 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;
+ }
}
- return {...parent, path: builtPath ? builtPath : parent.path, children: items}
- }
- const leftNav = _get_navigation_elements(this.routeState)
- return leftNav
},
- navigationRoutes() {
- const _to_route = (parent) => {
- if(parent.path === undefined) return parent.children.map(child => _to_route(child)).flat(Infinity)
- return parent
- }
- let routes = _to_route(this.routeState)
- return Array.isArray(routes) ? routes : [routes]
+ getters: {
+ breadcrumbs() {
+ if (this.current)
+ return _traverseParent(this.current)
+
+ 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 _traverseParent(child) {
+ let breadcrumbs = []
+ let builtPath = child.path
+ if (child.parent) {
+ breadcrumbs = _traverseParent(child.parent)
+ builtPath = _buildPath(builtPath, breadcrumbs);
+ }
+ if (_isBaseOrNotStub(child)) breadcrumbs.push({
+ ...child,
+ icon: null,
+ path: builtPath,
+ children: null
+ })
+ return breadcrumbs
+ }
+
+ function _isBaseOrNotStub(child) {
+ return child.is_base || (child.path && child.path !== '');
+ }
+
+ function _buildPath(builtPath, breadcrumbs) {
+ if (!isAbsolutePath(builtPath)) {
+ const {
+ path: parentPath
+ } = breadcrumbs[breadcrumbs.length - 1];
+ if (parentPath !== undefined) {
+ builtPath = `${parentPath}${addSlashIfNotPresent(parentPath)}${builtPath}`;
+ }
+ }
+ return builtPath;
+ }
+ },
+ 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;
+}
+
+function isParent(parent) {
+ return parent.children && parent.children.length;
+}
+
+function isAbsolutePath(path) {
+ return /^\//.test(path);
+}
--