@@ -9,51 +9,78 @@ import {
99 DropdownMenuTrigger ,
1010} from '@/components/ui/dropdownMenu' ;
1111import { useInstanceManagePermission } from '@/hooks/usePermissions' ;
12+ import { excludeFalsy } from '@/lib/arrays/excludeFalsy' ;
1213import { buildAbsoluteLinkToPage } from '@/lib/urls/buildAbsoluteLinkToPage' ;
1314import { Link , useParams } from '@tanstack/react-router' ;
14- import { DatabaseIcon , GaugeIcon , Menu , NotepadText , Package , SettingsIcon } from 'lucide-react' ;
15+ import { DatabaseIcon , GaugeIcon , Menu , NotepadTextIcon , PackageIcon , SettingsIcon } from 'lucide-react' ;
16+ import { ReactNode , useMemo } from 'react' ;
1517
16- function DesktopInstanceNavBar ( ) {
18+ interface Link {
19+ to : string ;
20+ name : string ;
21+ shortName ?: string ;
22+ icon : ReactNode ;
23+ }
24+
25+ export function InstanceNavBar ( ) {
1726 const canManage = useInstanceManagePermission ( ) ;
1827 const params = useParams ( { strict : false } ) ;
28+ const links = useMemo ( ( ) => [
29+ {
30+ to : buildAbsoluteLinkToPage ( params ) ,
31+ name : 'Applications' ,
32+ shortName : 'Apps' ,
33+ icon : < PackageIcon className = "inline-block" /> ,
34+ } ,
35+ {
36+ to : buildAbsoluteLinkToPage ( params , 'databases' ) ,
37+ icon : < DatabaseIcon className = "inline-block" /> ,
38+ name : 'Databases' ,
39+ } ,
40+ canManage && {
41+ to : buildAbsoluteLinkToPage ( params , 'status' ) ,
42+ icon : < GaugeIcon className = "inline-block" /> ,
43+ name : 'Status' ,
44+ } ,
45+ canManage && {
46+ to : buildAbsoluteLinkToPage ( params , 'logs' ) ,
47+ icon : < NotepadTextIcon className = "inline-block" /> ,
48+ name : 'Logs' ,
49+ } ,
50+ canManage && {
51+ to : buildAbsoluteLinkToPage ( params , 'config' ) ,
52+ icon : < SettingsIcon className = "inline-block" /> ,
53+ name : 'Config' ,
54+ } ,
55+ ] . filter ( excludeFalsy ) satisfies Link [ ] , [ canManage , params ] ) ;
56+ return (
57+ < >
58+ < DesktopInstanceNavBar links = { links } />
59+ < MobileInstanceNavBar links = { links } />
60+ </ >
61+ ) ;
62+ }
63+
64+ function DesktopInstanceNavBar ( { links } : { links : Link [ ] } ) {
1965 return (
2066 < div className = "hidden md:flex items-center justify-between h-full text-sm text-white" >
2167 < Breadcrumbs />
2268 < div className = "flex space-x-2 *:hover:text-grey" >
23- < Link to = { buildAbsoluteLinkToPage ( params ) } className = "p-2 text-center" >
24- < Package className = "inline-block" />
25- < span className = "hidden xl:inline-block ml-1" > Applications</ span >
26- < span className = "visible xl:hidden ml-1" > Apps</ span >
27-
28- </ Link >
29- < Link to = { buildAbsoluteLinkToPage ( params , 'databases' ) } className = "p-2 text-center" >
30- < DatabaseIcon className = "inline-block" />
31- < span className = "hidden xl:inline-block ml-1" > Databases</ span >
32- </ Link >
33- { canManage && (
34- < >
35- < Link to = { buildAbsoluteLinkToPage ( params , 'status' ) } className = "p-2 text-center" >
36- < GaugeIcon className = "inline-block" />
37- < span className = "hidden xl:inline-block ml-1" > Status</ span >
38- </ Link >
39- < Link to = { buildAbsoluteLinkToPage ( params , 'logs' ) } className = "p-2 text-center" >
40- < NotepadText className = "inline-block" />
41- < span className = "hidden xl:inline-block ml-1" > Logs</ span >
42- </ Link >
43- < Link to = { buildAbsoluteLinkToPage ( params , 'config' ) } className = "p-2 text-center" >
44- < SettingsIcon className = "inline-block" />
45- < span className = "hidden xl:inline-block ml-1" > Config</ span >
46- </ Link >
47- </ >
48- ) }
69+ { links . map ( link => (
70+ < Link key = { link . to } to = { link . to } className = "p-2 text-center" >
71+ { link . icon }
72+ < span className = "hidden xl:inline-block ml-1" > { link . name } </ span >
73+ { link . shortName && (
74+ < span className = "visible xl:hidden ml-1" > { link . shortName } </ span >
75+ ) }
76+ </ Link >
77+ ) ) }
4978 </ div >
5079 </ div >
5180 ) ;
5281}
5382
54- function MobileInstanceNavBar ( ) {
55- const canManage = useInstanceManagePermission ( ) ;
56- const params = useParams ( { strict : false } ) ;
83+ function MobileInstanceNavBar ( { links } : { links : Link [ ] } ) {
5784 return (
5885 < >
5986 < div className = "flex md:hidden items-center justify-between p-2 text-white" >
@@ -67,37 +94,15 @@ function MobileInstanceNavBar() {
6794 < DropdownMenuContent >
6895 < DropdownMenuLabel > Instance Menu</ DropdownMenuLabel >
6996 < DropdownMenuSeparator />
70- < DropdownMenuItem asChild >
71- < Link to = { buildAbsoluteLinkToPage ( params ) } > Applications</ Link >
72- </ DropdownMenuItem >
73- < DropdownMenuItem asChild >
74- < Link to = { buildAbsoluteLinkToPage ( params , 'databases' ) } > Databases</ Link >
75- </ DropdownMenuItem >
76- { canManage && (
77- < >
78- < DropdownMenuItem asChild >
79- < Link to = { buildAbsoluteLinkToPage ( params , 'status' ) } > Status</ Link >
80- </ DropdownMenuItem >
81- < DropdownMenuItem asChild >
82- < Link to = { buildAbsoluteLinkToPage ( params , 'config' ) } > Config</ Link >
83- </ DropdownMenuItem >
84- < DropdownMenuItem asChild >
85- < Link to = { buildAbsoluteLinkToPage ( params , 'logs' ) } > Logs</ Link >
86- </ DropdownMenuItem >
87- </ >
88- ) }
97+
98+ { links . map ( link => (
99+ < DropdownMenuItem key = { link . to } asChild >
100+ < Link to = { link . to } > { link . name } </ Link >
101+ </ DropdownMenuItem >
102+ ) ) }
89103 </ DropdownMenuContent >
90104 </ DropdownMenu >
91105 </ div >
92106 </ >
93107 ) ;
94108}
95-
96- export function InstanceNavBar ( ) {
97- return (
98- < >
99- < DesktopInstanceNavBar />
100- < MobileInstanceNavBar />
101- </ >
102- ) ;
103- }
0 commit comments