@sanity/sdk-react 3.0.0-rc.0 → 3.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -155
- package/dist/index.d.ts +2488 -2019
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4435 -1529
- package/dist/index.js.map +1 -1
- package/package.json +55 -59
- package/src/_exports/index.ts +2 -4
- package/src/_exports/sdk-react.ts +30 -18
- package/src/components/SDKProvider.test.tsx +173 -32
- package/src/components/SDKProvider.tsx +87 -28
- package/src/components/SanityApp.test.tsx +68 -12
- package/src/components/SanityApp.tsx +93 -87
- package/src/components/auth/AuthBoundary.recovery.test.tsx +86 -0
- package/src/components/auth/AuthBoundary.test.tsx +7 -7
- package/src/components/auth/AuthBoundary.tsx +29 -6
- package/src/components/auth/DashboardAccessRequest.tsx +37 -0
- package/src/components/auth/LoginError.test.tsx +191 -5
- package/src/components/auth/LoginError.tsx +104 -61
- package/src/components/errors/ChunkLoadError.test.tsx +59 -0
- package/src/components/errors/ChunkLoadError.tsx +56 -0
- package/src/components/errors/CorsErrorComponent.tsx +2 -2
- package/src/components/errors/chunkReloadStorage.ts +57 -0
- package/src/config/handles.ts +29 -27
- package/src/constants.ts +5 -0
- package/src/context/ComlinkTokenRefresh.test.tsx +10 -27
- package/src/context/ComlinkTokenRefresh.tsx +3 -5
- package/src/context/DefaultResourceContext.ts +3 -3
- package/src/context/OrganizationResourcesProvider.test.tsx +189 -0
- package/src/context/OrganizationResourcesProvider.tsx +111 -0
- package/src/context/PerspectiveContext.ts +3 -3
- package/src/context/ProjectContext.ts +15 -0
- package/src/context/ResourceProvider.test.tsx +93 -90
- package/src/context/ResourceProvider.tsx +62 -93
- package/src/context/SDKStudioContext.test.tsx +28 -33
- package/src/context/SanityInstanceProvider.test.tsx +100 -0
- package/src/context/SanityInstanceProvider.tsx +71 -0
- package/src/context/WorkbenchTokenRefresh.test.tsx +106 -0
- package/src/context/WorkbenchTokenRefresh.tsx +61 -0
- package/src/context/renderSanityApp.test.tsx +151 -49
- package/src/context/renderSanityApp.tsx +12 -8
- package/src/context/workbenchToken.ts +63 -0
- package/src/hooks/access/useCheckPermissions.test-d.ts +15 -0
- package/src/hooks/access/useCheckPermissions.test.tsx +53 -0
- package/src/hooks/access/useCheckPermissions.ts +24 -0
- package/src/hooks/agent/agentActions.test.tsx +2 -2
- package/src/hooks/agent/agentActions.ts +52 -72
- package/src/hooks/agent/useAgentResourceContext.ts +1 -1
- package/src/hooks/applications/useApplication.test-d.ts +30 -0
- package/src/hooks/applications/useApplication.ts +22 -0
- package/src/hooks/applications/useApplications.test-d.ts +31 -0
- package/src/hooks/applications/useApplications.ts +25 -0
- package/src/hooks/applications/useDeleteApplication.test-d.ts +12 -0
- package/src/hooks/applications/useDeleteApplication.ts +11 -0
- package/src/hooks/applications/useUpdateApplication.test-d.ts +12 -0
- package/src/hooks/applications/useUpdateApplication.ts +11 -0
- package/src/hooks/auth/useDashboardOrganizationId.test.tsx +2 -8
- package/src/hooks/auth/useVerifyOrgProjects.test.tsx +8 -32
- package/src/hooks/auth/useVerifyOrgProjects.tsx +13 -6
- package/src/hooks/client/useClient.test.tsx +1 -4
- package/src/hooks/client/useClient.ts +1 -0
- package/src/hooks/comlink/useFrameConnection.test.tsx +3 -2
- package/src/hooks/comlink/useFrameConnection.ts +1 -1
- package/src/hooks/comlink/useWindowConnection.test.tsx +4 -3
- package/src/hooks/comlink/useWindowConnection.ts +2 -3
- package/src/hooks/comments/useCommentActions.test.tsx +150 -0
- package/src/hooks/comments/useCommentActions.ts +109 -0
- package/src/hooks/comments/useCommentList.ts +79 -0
- package/src/hooks/comments/useCommentThreads.test.tsx +107 -0
- package/src/hooks/comments/useCommentThreads.ts +73 -0
- package/src/hooks/comments/useComments.test.tsx +242 -0
- package/src/hooks/comments/useComments.ts +59 -0
- package/src/hooks/context/useResource.test.tsx +32 -0
- package/src/hooks/context/useResource.ts +24 -0
- package/src/hooks/context/useSanityInstance.test.tsx +18 -1
- package/src/hooks/context/useSanityInstance.ts +6 -6
- package/src/hooks/dashboard/useManageFavorite.test.tsx +110 -46
- package/src/hooks/dashboard/useManageFavorite.ts +11 -17
- package/src/hooks/dashboard/useNavigateToStudioDocument.test.ts +5 -7
- package/src/hooks/dashboard/useNavigateToStudioDocument.ts +2 -6
- package/src/hooks/dashboard/useRecordDocumentHistoryEvent.test.ts +0 -2
- package/src/hooks/dashboard/useRecordDocumentHistoryEvent.ts +2 -2
- package/src/hooks/dashboard/useWindowTitle.test.ts +244 -0
- package/src/hooks/dashboard/useWindowTitle.ts +114 -0
- package/src/hooks/datasets/useDatasets.test.tsx +116 -0
- package/src/hooks/datasets/useDatasets.ts +33 -13
- package/src/hooks/document/useApplyDocumentActions.test.tsx +48 -0
- package/src/hooks/document/useApplyDocumentActions.ts +66 -48
- package/src/hooks/document/useCreateDocument.test.tsx +83 -0
- package/src/hooks/document/useCreateDocument.ts +117 -0
- package/src/hooks/document/useDocument.test.tsx +37 -8
- package/src/hooks/document/useDocument.ts +131 -66
- package/src/hooks/document/useDocumentEvent.test.tsx +16 -4
- package/src/hooks/document/useDocumentEvent.ts +16 -10
- package/src/hooks/document/useDocumentPermissions.test.tsx +8 -7
- package/src/hooks/document/useDocumentPermissions.ts +71 -39
- package/src/hooks/document/useDocumentSyncStatus.test.ts +1 -0
- package/src/hooks/document/useDocumentSyncStatus.ts +13 -9
- package/src/hooks/document/useEditDocument.test.tsx +21 -14
- package/src/hooks/document/useEditDocument.ts +163 -17
- package/src/hooks/documents/useDocuments.test.tsx +64 -44
- package/src/hooks/documents/useDocuments.ts +31 -20
- package/src/hooks/helpers/createCallbackHook.test.tsx +13 -19
- package/src/hooks/helpers/createFetcherHook.test.tsx +180 -0
- package/src/hooks/helpers/createFetcherHook.ts +69 -0
- package/src/hooks/helpers/createMutationHook.test.tsx +125 -0
- package/src/hooks/helpers/createMutationHook.tsx +93 -0
- package/src/hooks/helpers/createStateSourceHook.test.tsx +10 -10
- package/src/hooks/helpers/createStateSourceHook.tsx +2 -1
- package/src/hooks/{document/useApplyDocumentActions.test.ts → helpers/useApplyActions.test.tsx} +92 -53
- package/src/hooks/helpers/useApplyActions.ts +68 -0
- package/src/hooks/helpers/useNormalizedResourceOptions.test.tsx +226 -0
- package/src/hooks/helpers/useNormalizedResourceOptions.ts +79 -48
- package/src/hooks/helpers/useResolvedProjectId.test.tsx +59 -0
- package/src/hooks/helpers/useResolvedProjectId.ts +35 -0
- package/src/hooks/helpers/useTrackHookUsage.ts +37 -0
- package/src/hooks/installations/useInstallation.test-d.ts +19 -0
- package/src/hooks/installations/useInstallation.ts +22 -0
- package/src/hooks/installations/useInstallations.test-d.ts +26 -0
- package/src/hooks/installations/useInstallations.ts +25 -0
- package/src/hooks/organizations/useOrganization.test-d.ts +60 -0
- package/src/hooks/organizations/useOrganization.test.ts +63 -0
- package/src/hooks/organizations/useOrganization.ts +34 -0
- package/src/hooks/organizations/useOrganizations.test-d.ts +68 -0
- package/src/hooks/organizations/useOrganizations.test.ts +63 -0
- package/src/hooks/organizations/useOrganizations.ts +39 -0
- package/src/hooks/paginatedDocuments/usePaginatedDocuments.test.tsx +34 -27
- package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +35 -22
- package/src/hooks/presence/usePresence.test.tsx +0 -15
- package/src/hooks/presence/usePresence.ts +22 -20
- package/src/hooks/presence/usePresenceForDocument.test.tsx +141 -0
- package/src/hooks/presence/usePresenceForDocument.ts +104 -0
- package/src/hooks/presence/useReportPresence.test.tsx +202 -0
- package/src/hooks/presence/useReportPresence.ts +170 -0
- package/src/hooks/preview/useDocumentPreview.test.tsx +0 -1
- package/src/hooks/preview/useDocumentPreview.tsx +12 -14
- package/src/hooks/projection/useDocumentProjection.test.tsx +78 -9
- package/src/hooks/projection/useDocumentProjection.ts +81 -2
- package/src/hooks/projects/useProject.test-d.ts +56 -0
- package/src/hooks/projects/useProject.test.tsx +120 -0
- package/src/hooks/projects/useProject.ts +42 -43
- package/src/hooks/projects/useProjects.test-d.ts +60 -0
- package/src/hooks/projects/useProjects.test.ts +45 -98
- package/src/hooks/projects/useProjects.ts +17 -32
- package/src/hooks/query/useQuery.test.tsx +6 -5
- package/src/hooks/query/useQuery.ts +94 -17
- package/src/hooks/releases/useActiveReleases.test.tsx +13 -7
- package/src/hooks/releases/useActiveReleases.ts +28 -24
- package/src/hooks/releases/useAllReleases.test.tsx +93 -0
- package/src/hooks/releases/useAllReleases.ts +62 -0
- package/src/hooks/releases/useApplyReleaseActions.test.tsx +66 -0
- package/src/hooks/releases/useApplyReleaseActions.ts +82 -0
- package/src/hooks/releases/usePerspective.test.tsx +18 -10
- package/src/hooks/releases/usePerspective.ts +13 -17
- package/src/hooks/users/useUser.test.tsx +3 -9
- package/src/hooks/users/useUser.ts +4 -8
- package/src/hooks/users/useUsers.test.tsx +103 -7
- package/src/hooks/users/useUsers.ts +38 -5
- package/src/utils/resolveOrgResources.test.ts +111 -0
- package/src/utils/resolveOrgResources.ts +69 -0
- package/src/hooks/context/useDefaultResource.test.tsx +0 -25
- package/src/hooks/context/useDefaultResource.ts +0 -30
- package/src/hooks/dashboard/useDispatchIntent.test.ts +0 -254
- package/src/hooks/dashboard/useDispatchIntent.ts +0 -157
- package/src/hooks/dashboard/utils/useResourceIdFromDocumentHandle.test.ts +0 -107
- package/src/hooks/dashboard/utils/useResourceIdFromDocumentHandle.ts +0 -39
- package/src/hooks/datasets/useDatasets.test.ts +0 -66
- package/src/hooks/helpers/useNormalizedResourceOptions.test.ts +0 -65
- package/src/hooks/projects/useProject.test.ts +0 -79
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
import {type Message} from '@sanity/comlink'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
getFavoritesState,
|
|
5
|
-
resolveFavoritesState,
|
|
6
|
-
type SanityInstance,
|
|
7
|
-
} from '@sanity/sdk'
|
|
2
|
+
import {type FavoriteStatusResponse, getFavoritesState, resolveFavoritesState} from '@sanity/sdk'
|
|
3
|
+
import {act, renderHook} from '@testing-library/react'
|
|
8
4
|
import {BehaviorSubject} from 'rxjs'
|
|
9
|
-
import {beforeEach, describe, expect, it, vi} from 'vitest'
|
|
5
|
+
import {beforeEach, describe, expect, it, type Mock, vi} from 'vitest'
|
|
10
6
|
|
|
11
|
-
import {act, renderHook} from '../../../test/test-utils'
|
|
12
7
|
import {ResourceProvider} from '../../context/ResourceProvider'
|
|
13
|
-
import {useSanityInstance} from '../../hooks/context/useSanityInstance'
|
|
14
8
|
import {useWindowConnection, type WindowConnection} from '../comlink/useWindowConnection'
|
|
15
9
|
import {useManageFavorite} from './useManageFavorite'
|
|
16
10
|
|
|
11
|
+
type MockFetch = (type: string, data?: unknown, options?: unknown) => Promise<{success: boolean}>
|
|
12
|
+
type MockSendMessage = (type: string, data?: unknown) => void
|
|
13
|
+
|
|
17
14
|
vi.mock(import('@sanity/sdk'), async (importOriginal) => {
|
|
18
15
|
const actual = await importOriginal()
|
|
19
16
|
return {
|
|
@@ -27,20 +24,15 @@ vi.mock('../comlink/useWindowConnection', () => ({
|
|
|
27
24
|
useWindowConnection: vi.fn(),
|
|
28
25
|
}))
|
|
29
26
|
|
|
30
|
-
vi.mock('../../hooks/context/useSanityInstance', () => ({
|
|
31
|
-
useSanityInstance: vi.fn(),
|
|
32
|
-
}))
|
|
33
|
-
|
|
34
27
|
describe('useManageFavorite', () => {
|
|
35
28
|
let favoriteStatusSubject: BehaviorSubject<FavoriteStatusResponse>
|
|
36
|
-
let mockFetch:
|
|
37
|
-
let mockSendMessage:
|
|
29
|
+
let mockFetch: Mock<MockFetch>
|
|
30
|
+
let mockSendMessage: Mock<MockSendMessage>
|
|
38
31
|
|
|
39
32
|
const mockDocumentHandle = {
|
|
40
33
|
documentId: 'mock-id',
|
|
41
34
|
documentType: 'mock-type',
|
|
42
35
|
resourceType: 'studio' as const,
|
|
43
|
-
resource: {projectId: 'test', dataset: 'test'},
|
|
44
36
|
}
|
|
45
37
|
|
|
46
38
|
beforeEach(() => {
|
|
@@ -67,32 +59,43 @@ describe('useManageFavorite', () => {
|
|
|
67
59
|
})
|
|
68
60
|
|
|
69
61
|
// Mock useWindowConnection
|
|
70
|
-
mockFetch = vi.fn().mockResolvedValue({success: true})
|
|
71
|
-
mockSendMessage = vi.fn()
|
|
72
|
-
vi.mocked(useWindowConnection).mockImplementation(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
62
|
+
mockFetch = vi.fn<MockFetch>().mockResolvedValue({success: true})
|
|
63
|
+
mockSendMessage = vi.fn<MockSendMessage>()
|
|
64
|
+
vi.mocked(useWindowConnection).mockImplementation(
|
|
65
|
+
() =>
|
|
66
|
+
({
|
|
67
|
+
fetch: (type: string, data?: unknown, options: unknown = {}) =>
|
|
68
|
+
mockFetch(type, data, options),
|
|
69
|
+
sendMessage: mockSendMessage,
|
|
70
|
+
}) as unknown as WindowConnection<Message>,
|
|
71
|
+
)
|
|
79
72
|
})
|
|
80
73
|
|
|
81
|
-
vi.mocked(useSanityInstance).mockImplementation(() => ({}) as unknown as SanityInstance)
|
|
82
|
-
|
|
83
74
|
afterEach(() => {
|
|
84
75
|
favoriteStatusSubject.complete()
|
|
85
76
|
vi.clearAllMocks()
|
|
86
77
|
})
|
|
87
78
|
|
|
88
79
|
it('should initialize with default states', () => {
|
|
89
|
-
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle)
|
|
80
|
+
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle), {
|
|
81
|
+
wrapper: ({children}) => (
|
|
82
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
83
|
+
{children}
|
|
84
|
+
</ResourceProvider>
|
|
85
|
+
),
|
|
86
|
+
})
|
|
90
87
|
|
|
91
88
|
expect(result.current.isFavorited).toBe(false)
|
|
92
89
|
})
|
|
93
90
|
|
|
94
91
|
it('should handle favorite action and update state', async () => {
|
|
95
|
-
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle)
|
|
92
|
+
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle), {
|
|
93
|
+
wrapper: ({children}) => (
|
|
94
|
+
<ResourceProvider projectId="test" dataset="test" fallback={null}>
|
|
95
|
+
{children}
|
|
96
|
+
</ResourceProvider>
|
|
97
|
+
),
|
|
98
|
+
})
|
|
96
99
|
|
|
97
100
|
expect(result.current.isFavorited).toBe(false)
|
|
98
101
|
|
|
@@ -121,7 +124,13 @@ describe('useManageFavorite', () => {
|
|
|
121
124
|
})
|
|
122
125
|
|
|
123
126
|
it('should handle unfavorite action and update state', async () => {
|
|
124
|
-
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle)
|
|
127
|
+
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle), {
|
|
128
|
+
wrapper: ({children}) => (
|
|
129
|
+
<ResourceProvider projectId="test" dataset="test" fallback={null}>
|
|
130
|
+
{children}
|
|
131
|
+
</ResourceProvider>
|
|
132
|
+
),
|
|
133
|
+
})
|
|
125
134
|
|
|
126
135
|
// Set initial state to favorited
|
|
127
136
|
await act(async () => {
|
|
@@ -156,7 +165,13 @@ describe('useManageFavorite', () => {
|
|
|
156
165
|
it('should not update state if favorite action fails', async () => {
|
|
157
166
|
mockFetch.mockResolvedValueOnce({success: false})
|
|
158
167
|
|
|
159
|
-
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle)
|
|
168
|
+
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle), {
|
|
169
|
+
wrapper: ({children}) => (
|
|
170
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
171
|
+
{children}
|
|
172
|
+
</ResourceProvider>
|
|
173
|
+
),
|
|
174
|
+
})
|
|
160
175
|
|
|
161
176
|
expect(result.current.isFavorited).toBe(false)
|
|
162
177
|
|
|
@@ -176,7 +191,13 @@ describe('useManageFavorite', () => {
|
|
|
176
191
|
throw new Error(errorMessage)
|
|
177
192
|
})
|
|
178
193
|
|
|
179
|
-
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle)
|
|
194
|
+
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle), {
|
|
195
|
+
wrapper: ({children}) => (
|
|
196
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
197
|
+
{children}
|
|
198
|
+
</ResourceProvider>
|
|
199
|
+
),
|
|
200
|
+
})
|
|
180
201
|
|
|
181
202
|
await act(async () => {
|
|
182
203
|
await expect(result.current.favorite()).rejects.toThrow(errorMessage)
|
|
@@ -193,7 +214,7 @@ describe('useManageFavorite', () => {
|
|
|
193
214
|
consoleErrorSpy.mockRestore()
|
|
194
215
|
})
|
|
195
216
|
|
|
196
|
-
it('should throw error when studio resource is missing
|
|
217
|
+
it('should throw error when studio resource is missing projectId or dataset', () => {
|
|
197
218
|
const mockDocumentHandleWithoutProjectId = {
|
|
198
219
|
documentId: 'mock-id',
|
|
199
220
|
documentType: 'mock-type',
|
|
@@ -202,8 +223,10 @@ describe('useManageFavorite', () => {
|
|
|
202
223
|
|
|
203
224
|
expect(() =>
|
|
204
225
|
renderHook(() => useManageFavorite(mockDocumentHandleWithoutProjectId), {
|
|
205
|
-
wrapper: ({children}
|
|
206
|
-
<ResourceProvider fallback={null}>
|
|
226
|
+
wrapper: ({children}) => (
|
|
227
|
+
<ResourceProvider projectId={undefined} dataset={undefined} fallback={null}>
|
|
228
|
+
{children}
|
|
229
|
+
</ResourceProvider>
|
|
207
230
|
),
|
|
208
231
|
}),
|
|
209
232
|
).toThrow('projectId and dataset are required for studio resources')
|
|
@@ -215,12 +238,17 @@ describe('useManageFavorite', () => {
|
|
|
215
238
|
documentType: 'mock-type',
|
|
216
239
|
resourceType: 'media-library' as const,
|
|
217
240
|
resourceId: undefined,
|
|
218
|
-
resource: {mediaLibraryId: 'media-library-id'},
|
|
219
241
|
}
|
|
220
242
|
|
|
221
|
-
expect(() =>
|
|
222
|
-
|
|
223
|
-
|
|
243
|
+
expect(() =>
|
|
244
|
+
renderHook(() => useManageFavorite(mockMediaDocumentHandle), {
|
|
245
|
+
wrapper: ({children}) => (
|
|
246
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
247
|
+
{children}
|
|
248
|
+
</ResourceProvider>
|
|
249
|
+
),
|
|
250
|
+
}),
|
|
251
|
+
).toThrow('resourceId is required for media-library and canvas resources')
|
|
224
252
|
})
|
|
225
253
|
|
|
226
254
|
it('should include schemaName in payload when provided', async () => {
|
|
@@ -228,7 +256,13 @@ describe('useManageFavorite', () => {
|
|
|
228
256
|
...mockDocumentHandle,
|
|
229
257
|
schemaName: 'testSchema',
|
|
230
258
|
}
|
|
231
|
-
const {result} = renderHook(() => useManageFavorite(mockDocumentHandleWithSchema)
|
|
259
|
+
const {result} = renderHook(() => useManageFavorite(mockDocumentHandleWithSchema), {
|
|
260
|
+
wrapper: ({children}) => (
|
|
261
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
262
|
+
{children}
|
|
263
|
+
</ResourceProvider>
|
|
264
|
+
),
|
|
265
|
+
})
|
|
232
266
|
|
|
233
267
|
await act(async () => {
|
|
234
268
|
await result.current.favorite()
|
|
@@ -241,7 +275,7 @@ describe('useManageFavorite', () => {
|
|
|
241
275
|
id: 'mock-id',
|
|
242
276
|
type: 'mock-type',
|
|
243
277
|
resource: {
|
|
244
|
-
id: 'test.test',
|
|
278
|
+
id: 'test-project.test-dataset',
|
|
245
279
|
type: 'studio',
|
|
246
280
|
schemaName: 'testSchema',
|
|
247
281
|
},
|
|
@@ -263,7 +297,13 @@ describe('useManageFavorite', () => {
|
|
|
263
297
|
getCurrent: () => undefined,
|
|
264
298
|
observable: favoriteStatusSubject.asObservable(),
|
|
265
299
|
}))
|
|
266
|
-
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle)
|
|
300
|
+
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle), {
|
|
301
|
+
wrapper: ({children}) => (
|
|
302
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
303
|
+
{children}
|
|
304
|
+
</ResourceProvider>
|
|
305
|
+
),
|
|
306
|
+
})
|
|
267
307
|
expect(result.current.isFavorited).toBe(false)
|
|
268
308
|
})
|
|
269
309
|
|
|
@@ -272,7 +312,13 @@ describe('useManageFavorite', () => {
|
|
|
272
312
|
fetch: undefined,
|
|
273
313
|
sendMessage: mockSendMessage,
|
|
274
314
|
} as unknown as WindowConnection<Message>)
|
|
275
|
-
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle)
|
|
315
|
+
const {result} = renderHook(() => useManageFavorite(mockDocumentHandle), {
|
|
316
|
+
wrapper: ({children}) => (
|
|
317
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
318
|
+
{children}
|
|
319
|
+
</ResourceProvider>
|
|
320
|
+
),
|
|
321
|
+
})
|
|
276
322
|
await act(async () => {
|
|
277
323
|
await result.current.favorite()
|
|
278
324
|
await result.current.unfavorite()
|
|
@@ -283,7 +329,13 @@ describe('useManageFavorite', () => {
|
|
|
283
329
|
it('should do nothing if documentId is missing', async () => {
|
|
284
330
|
const handle = {...mockDocumentHandle, documentId: undefined}
|
|
285
331
|
// @ts-expect-error -- no access to ManageFavorite props type
|
|
286
|
-
const {result} = renderHook(() => useManageFavorite(handle)
|
|
332
|
+
const {result} = renderHook(() => useManageFavorite(handle), {
|
|
333
|
+
wrapper: ({children}) => (
|
|
334
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
335
|
+
{children}
|
|
336
|
+
</ResourceProvider>
|
|
337
|
+
),
|
|
338
|
+
})
|
|
287
339
|
await act(async () => {
|
|
288
340
|
await result.current.favorite()
|
|
289
341
|
await result.current.unfavorite()
|
|
@@ -294,7 +346,13 @@ describe('useManageFavorite', () => {
|
|
|
294
346
|
it('should do nothing if documentType is missing', async () => {
|
|
295
347
|
const handle = {...mockDocumentHandle, documentType: undefined}
|
|
296
348
|
// @ts-expect-error -- no access to ManageFavorite props type
|
|
297
|
-
const {result} = renderHook(() => useManageFavorite(handle)
|
|
349
|
+
const {result} = renderHook(() => useManageFavorite(handle), {
|
|
350
|
+
wrapper: ({children}) => (
|
|
351
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
352
|
+
{children}
|
|
353
|
+
</ResourceProvider>
|
|
354
|
+
),
|
|
355
|
+
})
|
|
298
356
|
await act(async () => {
|
|
299
357
|
await result.current.favorite()
|
|
300
358
|
await result.current.unfavorite()
|
|
@@ -305,7 +363,13 @@ describe('useManageFavorite', () => {
|
|
|
305
363
|
it('should do nothing if resourceType is missing', async () => {
|
|
306
364
|
const handle = {...mockDocumentHandle, resourceType: undefined, resourceId: 'studio'}
|
|
307
365
|
// @ts-expect-error -- no access to ManageFavorite props type
|
|
308
|
-
const {result} = renderHook(() => useManageFavorite(handle)
|
|
366
|
+
const {result} = renderHook(() => useManageFavorite(handle), {
|
|
367
|
+
wrapper: ({children}) => (
|
|
368
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
369
|
+
{children}
|
|
370
|
+
</ResourceProvider>
|
|
371
|
+
),
|
|
372
|
+
})
|
|
309
373
|
await act(async () => {
|
|
310
374
|
await result.current.favorite()
|
|
311
375
|
await result.current.unfavorite()
|
|
@@ -7,16 +7,14 @@ import {
|
|
|
7
7
|
type StudioResource,
|
|
8
8
|
} from '@sanity/message-protocol'
|
|
9
9
|
import {
|
|
10
|
+
type DocumentHandle,
|
|
10
11
|
type FavoriteStatusResponse,
|
|
11
|
-
type FrameMessage,
|
|
12
12
|
getFavoritesState,
|
|
13
|
-
isDatasetResource,
|
|
14
13
|
resolveFavoritesState,
|
|
15
14
|
} from '@sanity/sdk'
|
|
16
|
-
import {
|
|
15
|
+
import {type FrameMessage} from '@sanity/sdk/comlink'
|
|
16
|
+
import {useCallback, useMemo, useSyncExternalStore} from 'react'
|
|
17
17
|
|
|
18
|
-
import {type DocumentHandle} from '../../config/handles'
|
|
19
|
-
import {ResourceContext} from '../../context/DefaultResourceContext'
|
|
20
18
|
import {useWindowConnection} from '../comlink/useWindowConnection'
|
|
21
19
|
import {useSanityInstance} from '../context/useSanityInstance'
|
|
22
20
|
|
|
@@ -84,7 +82,8 @@ interface UseManageFavoriteProps extends DocumentHandle {
|
|
|
84
82
|
export function useManageFavorite({
|
|
85
83
|
documentId,
|
|
86
84
|
documentType,
|
|
87
|
-
|
|
85
|
+
projectId: paramProjectId,
|
|
86
|
+
dataset: paramDataset,
|
|
88
87
|
resourceId: paramResourceId,
|
|
89
88
|
resourceType,
|
|
90
89
|
schemaName,
|
|
@@ -94,11 +93,11 @@ export function useManageFavorite({
|
|
|
94
93
|
connectTo: SDK_CHANNEL_NAME,
|
|
95
94
|
})
|
|
96
95
|
const instance = useSanityInstance()
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
const projectId =
|
|
101
|
-
const dataset =
|
|
96
|
+
const {config} = instance
|
|
97
|
+
const instanceProjectId = config?.projectId
|
|
98
|
+
const instanceDataset = config?.dataset
|
|
99
|
+
const projectId = paramProjectId ?? instanceProjectId
|
|
100
|
+
const dataset = paramDataset ?? instanceDataset
|
|
102
101
|
|
|
103
102
|
if (resourceType === 'studio' && (!projectId || !dataset)) {
|
|
104
103
|
throw new Error('projectId and dataset are required for studio resources')
|
|
@@ -111,21 +110,16 @@ export function useManageFavorite({
|
|
|
111
110
|
throw new Error('resourceId is required for media-library and canvas resources')
|
|
112
111
|
}
|
|
113
112
|
|
|
114
|
-
if (!resource) {
|
|
115
|
-
throw new Error('resource is required')
|
|
116
|
-
}
|
|
117
|
-
|
|
118
113
|
// used for favoriteStore functions like getFavoritesState and resolveFavoritesState
|
|
119
114
|
const context = useMemo(
|
|
120
115
|
() => ({
|
|
121
116
|
documentId,
|
|
122
117
|
documentType,
|
|
123
|
-
resource,
|
|
124
118
|
resourceId,
|
|
125
119
|
resourceType,
|
|
126
120
|
schemaName,
|
|
127
121
|
}),
|
|
128
|
-
[documentId, documentType,
|
|
122
|
+
[documentId, documentType, resourceId, resourceType, schemaName],
|
|
129
123
|
)
|
|
130
124
|
|
|
131
125
|
// Get favorite status using StateSource
|
|
@@ -33,7 +33,8 @@ describe('useNavigateToStudioDocument', () => {
|
|
|
33
33
|
const mockDocumentHandle: DocumentHandle = {
|
|
34
34
|
documentId: 'doc123',
|
|
35
35
|
documentType: 'article',
|
|
36
|
-
|
|
36
|
+
projectId: 'project1',
|
|
37
|
+
dataset: 'dataset1',
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
const mockWorkspace = {
|
|
@@ -108,13 +109,13 @@ describe('useNavigateToStudioDocument', () => {
|
|
|
108
109
|
consoleSpy.mockRestore()
|
|
109
110
|
})
|
|
110
111
|
|
|
111
|
-
it('warns and does not navigate when
|
|
112
|
+
it('warns and does not navigate when projectId or dataset is missing', () => {
|
|
112
113
|
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
113
114
|
|
|
114
115
|
const incompleteDocumentHandle: DocumentHandle = {
|
|
115
116
|
documentId: 'doc123',
|
|
116
117
|
documentType: 'article',
|
|
117
|
-
|
|
118
|
+
// missing projectId and dataset
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
const {result} = renderHook(() => useNavigateToStudioDocument(incompleteDocumentHandle))
|
|
@@ -196,11 +197,8 @@ describe('useNavigateToStudioDocument', () => {
|
|
|
196
197
|
|
|
197
198
|
result.current.navigateToStudioDocument()
|
|
198
199
|
|
|
199
|
-
const resource = mockDocumentHandle.resource
|
|
200
|
-
const projectId = 'projectId' in resource ? resource.projectId : undefined
|
|
201
|
-
const dataset = 'dataset' in resource ? resource.dataset : undefined
|
|
202
200
|
expect(consoleSpy).toHaveBeenCalledWith(
|
|
203
|
-
`No workspace found for document with projectId: ${projectId} and dataset: ${dataset} or with preferred studio url: ${preferredUrl}`,
|
|
201
|
+
`No workspace found for document with projectId: ${mockDocumentHandle.projectId} and dataset: ${mockDocumentHandle.dataset} or with preferred studio url: ${preferredUrl}`,
|
|
204
202
|
)
|
|
205
203
|
expect(mockSendMessage).not.toHaveBeenCalled()
|
|
206
204
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {type Bridge, SDK_CHANNEL_NAME, SDK_NODE_NAME} from '@sanity/message-protocol'
|
|
2
|
-
import {
|
|
2
|
+
import {type DocumentHandle} from '@sanity/sdk'
|
|
3
3
|
import {useCallback} from 'react'
|
|
4
4
|
|
|
5
|
-
import {type DocumentHandle} from '../../config/handles'
|
|
6
5
|
import {useWindowConnection} from '../comlink/useWindowConnection'
|
|
7
6
|
import {
|
|
8
7
|
type DashboardResource,
|
|
@@ -72,10 +71,7 @@ export function useNavigateToStudioDocument(
|
|
|
72
71
|
})
|
|
73
72
|
|
|
74
73
|
const navigateToStudioDocument = useCallback(() => {
|
|
75
|
-
const {
|
|
76
|
-
const datasetResource = resource && isDatasetResource(resource) ? resource : undefined
|
|
77
|
-
const projectId = datasetResource?.projectId
|
|
78
|
-
const dataset = datasetResource?.dataset
|
|
74
|
+
const {projectId, dataset} = documentHandle
|
|
79
75
|
|
|
80
76
|
if (!projectId || !dataset) {
|
|
81
77
|
// eslint-disable-next-line no-console
|
|
@@ -15,7 +15,6 @@ describe('useRecordDocumentHistoryEvent', () => {
|
|
|
15
15
|
documentType: 'mock-type',
|
|
16
16
|
resourceType: 'studio' as const,
|
|
17
17
|
resourceId: 'mock-resource-id',
|
|
18
|
-
resource: {projectId: 'mock-project-id', dataset: 'mock-dataset'},
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
beforeEach(() => {
|
|
@@ -63,7 +62,6 @@ describe('useRecordDocumentHistoryEvent', () => {
|
|
|
63
62
|
documentType: 'mock-type',
|
|
64
63
|
resourceType: 'media-library' as const,
|
|
65
64
|
resourceId: undefined,
|
|
66
|
-
resource: {mediaLibraryId: 'mock-media-library-id'},
|
|
67
65
|
}
|
|
68
66
|
|
|
69
67
|
expect(() => renderHook(() => useRecordDocumentHistoryEvent(mockMediaDocumentHandle))).toThrow(
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
SDK_NODE_NAME,
|
|
7
7
|
type StudioResource,
|
|
8
8
|
} from '@sanity/message-protocol'
|
|
9
|
-
import {type
|
|
9
|
+
import {type DocumentHandle} from '@sanity/sdk'
|
|
10
|
+
import {type FrameMessage} from '@sanity/sdk/comlink'
|
|
10
11
|
import {useCallback} from 'react'
|
|
11
12
|
|
|
12
|
-
import {type DocumentHandle} from '../../config/handles'
|
|
13
13
|
import {useWindowConnection} from '../comlink/useWindowConnection'
|
|
14
14
|
|
|
15
15
|
interface DocumentInteractionHistory {
|