fix(web): реактивно переключать пространство через SpaceProvider
Docker / build (push) Failing after 18s
Docker / build (push) Failing after 18s
localStorage не вызывал re-render; useSpaceId + remount main по spaceId. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -57,6 +57,7 @@ import {
|
||||
can,
|
||||
permissionForPath,
|
||||
} from '@/lib/auth'
|
||||
import { SpaceProvider, useSpaceId } from '@/lib/space'
|
||||
|
||||
interface NavItem {
|
||||
to: string
|
||||
@@ -162,6 +163,7 @@ export function AppShell({ children }: { children: ReactNode }) {
|
||||
})).filter((g) => g.items.length > 0)
|
||||
|
||||
return (
|
||||
<SpaceProvider>
|
||||
<TooltipProvider delay={0}>
|
||||
<SidebarProvider
|
||||
style={
|
||||
@@ -247,11 +249,22 @@ export function AppShell({ children }: { children: ReactNode }) {
|
||||
</div>
|
||||
</header>
|
||||
<main className="flex flex-1 flex-col gap-4 px-4 py-4 md:gap-6 md:px-6 md:py-5">
|
||||
{children}
|
||||
<SpaceScopedMain>{children}</SpaceScopedMain>
|
||||
</main>
|
||||
</SidebarInset>
|
||||
<GlobalSearch open={searchOpen} onOpenChange={setSearchOpen} />
|
||||
</SidebarProvider>
|
||||
</TooltipProvider>
|
||||
</SpaceProvider>
|
||||
)
|
||||
}
|
||||
|
||||
/** Remount route content when space changes so snapshot queries pick new X-Space-Id. */
|
||||
function SpaceScopedMain({ children }: { children: ReactNode }) {
|
||||
const { spaceId } = useSpaceId()
|
||||
return (
|
||||
<div key={spaceId ?? 'default'} className="flex flex-1 flex-col gap-4 md:gap-6">
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -30,26 +30,28 @@ import {
|
||||
} from '@cfdm/ui/components/sidebar'
|
||||
|
||||
import { api } from '@/lib/api-client'
|
||||
import { getStoredSpaceId, setStoredSpaceId, type SpaceDto } from '@/lib/space'
|
||||
import { useSpaceId, type SpaceDto } from '@/lib/space'
|
||||
import { spacesKeys, spacesQueryOptions, snapshotKeys } from '@/queries/snapshot'
|
||||
|
||||
export function SpaceSwitcher() {
|
||||
const { isMobile } = useSidebar()
|
||||
const qc = useQueryClient()
|
||||
const { spaceId, setSpaceId } = useSpaceId()
|
||||
const { data: spaces = [] } = useQuery(spacesQueryOptions())
|
||||
const currentId = getStoredSpaceId() ?? spaces[0]?.id
|
||||
const currentId = spaceId ?? spaces[0]?.id
|
||||
const current = spaces.find((s) => s.id === currentId) ?? spaces[0]
|
||||
const [createOpen, setCreateOpen] = useState(false)
|
||||
const [name, setName] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
if (!getStoredSpaceId() && spaces[0]?.id) {
|
||||
setStoredSpaceId(spaces[0].id)
|
||||
if (!spaceId && spaces[0]?.id) {
|
||||
setSpaceId(spaces[0].id)
|
||||
}
|
||||
}, [spaces])
|
||||
}, [spaceId, spaces, setSpaceId])
|
||||
|
||||
function selectSpace(space: SpaceDto) {
|
||||
setStoredSpaceId(space.id)
|
||||
if (space.id === currentId) return
|
||||
setSpaceId(space.id)
|
||||
void qc.invalidateQueries({ queryKey: snapshotKeys.all })
|
||||
void qc.invalidateQueries({ queryKey: spacesKeys.all })
|
||||
toast.success(`Пространство: ${space.name}`)
|
||||
@@ -64,7 +66,7 @@ export function SpaceSwitcher() {
|
||||
if (!n) return
|
||||
try {
|
||||
const created = await api.createSpace({ name: n })
|
||||
setStoredSpaceId(created.id)
|
||||
setSpaceId(created.id)
|
||||
setCreateOpen(false)
|
||||
setName('')
|
||||
await qc.invalidateQueries({ queryKey: spacesKeys.all })
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
} from '@cfdm/ui/components/sheet'
|
||||
|
||||
import { api } from '@/lib/api-client'
|
||||
import { getStoredSpaceId } from '@/lib/space'
|
||||
import { useSpaceId } from '@/lib/space'
|
||||
import { spacesQueryOptions, snapshotKeys } from '@/queries/snapshot'
|
||||
import type { Vps } from '@/types/entities'
|
||||
|
||||
@@ -33,8 +33,9 @@ type Props = {
|
||||
|
||||
export function VpsAccessSheet({ vps, open, onOpenChange }: Props) {
|
||||
const qc = useQueryClient()
|
||||
const { spaceId } = useSpaceId()
|
||||
const { data: spaces = [] } = useQuery(spacesQueryOptions())
|
||||
const fromSpaceId = getStoredSpaceId() ?? spaces.find((s) => s.kind === 'main')?.id ?? ''
|
||||
const fromSpaceId = spaceId ?? spaces.find((s) => s.kind === 'main')?.id ?? ''
|
||||
const targets = spaces.filter((s) => s.id !== fromSpaceId)
|
||||
const [toSpaceId, setToSpaceId] = useState('')
|
||||
const [permission, setPermission] = useState<'read' | 'write'>('read')
|
||||
|
||||
Reference in New Issue
Block a user