Bugzilla – Attachment 148081 Details for
Bug 33169
Improve vue breadcrumbs and left-hand menu
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 33169: (follow-up) Cleanup and tidy a little bit
Bug-33169-follow-up-Cleanup-and-tidy-a-little-bit.patch (text/plain), 27.41 KB, created by
Agustín Moyano
on 2023-03-10 16:10:19 UTC
(
hide
)
Description:
Bug 33169: (follow-up) Cleanup and tidy a little bit
Filename:
MIME Type:
Creator:
Agustín Moyano
Created:
2023-03-10 16:10:19 UTC
Size:
27.41 KB
patch
obsolete
>From fe86ebefdc24501fccfb0963b2fd4e8a10f3fc67 Mon Sep 17 00:00:00 2001 >From: Agustin Moyano <agustinmoyano@theke.io> >Date: Thu, 9 Mar 2023 23:02:38 +0000 >Subject: [PATCH] Bug 33169: (follow-up) Cleanup and tidy a little bit > >--- > .../prog/js/vue/components/Breadcrumbs.vue | 14 +- > .../prog/js/vue/components/NavigationItem.vue | 2 +- > .../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, 280 insertions(+), 164 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/i18n/index.js > >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Breadcrumbs.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Breadcrumbs.vue >index f8d87cbce6..e4377221a9 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Breadcrumbs.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Breadcrumbs.vue >@@ -8,7 +8,12 @@ > ></NavigationItem> > <NavigationItem > v-else >- :item="{ ...item, path: undefined, href: undefined }" >+ :item="{ >+ ...item, >+ disabled: true, >+ path: undefined, >+ href: undefined, >+ }" > ></NavigationItem> > </template> > </ol> >@@ -35,9 +40,10 @@ export default { > </script> > > <style> >-#breadcrumbs ol li a.disabled { >- color: #666; >+#breadcrumbs .disabled { >+ padding: 0.6em 0.3em; >+ text-decoration: none; >+ color: #000; > pointer-events: none; >- font-weight: 700; > } > </style> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/NavigationItem.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/NavigationItem.vue >index eedbff9636..bb93aff019 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/NavigationItem.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/NavigationItem.vue >@@ -21,7 +21,7 @@ > </template> > <span v-if="item.title">{{ $__(item.title) }}</span> > </a> >- <span v-else> >+ <span v-else :class="{ disabled: item.disabled }"> > <template v-if="item.icon"> > <i :class="`fa ${item.icon}`"></i> > </template> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/i18n/index.js b/koha-tmpl/intranet-tmpl/prog/js/vue/i18n/index.js >new file mode 100644 >index 0000000000..8dc89f12d1 >--- /dev/null >+++ b/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.$__ = $__ >+ }, >+}; >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/erm.ts b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/erm.ts >index 2d508d4aed..9dbf643964 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/erm.ts >+++ b/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); >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/erm.js b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/erm.js >index 21d777ac3a..46610f0527 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/erm.js >+++ b/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: '<router-view />'}, > 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, > }, > ], >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js >index 9d8a9a5650..6271d6b315 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/navigation.js >+++ b/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); >+} >-- >2.25.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 33169
:
147962
|
148044
|
148081
|
148097
|
149710
|
149744
|
151530
|
151797
|
152068
|
152539
|
152540
|
152541
|
153889
|
153890
|
157785
|
157806
|
157807