Skip to content

Commit 401468e

Browse files
authored
feat: add useDashboardOrganizationId hook (#339)
1 parent 026dd26 commit 401468e

File tree

7 files changed

+97
-1
lines changed

7 files changed

+97
-1
lines changed

apps/kitchensink-react/src/AppRoutes.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Home from './Home'
1616
import {ProjectAuthHome} from './ProjectAuthentication/ProjectAuthHome'
1717
import {ProjectInstanceWrapper} from './ProjectAuthentication/ProjectInstanceWrapper'
1818
import {ProtectedRoute} from './ProtectedRoute'
19+
import {DashboardContextRoute} from './routes/DashboardContextRoute'
1920
import {UsersRoute} from './routes/UsersRoute'
2021
import {UnauthenticatedHome} from './Unauthenticated/UnauthenticatedHome'
2122
import {UnauthenticatedInstanceWrapper} from './Unauthenticated/UnauthenticatedInstanceWrapper'
@@ -53,6 +54,10 @@ const documentCollectionRoutes = [
5354
path: 'document-core-interactions',
5455
element: <DocumentCoreInteractionsRoute />,
5556
},
57+
{
58+
path: 'dashboard-context',
59+
element: <DashboardContextRoute />,
60+
},
5661
]
5762

5863
const frameRoutes = [1, 2, 3].map((frameNum) => ({
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {useDashboardOrganizationId} from '@sanity/sdk-react'
2+
import {Box, Heading, Text} from '@sanity/ui'
3+
import {type JSX} from 'react'
4+
5+
export function DashboardContextRoute(): JSX.Element {
6+
const orgId = useDashboardOrganizationId()
7+
8+
return (
9+
<Box padding={4}>
10+
<Heading as="h1" size={5}>
11+
Dashboard Context
12+
</Heading>
13+
<Box paddingY={5}>
14+
<Text>Organization ID: {orgId}</Text>
15+
</Box>
16+
</Box>
17+
)
18+
}

packages/core/src/_exports/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export {
1515
type ErrorAuthState,
1616
getAuthState,
1717
getCurrentUserState,
18+
getDashboardOrganizationId,
1819
getLoginUrlsState,
1920
getTokenState,
2021
type LoggedInAuthState,

packages/core/src/auth/authStore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export interface AuthConfig {
131131
export interface DashboardContext {
132132
mode?: string
133133
env?: string
134-
orgId?: string | object
134+
orgId?: string
135135
}
136136

137137
let tokenRefresherRunning = false

packages/react/src/_exports/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export {SanityProvider} from '../context/SanityProvider'
66
export {useAuthState} from '../hooks/auth/useAuthState'
77
export {useAuthToken} from '../hooks/auth/useAuthToken'
88
export {useCurrentUser} from '../hooks/auth/useCurrentUser'
9+
export {useDashboardOrganizationId} from '../hooks/auth/useDashboardOrganizationId'
910
export {useHandleCallback} from '../hooks/auth/useHandleCallback'
1011
export {useLoginUrls} from '../hooks/auth/useLoginUrls'
1112
export {useLogOut} from '../hooks/auth/useLogOut'
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import {createSanityInstance, getDashboardOrganizationId} from '@sanity/sdk'
2+
import {renderHook} from '@testing-library/react'
3+
import {throwError} from 'rxjs'
4+
import {describe, expect, it, vi} from 'vitest'
5+
6+
import {useDashboardOrganizationId} from './useDashboardOrganizationId'
7+
8+
vi.mock('../context/useSanityInstance', () => ({
9+
useSanityInstance: vi.fn().mockReturnValue(createSanityInstance({projectId: 'p', dataset: 'd'})),
10+
}))
11+
12+
vi.mock('@sanity/sdk', async (importOriginal) => {
13+
const actual = await importOriginal()
14+
return {...(actual || {}), getDashboardOrganizationId: vi.fn()}
15+
})
16+
17+
describe('useDashboardOrganizationId', () => {
18+
it('should return undefined when no organization ID is set', () => {
19+
const subscribe = vi.fn()
20+
vi.mocked(getDashboardOrganizationId).mockReturnValue({
21+
getCurrent: () => undefined,
22+
subscribe,
23+
observable: throwError(() => new Error('Unexpected usage of observable')),
24+
})
25+
26+
const {result} = renderHook(() => useDashboardOrganizationId())
27+
expect(result.current).toBeUndefined()
28+
})
29+
30+
it('should return organization ID when one is set', () => {
31+
const subscribe = vi.fn()
32+
const mockOrgId = 'team_123'
33+
vi.mocked(getDashboardOrganizationId).mockReturnValue({
34+
getCurrent: () => mockOrgId,
35+
subscribe,
36+
observable: throwError(() => new Error('Unexpected usage of observable')),
37+
})
38+
39+
const {result} = renderHook(() => useDashboardOrganizationId())
40+
expect(result.current).toBe(mockOrgId)
41+
})
42+
})
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import {getDashboardOrganizationId} from '@sanity/sdk'
2+
import {useMemo, useSyncExternalStore} from 'react'
3+
4+
import {useSanityInstance} from '../context/useSanityInstance'
5+
6+
/**
7+
* @remarks
8+
* A React hook that retrieves the dashboard organization ID that is currently selected in the Sanity Dashboard.
9+
*
10+
* @example
11+
* ```tsx
12+
* function DashboardComponent() {
13+
* const orgId = useDashboardOrganizationId()
14+
*
15+
* if (!orgId) return null
16+
*
17+
* return <div>Organization ID: {String(orgId)}</div>
18+
* }
19+
* ```
20+
*
21+
* @returns The dashboard organization ID (string | undefined)
22+
* @public
23+
*/
24+
export function useDashboardOrganizationId(): string | undefined {
25+
const instance = useSanityInstance()
26+
const {subscribe, getCurrent} = useMemo(() => getDashboardOrganizationId(instance), [instance])
27+
28+
return useSyncExternalStore(subscribe, getCurrent)
29+
}

0 commit comments

Comments
 (0)