semantic cleanup
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
import { t } from "$lib/i18n";
|
||||
import { auth } from "$lib/auth/store.js";
|
||||
import { buildSidebarCategories } from "$lib/components/layout/sidebarNavigation.js";
|
||||
import { fetchApi } from "$lib/api.js";
|
||||
import { browser } from "$app/environment";
|
||||
import Icon from "$lib/ui/Icon.svelte";
|
||||
|
||||
@@ -59,10 +60,13 @@
|
||||
const authState = fromStore(auth);
|
||||
const failingCountState = fromStore(failingCount);
|
||||
|
||||
let features = $state({});
|
||||
|
||||
let categories = $derived(
|
||||
buildSidebarCategories(
|
||||
translationState.current,
|
||||
authState.current?.user || null,
|
||||
features,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -183,6 +187,17 @@
|
||||
healthStore.refresh();
|
||||
// Refresh every 5 minutes
|
||||
const interval = setInterval(() => healthStore.refresh(), 5 * 60 * 1000);
|
||||
|
||||
// Fetch feature flags for sidebar filtering
|
||||
fetchApi("/settings/features")
|
||||
.then((res) => {
|
||||
features = res;
|
||||
})
|
||||
.catch(() => {
|
||||
// Graceful degradation: default to {} (all features visible)
|
||||
features = {};
|
||||
});
|
||||
|
||||
return () => clearInterval(interval);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -24,10 +24,10 @@ function isItemAllowed(user, item) {
|
||||
// [/DEF:isItemAllowed:Function]
|
||||
|
||||
// [DEF:buildSidebarCategories:Function]
|
||||
// @PURPOSE: Build translated sidebar categories and filter them by RBAC permissions.
|
||||
// @PRE: i18nState provides nav labels; user can be null.
|
||||
// @POST: Returns only categories/subitems available for provided user.
|
||||
export function buildSidebarCategories(i18nState, user) {
|
||||
// @PURPOSE: Build translated sidebar categories and filter them by RBAC permissions and feature flags.
|
||||
// @PRE: i18nState provides nav labels; user can be null; features default to {} (all enabled).
|
||||
// @POST: Returns only categories/subitems available for provided user and enabled features.
|
||||
export function buildSidebarCategories(i18nState, user, features = {}) {
|
||||
const nav = i18nState?.nav || {};
|
||||
|
||||
const categories = [
|
||||
@@ -51,6 +51,7 @@ export function buildSidebarCategories(i18nState, user) {
|
||||
path: "/dashboards/health",
|
||||
requiredPermission: "plugin:migration",
|
||||
requiredAction: "READ",
|
||||
requiredFeature: "health_monitor",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -74,6 +75,7 @@ export function buildSidebarCategories(i18nState, user) {
|
||||
path: "/datasets/review",
|
||||
requiredPermission: "plugin:migration",
|
||||
requiredAction: "READ",
|
||||
requiredFeature: "dataset_review",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -154,10 +156,15 @@ export function buildSidebarCategories(i18nState, user) {
|
||||
},
|
||||
];
|
||||
|
||||
function isFeatureEnabled(item) {
|
||||
if (!item?.requiredFeature) return true;
|
||||
return features[item.requiredFeature] !== false;
|
||||
}
|
||||
|
||||
return categories
|
||||
.map((category) => {
|
||||
const visibleSubItems = (category.subItems || []).filter((subItem) =>
|
||||
isItemAllowed(user, subItem),
|
||||
const visibleSubItems = (category.subItems || []).filter(
|
||||
(subItem) => isItemAllowed(user, subItem) && isFeatureEnabled(subItem),
|
||||
);
|
||||
return {
|
||||
...category,
|
||||
|
||||
Reference in New Issue
Block a user