diff --git a/apps/shelve/app/components/CommandPalette.vue b/apps/shelve/app/components/CommandPalette.vue index 85279cb1..80e31070 100644 --- a/apps/shelve/app/components/CommandPalette.vue +++ b/apps/shelve/app/components/CommandPalette.vue @@ -267,6 +267,9 @@ function playAction(item: CommandItem, index: number) { + + {{ item.suffix }} + { + try { + const projects = useProjects(team.slug) + if (!projects.value || projects.value.length === 0) { + projects.value = await $fetch(`/api/teams/${team.slug}/projects`) + } + } catch (error) { + console.error(`Failed to fetch projects for ${team.slug}:`, error) + } + })) + } + + // Eagerly fetch projects when teams are available + watch(teams, (newTeams) => { + if (newTeams && newTeams.length > 0) { + fetchAllProjects() + } + }, { immediate: true }) + // Submenu state const subMenuState = reactive({ active: false, @@ -252,6 +275,40 @@ export function useAppCommands() { })) }) + // Project commands - all projects from all teams + const projectCommands = computed(() => { + if (!teams.value || teams.value.length === 0) return [] + + const currentTeamSlug = getTeamSlug() + const allProjects: CommandItem[] = [] + + // useProjects returns useState keyed by slug - safe to call in computed + for (const team of teams.value) { + const projects = useProjects(team.slug) + if (!projects.value || projects.value.length === 0) continue + + const isCurrentTeam = team.slug === currentTeamSlug + for (const project of projects.value) { + allProjects.push({ + id: `project-${project.id}`, + label: project.name, + icon: project.logo || 'lucide:folder', + isAvatar: Boolean(project.logo), + suffix: isCurrentTeam ? undefined : team.name, + description: isCurrentTeam ? undefined : `in ${team.name}`, + action: () => navigateTo(`/${team.slug}/projects/${project.id}`), + keywords: ['project', 'switch', project.name, team.name], + active: route.params.projectId === String(project.id), + }) + } + } + + // Hide if only 1 project total + if (allProjects.length <= 1) return [] + + return allProjects + }) + // Help & Support commands const helpCommands = computed(() => [ { @@ -346,6 +403,15 @@ export function useAppCommands() { }) } + // Only show projects if available + if (projectCommands.value.length > 0) { + groups.push({ + id: 'projects', + label: 'Projects', + items: projectCommands.value + }) + } + // Only show navigation if we have teams if (teams.value && teams.value.length > 0) { groups.push({ diff --git a/packages/types/src/Command.ts b/packages/types/src/Command.ts index afc3ce53..d467151f 100644 --- a/packages/types/src/Command.ts +++ b/packages/types/src/Command.ts @@ -4,6 +4,7 @@ export interface CommandItem { icon: string isAvatar?: boolean description?: string + suffix?: string action?: () => void | Promise keywords?: string[] active?: boolean