Use routes closer to the route for objects
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
@@ -19,12 +20,52 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/component
|
||||
import { LayoutGrid, Boxes, Settings, Home, ChevronRight, Database, Layers, LogOut } from 'lucide-vue-next'
|
||||
|
||||
const { logout } = useAuth()
|
||||
const { api } = useApi()
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout()
|
||||
}
|
||||
|
||||
const menuItems = [
|
||||
// Fetch objects and group by app
|
||||
const apps = ref<any[]>([])
|
||||
const topLevelObjects = ref<any[]>([])
|
||||
const loading = ref(true)
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const response = await api.get('/setup/objects')
|
||||
const allObjects = response.data || response || []
|
||||
|
||||
// Group objects by app
|
||||
const appMap = new Map<string, any>()
|
||||
const noAppObjects: any[] = []
|
||||
|
||||
allObjects.forEach((obj: any) => {
|
||||
if (obj.appId) {
|
||||
if (!appMap.has(obj.appId)) {
|
||||
appMap.set(obj.appId, {
|
||||
id: obj.appId,
|
||||
name: obj.app?.name || obj.app?.label || 'Unknown App',
|
||||
label: obj.app?.label || obj.app?.name || 'Unknown App',
|
||||
objects: []
|
||||
})
|
||||
}
|
||||
appMap.get(obj.appId)!.objects.push(obj)
|
||||
} else {
|
||||
noAppObjects.push(obj)
|
||||
}
|
||||
})
|
||||
|
||||
apps.value = Array.from(appMap.values())
|
||||
topLevelObjects.value = noAppObjects
|
||||
} catch (e) {
|
||||
console.error('Failed to load objects:', e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
const staticMenuItems = [
|
||||
{
|
||||
title: 'Home',
|
||||
url: '/',
|
||||
@@ -46,17 +87,6 @@ const menuItems = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Runtime',
|
||||
icon: Database,
|
||||
items: [
|
||||
{
|
||||
title: 'My Apps',
|
||||
url: '/app',
|
||||
icon: Layers,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
@@ -82,11 +112,12 @@ const menuItems = [
|
||||
</SidebarMenu>
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
<!-- Static Menu Items -->
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Application</SidebarGroupLabel>
|
||||
<SidebarGroupLabel>Navigation</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
<template v-for="item in menuItems" :key="item.title">
|
||||
<template v-for="item in staticMenuItems" :key="item.title">
|
||||
<!-- Simple menu item -->
|
||||
<SidebarMenuItem v-if="!item.items">
|
||||
<SidebarMenuButton as-child>
|
||||
@@ -127,6 +158,63 @@ const menuItems = [
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
|
||||
<!-- Top-level Objects (no app) -->
|
||||
<SidebarGroup v-if="!loading && topLevelObjects.length > 0">
|
||||
<SidebarGroupLabel>Objects</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem v-for="obj in topLevelObjects" :key="obj.id">
|
||||
<SidebarMenuButton as-child>
|
||||
<NuxtLink :to="`/${obj.apiName.toLowerCase()}`">
|
||||
<Database class="h-4 w-4" />
|
||||
<span>{{ obj.label || obj.apiName }}</span>
|
||||
</NuxtLink>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
|
||||
<!-- App-grouped Objects -->
|
||||
<SidebarGroup v-if="!loading && apps.length > 0">
|
||||
<SidebarGroupLabel>Apps</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
<Collapsible
|
||||
v-for="app in apps"
|
||||
:key="app.id"
|
||||
as-child
|
||||
:default-open="true"
|
||||
class="group/collapsible"
|
||||
>
|
||||
<SidebarMenuItem>
|
||||
<CollapsibleTrigger as-child>
|
||||
<SidebarMenuButton :tooltip="app.label">
|
||||
<LayoutGrid class="h-4 w-4" />
|
||||
<span>{{ app.label }}</span>
|
||||
<ChevronRight
|
||||
class="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
|
||||
/>
|
||||
</SidebarMenuButton>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<SidebarMenuSub>
|
||||
<SidebarMenuSubItem v-for="obj in app.objects" :key="obj.id">
|
||||
<SidebarMenuSubButton as-child>
|
||||
<NuxtLink :to="`/${obj.apiName.toLowerCase()}`">
|
||||
<Database class="h-4 w-4" />
|
||||
<span>{{ obj.label || obj.apiName }}</span>
|
||||
</NuxtLink>
|
||||
</SidebarMenuSubButton>
|
||||
</SidebarMenuSubItem>
|
||||
</SidebarMenuSub>
|
||||
</CollapsibleContent>
|
||||
</SidebarMenuItem>
|
||||
</Collapsible>
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
</SidebarContent>
|
||||
<SidebarFooter>
|
||||
<SidebarMenu>
|
||||
|
||||
Reference in New Issue
Block a user