This is an automated email from the ASF dual-hosted git repository.
wu-sheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-horizon-ui.git
The following commit(s) were added to refs/heads/main by this push:
new 5510c7f bff: drop stale getMenuItems query from /api/menu
5510c7f is described below
commit 5510c7fe8a113d8073411f5db4fb3ee25c90f331
Author: Wu Sheng <[email protected]>
AuthorDate: Wed May 20 09:04:22 2026 +0800
bff: drop stale getMenuItems query from /api/menu
`getMenuItems` is not in OAP's GraphQL schema, so the request was
emitting a GraphQL validation warning on every menu fetch and returning
nothing. The bundled `bundled_templates/layers/<key>.json` files
already own per-layer alias / color / documentLink / slots / caps;
deriveLayer's primary path reads from there.
Changes:
- GraphQL query: remove the `items: getMenuItems { … }` selection.
What's left is `listLayers` + `listLayerLevels`.
- MenuRaw: drop `items`.
- deriveLayer: drop the `items` parameter. The template-or-default
paths produce `name` from the template alias / a title-cased
rawKey, and `documentLink` from the template.
- Catalog order: build from `allLayerTemplates()` (filesystem order
under bundled_templates/layers/, alphabetical by basename), with
OAP-active layers that have no template appended after. The
`items`-driven ordering loop is gone.
---
apps/bff/src/http/query/menu.ts | 58 ++++++++++++++---------------------------
1 file changed, 19 insertions(+), 39 deletions(-)
diff --git a/apps/bff/src/http/query/menu.ts b/apps/bff/src/http/query/menu.ts
index 809ca2a..2eae4d0 100644
--- a/apps/bff/src/http/query/menu.ts
+++ b/apps/bff/src/http/query/menu.ts
@@ -27,7 +27,7 @@ import type { ConfigSource } from '../../config/loader.js';
import type { SessionStore } from '../../user/sessions.js';
import { requireAuth } from '../../user/middleware.js';
import { buildOapOpts, graphqlPost, type GraphqlOptions } from
'../../client/graphql.js';
-import { getLayerTemplate, type LayerComponentFlags } from
'../../logic/layers/loader.js';
+import { allLayerTemplates, getLayerTemplate, type LayerComponentFlags } from
'../../logic/layers/loader.js';
/**
* Map the JSON config's `components.*` flags onto the wire `caps`
@@ -65,19 +65,11 @@ export interface MenuRouteDeps {
fetch?: FetchLike;
}
-// One round-trip, three aliased queries.
+// `listLayers` — active layers in this deployment.
+// `listLayerLevels` — catalog level per layer (sidebar hierarchy).
const MENU_QUERY = /* GraphQL */ `
query HorizonMenu {
layers: listLayers
- items: getMenuItems {
- title
- icon
- layer
- activate
- description
- documentLink
- i18nKey
- }
levels: listLayerLevels {
layer
level
@@ -102,15 +94,6 @@ function canonical(layer: string): string {
interface MenuRaw {
layers: string[];
- items: Array<{
- title: string;
- icon?: string | null;
- layer: string;
- activate?: boolean | null;
- description?: string | null;
- documentLink?: string | null;
- i18nKey?: string | null;
- }>;
levels: Array<{ layer: string; level: number }>;
}
@@ -174,17 +157,16 @@ function deriveLayer(
level: number | null,
serviceCount: number,
normal: boolean | null,
- items: MenuRaw['items'],
): LayerDef {
- const item = items.find((i) => canonical(i.layer) === rawKey);
- // JSON template wins when present — alias / color / slots / caps all
- // come from there. Hardcoded LAYER_DEFAULTS stays as the fallback for
- // layers without a template (older OAP layers, custom layers).
+ // JSON template wins when present — alias / color / slots / caps /
+ // documentLink all come from there. Hardcoded LAYER_DEFAULTS stays as
+ // the fallback for layers without a template (older OAP layers,
+ // custom layers).
const tpl = getLayerTemplate(rawKey);
if (tpl) {
return {
key: rawKey.toLowerCase(),
- name: tpl.alias || item?.title?.trim() || rawKey,
+ name: tpl.alias || rawKey,
color: tpl.color || 'var(--sw-fg-2)',
serviceCount,
active,
@@ -192,7 +174,7 @@ function deriveLayer(
normal,
group: tpl.group,
visibility: tpl.visibility,
- documentLink: tpl.documentLink ?? item?.documentLink ?? undefined,
+ documentLink: tpl.documentLink ?? undefined,
slots: tpl.slots,
caps: componentsToCaps(tpl.components),
header: tpl.header,
@@ -206,13 +188,12 @@ function deriveLayer(
const def = LAYER_DEFAULTS[rawKey] ?? DEFAULT_FOR_UNKNOWN_LAYER;
return {
key: rawKey.toLowerCase(),
- name: item?.title?.trim() || rawKey.replace(/_/g, '
').toLowerCase().replace(/\b\w/g, (c) => c.toUpperCase()),
+ name: rawKey.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, (c) =>
c.toUpperCase()),
color: def.color,
serviceCount,
active,
level,
normal,
- documentLink: item?.documentLink ?? undefined,
slots: def.slots,
caps: def.caps,
};
@@ -286,14 +267,14 @@ export function registerMenuRoute(app: FastifyInstance,
deps: MenuRouteDeps): vo
}
}
- // Catalog order = the order OAP returned `getMenuItems` (mirrors
- // menu.yaml). Active-only keys not in the catalog get appended at
- // the end so nothing disappears.
+ // Catalog order = the order the JSON layer templates are loaded
+ // (filesystem order under bundled_templates/layers/, alphabetical
+ // by basename). Active OAP-reported layers that have no template
+ // get appended at the end so nothing disappears from the sidebar.
const ordered: string[] = [];
const seen = new Set<string>();
- for (const item of raw.items) {
- if (!item.layer) continue;
- const k = canonical(item.layer);
+ for (const tpl of allLayerTemplates()) {
+ const k = canonical(tpl.key.toUpperCase());
if (seen.has(k)) continue;
seen.add(k);
ordered.push(k);
@@ -306,9 +287,9 @@ export function registerMenuRoute(app: FastifyInstance,
deps: MenuRouteDeps): vo
}
// Layers we deliberately drop from the sidebar even when OAP
- // surfaces them. BanyanDB is OAP's storage backend — it shows
- // up as a Layer in `getMenuItems`, but the operator monitors it
- // via the OAP self-observability dashboard (CPU / memory / GC
+ // surfaces them. BanyanDB is OAP's storage backend — it shows up
+ // as a Layer in `listLayers`, but the operator monitors it via
+ // the OAP self-observability dashboard (CPU / memory / GC
// metrics there cover the storage node too). Keeping it as a
// standalone Databases-ish row was confusing per operator
// feedback. Add more keys here if other internal-only layers
@@ -323,7 +304,6 @@ export function registerMenuRoute(app: FastifyInstance,
deps: MenuRouteDeps): vo
levelByCanonical.has(key) ? (levelByCanonical.get(key) ?? null) :
null,
countByCanonical.get(key) ?? (activeCanonical.has(key) ? 0 : -1),
normalByCanonical.get(key) ?? null,
- raw.items,
),
);