feat: add navigation for remote machines
This commit is contained in:
+11
-5
@@ -27,7 +27,10 @@ import { usePersistentState } from "./hooks/usePersistentState";
|
||||
import { useIsMobile } from "./hooks/useIsMobile";
|
||||
import { useServiceInstances } from "./hooks/useServices";
|
||||
import { useDashboards } from "./hooks/useDashboards";
|
||||
import { configuredNavEntries } from "./integrations/navEntries";
|
||||
import {
|
||||
configuredNavEntries,
|
||||
remoteMachineNavEntries,
|
||||
} from "./integrations/navEntries";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Tooltip,
|
||||
@@ -97,10 +100,13 @@ function useNavItems() {
|
||||
const configuredTypes = new Set(
|
||||
services.filter((s) => s.enabled).map((s) => s.service_type),
|
||||
);
|
||||
const serviceEntries = configuredNavEntries(configuredTypes).map((e) => ({
|
||||
path: e.path,
|
||||
label: e.label,
|
||||
icon: e.icon,
|
||||
const serviceEntries = [
|
||||
...configuredNavEntries(configuredTypes),
|
||||
...remoteMachineNavEntries(services),
|
||||
].map((entry) => ({
|
||||
path: entry.path,
|
||||
label: entry.label,
|
||||
icon: entry.icon,
|
||||
}));
|
||||
const dashboardEntries = dashboards.map((d) => ({
|
||||
path: `/d/${d.slug}`,
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { configuredNavEntries, SERVICE_TYPE_NAV_ENTRIES } from "../navEntries";
|
||||
import {
|
||||
configuredNavEntries,
|
||||
remoteMachineNavEntries,
|
||||
SERVICE_TYPE_NAV_ENTRIES,
|
||||
} from "../navEntries";
|
||||
|
||||
describe("navEntries", () => {
|
||||
it("returns no entries when no types are configured", () => {
|
||||
@@ -13,8 +17,33 @@ describe("navEntries", () => {
|
||||
expect(entries[0].path).toBe("/services/jellyfin");
|
||||
});
|
||||
|
||||
it("does not expose remote machines as a top-level entry", () => {
|
||||
expect(configuredNavEntries(new Set(["remote_machine"]))).toEqual([]);
|
||||
it("creates one top-level entry per enabled remote machine", () => {
|
||||
const entries = remoteMachineNavEntries([
|
||||
{
|
||||
id: "storage",
|
||||
name: "Storage",
|
||||
service_type: "remote_machine",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "worker",
|
||||
name: "Worker",
|
||||
service_type: "remote_machine",
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
id: "disabled",
|
||||
name: "Disabled",
|
||||
service_type: "remote_machine",
|
||||
enabled: false,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(entries.map((entry) => entry.label)).toEqual(["Storage", "Worker"]);
|
||||
expect(entries.map((entry) => entry.path)).toEqual([
|
||||
"/services/remote_machine/storage",
|
||||
"/services/remote_machine/worker",
|
||||
]);
|
||||
});
|
||||
|
||||
it("returns all observability entries", () => {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
GanttChartSquare,
|
||||
Magnet,
|
||||
Monitor,
|
||||
Server,
|
||||
Users,
|
||||
type LucideIcon,
|
||||
} from "lucide-react";
|
||||
@@ -24,6 +25,13 @@ export interface NavEntry {
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface RemoteMachineNavSource {
|
||||
id: string;
|
||||
name: string;
|
||||
service_type: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static mapping from service type to its conditional nav entry.
|
||||
* Uses the service type's display name. One entry per type.
|
||||
@@ -77,3 +85,20 @@ export function configuredNavEntries(configuredTypes: Set<string>): NavEntry[] {
|
||||
configuredTypes.has(e.serviceType),
|
||||
);
|
||||
}
|
||||
|
||||
/** One direct sidebar entry for each enabled Remote Machine service. */
|
||||
export function remoteMachineNavEntries(
|
||||
services: RemoteMachineNavSource[],
|
||||
): NavEntry[] {
|
||||
return services
|
||||
.filter(
|
||||
(service) => service.enabled && service.service_type === "remote_machine",
|
||||
)
|
||||
.sort((left, right) => left.name.localeCompare(right.name))
|
||||
.map((service) => ({
|
||||
serviceType: service.service_type,
|
||||
label: service.name,
|
||||
icon: Server,
|
||||
path: `/services/remote_machine/${encodeURIComponent(service.id)}`,
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user