mirror of
https://github.com/supabase/supabase.git
synced 2026-10-11 20:35:07 +03:00
remove dashboard/
This commit is contained in:
61 files changed
+166
-28
No files matched your search
File renamed without changes.
+1
-1
@@ -6,6 +6,6 @@ export default async function V2OrgProjectPage({
|
||||
params: Promise<{ projectRef: string }>
|
||||
}) {
|
||||
const { projectRef } = await params
|
||||
redirect(`/dashboard/v2/project/${projectRef}`)
|
||||
redirect(`/v2/project/${projectRef}`)
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ function OrgDashboardContent() {
|
||||
{projects.map((proj) => (
|
||||
<li key={proj.ref}>
|
||||
<Link
|
||||
href={`/dashboard/v2/project/${proj.ref}`}
|
||||
href={`/v2/project/${proj.ref}`}
|
||||
className="text-sm text-foreground hover:underline"
|
||||
>
|
||||
{proj.name}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -21,7 +21,7 @@ export default function TableDetailLayout({ children }: { children: React.ReactN
|
||||
const { projectRef } = useV2Params()
|
||||
const tableId = params?.tableId as string
|
||||
|
||||
const base = projectRef ? `/dashboard/v2/project/${projectRef}/data/tables/${tableId}` : ''
|
||||
const base = projectRef ? `/v2/project/${projectRef}/data/tables/${tableId}` : ''
|
||||
|
||||
return (
|
||||
<StudioDataWorkspace projectRef={projectRef} id={tableId}>
|
||||
+1
-1
@@ -6,5 +6,5 @@ export default async function TableDetailPage({
|
||||
params: Promise<{ projectRef: string; tableId: string }>
|
||||
}) {
|
||||
const { projectRef, tableId } = await params
|
||||
redirect(`/dashboard/v2/project/${projectRef}/data/tables/${tableId}/data`)
|
||||
redirect(`/v2/project/${projectRef}/data/tables/${tableId}/data`)
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,138 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useParams, useRouter } from 'next/navigation'
|
||||
import { Building2, ChevronRight, Search } from 'lucide-react'
|
||||
|
||||
import { useOrganizationsQuery } from 'data/organizations/organizations-query'
|
||||
import { useOrgProjectsInfiniteQuery } from 'data/projects/org-projects-infinite-query'
|
||||
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
|
||||
|
||||
/**
|
||||
* Disambiguation page for /v2/project/_/[...routeSlug].
|
||||
*
|
||||
* The literal `_` segment can never collide with a real project ref, so any
|
||||
* link that doesn't yet know the target project (e.g. deep-links from docs or
|
||||
* CLI output) can point here. The user picks a project and is forwarded to
|
||||
* /v2/project/[projectRef]/[...routeSlug] with the same sub-path preserved.
|
||||
*/
|
||||
export default function V2ProjectDisambiguationPage() {
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
const routeSlug = params?.routeSlug as string[] | undefined
|
||||
|
||||
const subPath = routeSlug?.length ? `/${routeSlug.join('/')}` : '/data/tables'
|
||||
|
||||
const { data: organizations = [], isPending: isLoadingOrgs } = useOrganizationsQuery()
|
||||
const [selectedOrgSlug, setSelectedOrgSlug] = useState<string | undefined>(undefined)
|
||||
const activeOrg =
|
||||
organizations.find((o) => o.slug === selectedOrgSlug) ?? organizations[0]
|
||||
|
||||
const [search, setSearch] = useState('')
|
||||
|
||||
const { data: projectsData, isPending: isLoadingProjects } = useOrgProjectsInfiniteQuery(
|
||||
{ slug: activeOrg?.slug, limit: 50 },
|
||||
{ enabled: Boolean(activeOrg?.slug) }
|
||||
)
|
||||
const allProjects = projectsData?.pages?.flatMap((p) => p.projects) ?? []
|
||||
const projects = search.trim()
|
||||
? allProjects.filter((p) => p.name.toLowerCase().includes(search.toLowerCase()))
|
||||
: allProjects
|
||||
|
||||
const handleSelectProject = (ref: string) => {
|
||||
router.push(`/v2/project/${ref}${subPath}`)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-screen bg-background">
|
||||
{/* Header */}
|
||||
<div className="px-8 py-6 border-b border-border">
|
||||
<h1 className="text-xl font-semibold text-foreground">Select a project</h1>
|
||||
{subPath !== '/data/tables' && (
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
You'll be taken to <span className="font-mono text-xs">{subPath}</span> after selecting.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 min-h-0">
|
||||
{/* Org sidebar */}
|
||||
<aside className="w-56 shrink-0 border-r border-border overflow-y-auto py-2">
|
||||
{isLoadingOrgs ? (
|
||||
<div className="space-y-1 px-3 py-2">
|
||||
<ShimmeringLoader className="h-7" />
|
||||
<ShimmeringLoader className="h-7 w-4/5" />
|
||||
</div>
|
||||
) : (
|
||||
organizations.map((org) => {
|
||||
const isActive = org.slug === (activeOrg?.slug)
|
||||
return (
|
||||
<button
|
||||
key={org.slug}
|
||||
type="button"
|
||||
onClick={() => setSelectedOrgSlug(org.slug)}
|
||||
className={`w-full flex items-center gap-2.5 px-3 py-2 text-sm text-left transition-colors ${
|
||||
isActive
|
||||
? 'bg-sidebar-accent text-foreground font-medium'
|
||||
: 'text-muted-foreground hover:text-foreground hover:bg-sidebar-accent/50'
|
||||
}`}
|
||||
>
|
||||
<Building2 className="h-3.5 w-3.5 shrink-0" strokeWidth={1.5} />
|
||||
<span className="truncate">{org.name}</span>
|
||||
</button>
|
||||
)
|
||||
})
|
||||
)}
|
||||
</aside>
|
||||
|
||||
{/* Project list */}
|
||||
<main className="flex-1 min-w-0 flex flex-col overflow-hidden">
|
||||
<div className="px-4 py-3 border-b border-border shrink-0">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search projects…"
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
className="w-full pl-8 pr-3 py-1.5 text-sm bg-background border border-border rounded-md focus:outline-none focus:ring-1 focus:ring-foreground/30 placeholder:text-muted-foreground"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{isLoadingProjects ? (
|
||||
<div className="space-y-1 p-4">
|
||||
<ShimmeringLoader className="h-10" />
|
||||
<ShimmeringLoader className="h-10 w-4/5" />
|
||||
<ShimmeringLoader className="h-10 w-3/5" />
|
||||
</div>
|
||||
) : projects.length === 0 ? (
|
||||
<div className="flex items-center justify-center h-32 text-sm text-muted-foreground">
|
||||
{search ? 'No projects match your search.' : 'No projects in this organization.'}
|
||||
</div>
|
||||
) : (
|
||||
<ul className="divide-y divide-border">
|
||||
{projects.map((project) => (
|
||||
<li key={project.ref}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleSelectProject(project.ref)}
|
||||
className="w-full flex items-center justify-between px-5 py-3.5 text-left hover:bg-sidebar-accent/50 transition-colors group"
|
||||
>
|
||||
<div>
|
||||
<div className="text-sm font-medium text-foreground">{project.name}</div>
|
||||
<div className="text-xs text-muted-foreground font-mono">{project.ref}</div>
|
||||
</div>
|
||||
<ChevronRight className="h-4 w-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity shrink-0" />
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -66,7 +66,7 @@ export const TableGridEditor = ({
|
||||
const onTableCreated = useCallback(
|
||||
(table: { id: number }) => {
|
||||
if (variant === 'v2') {
|
||||
const base = projectRef ? `/dashboard/v2/project/${projectRef}` : ''
|
||||
const base = projectRef ? `/v2/project/${projectRef}` : ''
|
||||
router.push(
|
||||
`${base}/data/tables/${table.id}/data${
|
||||
!!selectedSchema ? `?schema=${selectedSchema}` : ''
|
||||
@@ -95,7 +95,7 @@ export const TableGridEditor = ({
|
||||
tabs.removeTab(tabId)
|
||||
setLastVisitedTable(undefined)
|
||||
|
||||
const base = projectRef ? `/dashboard/v2/project/${projectRef}` : ''
|
||||
const base = projectRef ? `/v2/project/${projectRef}` : ''
|
||||
router.push(`${base}/data/tables`)
|
||||
return
|
||||
}
|
||||
@@ -158,7 +158,7 @@ export const TableGridEditor = ({
|
||||
onClick={() => {
|
||||
tabs.removeTab(tabId)
|
||||
setLastVisitedTable(undefined)
|
||||
const base = projectRef ? `/dashboard/v2/project/${projectRef}` : ''
|
||||
const base = projectRef ? `/v2/project/${projectRef}` : ''
|
||||
router.push(`${base}/data/tables`)
|
||||
}}
|
||||
>
|
||||
@@ -172,7 +172,7 @@ export const TableGridEditor = ({
|
||||
onClick={() => setLastVisitedTable(undefined)}
|
||||
>
|
||||
<Link
|
||||
href={`/dashboard/v2/project/${projectRef}/data/tables/${openTabs[0].split('-')[1]}/data`}
|
||||
href={`/v2/project/${projectRef}/data/tables/${openTabs[0].split('-')[1]}/data`}
|
||||
>
|
||||
Close tab
|
||||
</Link>
|
||||
@@ -184,7 +184,7 @@ export const TableGridEditor = ({
|
||||
className="mt-2"
|
||||
onClick={() => setLastVisitedTable(undefined)}
|
||||
>
|
||||
<Link href={`/dashboard/v2/project/${projectRef}/data/tables`}>Head back</Link>
|
||||
<Link href={`/v2/project/${projectRef}/data/tables`}>Head back</Link>
|
||||
</Button>
|
||||
)
|
||||
) : !!tabId ? (
|
||||
|
||||
@@ -133,8 +133,8 @@ export function LeftActivityBar() {
|
||||
const { data: lints } = useProjectLintsQuery({ projectRef })
|
||||
const hasAdvisorWarnings = (lints?.length ?? 0) > 0
|
||||
|
||||
const base = projectRef ? `/dashboard/v2/project/${projectRef}` : '#'
|
||||
const homeBase = projectRef && orgSlug ? `/dashboard/v2/project/${projectRef}` : '#'
|
||||
const base = projectRef ? `/v2/project/${projectRef}` : '#'
|
||||
const homeBase = projectRef && orgSlug ? `/v2/project/${projectRef}` : '#'
|
||||
|
||||
return (
|
||||
<ActivityBar
|
||||
|
||||
@@ -153,7 +153,7 @@ export function BrowserPanel({ onCollapse }: { onCollapse?: () => void }) {
|
||||
const { expandedGroups, toggleGroup } = useV2DashboardStore()
|
||||
const counts = useV2DataCounts(projectRef)
|
||||
|
||||
const base = projectRef ? `/dashboard/v2/project/${projectRef}` : ''
|
||||
const base = projectRef ? `/v2/project/${projectRef}` : ''
|
||||
const isData = pathname?.includes('/data/')
|
||||
const isObs = pathname?.includes('/obs/')
|
||||
const isSettings = pathname?.includes('/settings/')
|
||||
|
||||
@@ -102,7 +102,7 @@ export function Chooser() {
|
||||
const [search, setSearch] = useState('')
|
||||
const lowerSearch = search.toLowerCase()
|
||||
|
||||
const base = projectRef ? `/dashboard/v2/project/${projectRef}` : ''
|
||||
const base = projectRef ? `/v2/project/${projectRef}` : ''
|
||||
|
||||
const openCategory = (category: string) => {
|
||||
const domain = CATEGORY_DOMAIN[category] ?? 'db'
|
||||
|
||||
@@ -31,7 +31,7 @@ export function DataTabBar() {
|
||||
|
||||
// Don't render the bar at all when there are no detail tabs
|
||||
if (detailTabs.length === 0) return null
|
||||
const chooserPath = projectRef ? `/dashboard/v2/project/${projectRef}/data` : '#'
|
||||
const chooserPath = projectRef ? `/v2/project/${projectRef}/data` : '#'
|
||||
|
||||
const handleClose = (tab: DataTab, e: React.MouseEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
@@ -269,19 +269,19 @@ export function HomeView() {
|
||||
{[
|
||||
{
|
||||
title: '+ New table',
|
||||
href: projectRef ? `/dashboard/v2/project/${projectRef}/data/tables` : '#',
|
||||
href: projectRef ? `/v2/project/${projectRef}/data/tables` : '#',
|
||||
},
|
||||
{
|
||||
title: '+ New bucket',
|
||||
href: projectRef ? `/dashboard/v2/project/${projectRef}/data/buckets` : '#',
|
||||
href: projectRef ? `/v2/project/${projectRef}/data/buckets` : '#',
|
||||
},
|
||||
{
|
||||
title: '+ New function',
|
||||
href: projectRef ? `/dashboard/v2/project/${projectRef}/data/edge-functions` : '#',
|
||||
href: projectRef ? `/v2/project/${projectRef}/data/edge-functions` : '#',
|
||||
},
|
||||
{
|
||||
title: '+ Add user',
|
||||
href: projectRef ? `/dashboard/v2/project/${projectRef}/data/users` : '#',
|
||||
href: projectRef ? `/v2/project/${projectRef}/data/users` : '#',
|
||||
},
|
||||
].map((a) => (
|
||||
<button
|
||||
|
||||
@@ -101,7 +101,7 @@ export function ProjectBranchSelectorPopover({ onClose }: ProjectBranchSelectorP
|
||||
projectCreationEnabled={projectCreationEnabled}
|
||||
onSelect={(ref) => {
|
||||
onClose()
|
||||
router.push(`/dashboard/v2/project/${ref}/data/tables`)
|
||||
router.push(`/v2/project/${ref}/data/tables`)
|
||||
}}
|
||||
onClose={onClose}
|
||||
/>
|
||||
@@ -112,7 +112,7 @@ export function ProjectBranchSelectorPopover({ onClose }: ProjectBranchSelectorP
|
||||
isBranchesLoaded={isBranchesSuccess}
|
||||
onSelect={(branch) => {
|
||||
onClose()
|
||||
router.push(`/dashboard/v2/project/${branch.project_ref}/data/tables`)
|
||||
router.push(`/v2/project/${branch.project_ref}/data/tables`)
|
||||
}}
|
||||
onCreateBranch={() => {
|
||||
onClose()
|
||||
@@ -120,7 +120,7 @@ export function ProjectBranchSelectorPopover({ onClose }: ProjectBranchSelectorP
|
||||
}}
|
||||
onManageBranches={() => {
|
||||
onClose()
|
||||
router.push(`/dashboard/v2/project/${projectRef}/settings/branches`)
|
||||
router.push(`/v2/project/${projectRef}/settings/branches`)
|
||||
}}
|
||||
onClose={onClose}
|
||||
/>
|
||||
|
||||
@@ -29,7 +29,7 @@ export function TabBar() {
|
||||
const { projectRef } = useV2Params()
|
||||
const { detailTabs, removeDetailTab } = useV2DashboardStore()
|
||||
|
||||
const base = projectRef ? `/dashboard/v2/project/${projectRef}` : ''
|
||||
const base = projectRef ? `/v2/project/${projectRef}` : ''
|
||||
const pathParts = pathname?.replace(/^\/v2\/[^/]+\/[^/]+/, '').split('/').filter(Boolean) ?? []
|
||||
const activity = pathParts[0]
|
||||
const category = pathParts[1]
|
||||
|
||||
@@ -42,13 +42,13 @@ export function V2BranchSelector() {
|
||||
const handleSelectBranch = (ref: string) => {
|
||||
if (!orgSlug) return
|
||||
setOpen(false)
|
||||
router.push(`/dashboard/v2/project/${ref}/data/tables`)
|
||||
router.push(`/v2/project/${ref}/data/tables`)
|
||||
}
|
||||
|
||||
const handleManageBranches = () => {
|
||||
if (!orgSlug || !projectRef) return
|
||||
setOpen(false)
|
||||
router.push(`/dashboard/v2/project/${projectRef}/settings/branches`)
|
||||
router.push(`/v2/project/${projectRef}/settings/branches`)
|
||||
}
|
||||
|
||||
if (!IS_PLATFORM) {
|
||||
|
||||
@@ -40,12 +40,12 @@ export function V2OrgProjectSelector() {
|
||||
const handleSelectProject = (ref: string) => {
|
||||
if (!orgSlug) return
|
||||
setOpen(false)
|
||||
router.push(`/dashboard/v2/project/${ref}/data/tables`)
|
||||
router.push(`/v2/project/${ref}/data/tables`)
|
||||
}
|
||||
|
||||
const handleSelectOrg = (slug: string) => {
|
||||
setOpen(false)
|
||||
router.push(`/dashboard/v2/org/${slug}`)
|
||||
router.push(`/v2/org/${slug}`)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -48,7 +48,7 @@ export function V2TableDetailView({ subTab }: { subTab: string }) {
|
||||
type: 'detail',
|
||||
category: 'tables',
|
||||
domain: 'db',
|
||||
path: `/dashboard/v2/project/${projectRef}/data/tables/${tableId}/data`,
|
||||
path: `/v2/project/${projectRef}/data/tables/${tableId}/data`,
|
||||
})
|
||||
}, [table, projectRef, tableId, openDataTab])
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ export function V2TablesList() {
|
||||
return tables.filter((t) => t.name.toLowerCase().includes(q))
|
||||
}, [tables, search])
|
||||
|
||||
const base = projectRef ? `/dashboard/v2/project/${projectRef}` : ''
|
||||
const base = projectRef ? `/v2/project/${projectRef}` : ''
|
||||
|
||||
const openTable = useCallback(
|
||||
(table: PostgresTable) => {
|
||||
|
||||
Reference in new issue
Block a user