Added better display of bread crums and side bar menus for apps and objects

This commit is contained in:
Francisco Gaona
2025-12-22 11:01:53 +01:00
parent db9848cce7
commit be6e34914e
8 changed files with 224 additions and 7 deletions

View File

@@ -41,16 +41,17 @@ onMounted(async () => {
const noAppObjects: any[] = []
allObjects.forEach((obj: any) => {
if (obj.appId) {
if (!appMap.has(obj.appId)) {
appMap.set(obj.appId, {
id: obj.appId,
const appId = obj.app_id || obj.appId
if (appId) {
if (!appMap.has(appId)) {
appMap.set(appId, {
id: 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)
appMap.get(appId)!.objects.push(obj)
} else {
noAppObjects.push(obj)
}

View File

@@ -0,0 +1,20 @@
import { ref } from 'vue'
// Shared state for breadcrumbs
const customBreadcrumbs = ref<Array<{ name: string; path?: string; isLast?: boolean }>>([])
export function useBreadcrumbs() {
const setBreadcrumbs = (crumbs: Array<{ name: string; path?: string; isLast?: boolean }>) => {
customBreadcrumbs.value = crumbs
}
const clearBreadcrumbs = () => {
customBreadcrumbs.value = []
}
return {
breadcrumbs: customBreadcrumbs,
setBreadcrumbs,
clearBreadcrumbs
}
}

View File

@@ -1,4 +1,5 @@
<script setup lang="ts">
import { ref } from 'vue'
import AppSidebar from '@/components/AppSidebar.vue'
import AIChatBar from '@/components/AIChatBar.vue'
import {
@@ -13,8 +14,15 @@ import { Separator } from '@/components/ui/separator'
import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'
const route = useRoute()
const { breadcrumbs: customBreadcrumbs } = useBreadcrumbs()
const breadcrumbs = computed(() => {
// If custom breadcrumbs are set by the page, use those
if (customBreadcrumbs.value.length > 0) {
return customBreadcrumbs.value
}
// Otherwise, fall back to URL-based breadcrumbs
const paths = route.path.split('/').filter(Boolean)
return paths.map((path, index) => ({
name: path.charAt(0).toUpperCase() + path.slice(1),

View File

@@ -12,6 +12,9 @@ const router = useRouter()
const { api } = useApi()
const { buildListViewConfig, buildDetailViewConfig, buildEditViewConfig } = useFields()
// Use breadcrumbs composable
const { setBreadcrumbs } = useBreadcrumbs()
// Get object API name from route (case-insensitive)
const objectApiName = computed(() => {
const name = route.params.objectName as string
@@ -45,6 +48,59 @@ const {
handleSave,
} = useViewState(`/runtime/objects/${objectApiName.value}/records`)
// Compute breadcrumbs based on the current route and object data
const updateBreadcrumbs = () => {
if (!objectDefinition.value) {
return
}
const crumbs: Array<{ name: string; path?: string; isLast?: boolean }> = []
// Add app breadcrumb if object belongs to an app
if (objectDefinition.value?.app) {
crumbs.push({
name: objectDefinition.value.app.label || objectDefinition.value.app.name,
path: undefined, // No path for app grouping
})
}
// Add object breadcrumb - always use plural
const objectLabel = objectDefinition.value?.pluralLabel || objectDefinition.value?.label || objectApiName.value
crumbs.push({
name: objectLabel,
path: `/${objectApiName.value.toLowerCase()}`,
})
// Add record name if viewing/editing a specific record
if (recordId.value && recordId.value !== 'new' && currentRecord.value) {
const nameField = objectDefinition.value?.nameField
let recordName = recordId.value // fallback to ID
// Try to get the display name from the nameField
if (nameField && currentRecord.value[nameField]) {
recordName = currentRecord.value[nameField]
}
crumbs.push({
name: recordName,
isLast: true,
})
} else if (recordId.value === 'new') {
crumbs.push({
name: 'New',
isLast: true,
})
}
setBreadcrumbs(crumbs)
}
// Watch for changes that affect breadcrumbs
watch([objectDefinition, currentRecord, recordId], () => {
updateBreadcrumbs()
}, { deep: true })
// View configs
const listConfig = computed(() => {
if (!objectDefinition.value) return null
@@ -162,6 +218,9 @@ onMounted(async () => {
} else if (recordId.value && recordId.value !== 'new') {
await fetchRecord(recordId.value)
}
// Update breadcrumbs after data is loaded
updateBreadcrumbs()
})
</script>