mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-03-03 16:05:56 +00:00
webapp > Settings: add breadcrumbs
This commit is contained in:
parent
27319b6ee1
commit
1e7ec18a2f
1 changed files with 61 additions and 3 deletions
|
@ -35,9 +35,20 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-content col-lg-9 col-md-7">
|
<div class="settings-content col-lg-9 col-md-7">
|
||||||
<div v-if="currentPage" class="settings-content-header">
|
<nav aria-label="breadcrumb">
|
||||||
{{ subMenus[currentPage].title }}
|
<ol class="breadcrumb settings-content-header">
|
||||||
</div>
|
<li
|
||||||
|
v-for="{ path, title, active } in breadcrumbs"
|
||||||
|
:key="path"
|
||||||
|
class="breadcrumb-item"
|
||||||
|
v-bind="active ? { 'aria-current': 'page' } : {}"
|
||||||
|
aria-current="page"
|
||||||
|
>
|
||||||
|
<template v-if="active">{{ title }}</template>
|
||||||
|
<RouterLink v-else :to="path">{{ title }}</RouterLink>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
<div class="mx-3">
|
<div class="mx-3">
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<transition name="slide-fade" appear>
|
<transition name="slide-fade" appear>
|
||||||
|
@ -54,6 +65,15 @@
|
||||||
<script>
|
<script>
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deduplicate an array of objects using the provided key
|
||||||
|
* @param {object[]} arr array of objects to deduplicate
|
||||||
|
* @param {string} key key used for uniqness
|
||||||
|
* @returns {object[]} the deduplicated array
|
||||||
|
*/
|
||||||
|
const uniqBy = (arr, key) =>
|
||||||
|
[ ...(new Map(arr.map(item => [ item[key], item ]))).values() ];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -121,6 +141,44 @@ export default {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
breadcrumbs: ({ $route, subMenus }) => {
|
||||||
|
// List of setting routes matching the current path
|
||||||
|
// for ex, with path "/settings/users/edit/1", we got:
|
||||||
|
// [
|
||||||
|
// { path: "/settings/users", ...otherRoutesProps },
|
||||||
|
// { path: "/settings/users/edit/:id", ...otherRoutesProps }
|
||||||
|
// ]
|
||||||
|
const settingRoutes = uniqBy(
|
||||||
|
$route.matched.filter(({ path }) => /^\/settings\//.test(path)),
|
||||||
|
"path"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get leaf submenu for a given setting path
|
||||||
|
* @param {string} path setting path, ex: "/settings/users/edit/1"
|
||||||
|
* @returns {object} the leaf subMenu corresponding to the given path
|
||||||
|
*/
|
||||||
|
const getLeafSubMenu = path => {
|
||||||
|
const pathParts = path.split("/").slice(2);
|
||||||
|
|
||||||
|
// walk through submenus and there children until reaching the corresponding leaf subMenu
|
||||||
|
// ex with "/settings/users/edit/1" we got { title: this.$t("Edit") }
|
||||||
|
// because this path match "users" > "children" > "edit" in subMenus
|
||||||
|
return pathParts.reduce(
|
||||||
|
(acc, pathPart) =>
|
||||||
|
acc[pathPart] || acc.children?.[pathPart] || acc,
|
||||||
|
subMenus
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// construct an array of setting routes path joined with submenus
|
||||||
|
return settingRoutes.map(({ path }, idx) => ({
|
||||||
|
path,
|
||||||
|
title: getLeafSubMenu(path).title,
|
||||||
|
active: !settingRoutes[idx + 1],
|
||||||
|
}));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
|
|
Loading…
Add table
Reference in a new issue