()
| 33 | * it via the `show-schema-viewer` event on `sqlEditorEvents`. |
| 34 | */ |
| 35 | export function AsidePanel() { |
| 36 | const { t } = useTranslation(); |
| 37 | const maybeSwitchProject = useSQLEditorStore((s) => s.maybeSwitchProject); |
| 38 | |
| 39 | const asidePanelTab = useSQLEditorStore((s) => s.asidePanelTab); |
| 40 | const isDisconnected = useIsDisconnected(); |
| 41 | const project = useSQLEditorEditorState((s) => s.project); |
| 42 | const projectContextReady = useSQLEditorEditorState( |
| 43 | (s) => s.projectContextReady |
| 44 | ); |
| 45 | |
| 46 | const defaultProjectName = useAppStore( |
| 47 | (s) => s.serverInfo?.defaultProject ?? "" |
| 48 | ); |
| 49 | // Self-fetch workspace permission state — the SQL editor route doesn't |
| 50 | // mount the dashboard shells that hydrate roles + workspace IAM, so the |
| 51 | // permission selectors below would otherwise read empty state. |
| 52 | const loadWorkspacePermissionState = useAppStore( |
| 53 | (s) => s.loadWorkspacePermissionState |
| 54 | ); |
| 55 | useEffect(() => { |
| 56 | void loadWorkspacePermissionState(); |
| 57 | }, [loadWorkspacePermissionState]); |
| 58 | const allowAccessDefaultProject = useAppStore((s) => |
| 59 | s.hasProjectPermission( |
| 60 | defaultProject(defaultProjectName), |
| 61 | "bb.projects.get" |
| 62 | ) |
| 63 | ); |
| 64 | const allowCreateProject = useAppStore((s) => |
| 65 | s.hasWorkspacePermission("bb.projects.create") |
| 66 | ); |
| 67 | |
| 68 | const handleSwitchProject = useCallback( |
| 69 | (name: string) => { |
| 70 | if (!name || !isValidProjectName(name)) { |
| 71 | getSQLEditorEditorState().setProject(""); |
| 72 | } else { |
| 73 | void maybeSwitchProject(name); |
| 74 | } |
| 75 | }, |
| 76 | [maybeSwitchProject] |
| 77 | ); |
| 78 | |
| 79 | // Vue's `<template #empty>` — rich empty state when the user is not |
| 80 | // a member of any project. Shows a "go to create" link when the user |
| 81 | // has `bb.projects.create`, or an "ask the admin" hint otherwise. |
| 82 | const emptyContent = ( |
| 83 | <div className="text-sm text-control-placeholder flex flex-col gap-1"> |
| 84 | <p> |
| 85 | {t("sql-editor.no-project.not-member-of-any-projects")}{" "} |
| 86 | {allowCreateProject ? ( |
| 87 | <RouterLink |
| 88 | to={{ name: PROJECT_V1_ROUTE_DASHBOARD, hash: "#new" }} |
| 89 | className="text-accent hover:underline" |
| 90 | > |
| 91 | {t("sql-editor.no-project.go-to-create")} |
| 92 | </RouterLink> |
nothing calls this directly
no test coverage detected