@sanity/sdk-react 0.0.0-alpha.20 → 0.0.0-alpha.21
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/dist/index.d.ts +276 -207
- package/dist/index.js +90 -75
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/_exports/index.ts +11 -11
- package/src/components/Login/LoginLinks.test.tsx +2 -2
- package/src/components/Login/LoginLinks.tsx +2 -2
- package/src/components/auth/AuthBoundary.test.tsx +2 -2
- package/src/components/auth/LoginCallback.test.tsx +3 -3
- package/src/components/auth/LoginCallback.tsx +4 -4
- package/src/hooks/auth/useCurrentUser.tsx +1 -0
- package/src/hooks/auth/useHandleAuthCallback.test.tsx +16 -0
- package/src/hooks/auth/{useHandleCallback.tsx → useHandleAuthCallback.tsx} +6 -6
- package/src/hooks/auth/useLogOut.test.tsx +2 -2
- package/src/hooks/client/useClient.ts +1 -0
- package/src/hooks/comlink/useManageFavorite.test.ts +9 -4
- package/src/hooks/comlink/useManageFavorite.ts +42 -13
- package/src/hooks/comlink/useRecordDocumentHistoryEvent.test.ts +7 -3
- package/src/hooks/comlink/useRecordDocumentHistoryEvent.ts +39 -12
- package/src/hooks/dashboard/useNavigateToStudioDocument.test.ts +178 -0
- package/src/hooks/dashboard/useNavigateToStudioDocument.ts +31 -5
- package/src/hooks/dashboard/useStudioWorkspacesByResourceId.test.tsx +5 -1
- package/src/hooks/dashboard/useStudioWorkspacesByResourceId.ts +4 -3
- package/src/hooks/datasets/useDatasets.ts +6 -3
- package/src/hooks/document/useApplyDocumentActions.test.ts +25 -0
- package/src/hooks/document/{useApplyActions.ts → useApplyDocumentActions.ts} +13 -12
- package/src/hooks/document/{usePermissions.ts → useDocumentPermissions.ts} +8 -6
- package/src/hooks/document/useDocumentSyncStatus.ts +4 -1
- package/src/hooks/document/useEditDocument.test.ts +8 -8
- package/src/hooks/document/useEditDocument.ts +2 -2
- package/src/hooks/{infiniteList/useInfiniteList.test.tsx → documents/useDocuments.test.tsx} +9 -9
- package/src/hooks/{infiniteList/useInfiniteList.ts → documents/useDocuments.ts} +10 -10
- package/src/hooks/{paginatedList/usePaginatedList.test.tsx → paginatedDocuments/usePaginatedDocuments.test.tsx} +14 -14
- package/src/hooks/{paginatedList/usePaginatedList.ts → paginatedDocuments/usePaginatedDocuments.ts} +7 -7
- package/src/hooks/preview/usePreview.tsx +2 -2
- package/src/hooks/projection/useProjection.ts +2 -2
- package/src/hooks/projects/useProject.ts +4 -1
- package/src/hooks/projects/useProjects.ts +7 -3
- package/src/hooks/auth/useHandleCallback.test.tsx +0 -16
- package/src/hooks/document/useApplyActions.test.ts +0 -25
|
@@ -11,18 +11,18 @@ const DEFAULT_PERSPECTIVE = 'drafts'
|
|
|
11
11
|
* Result structure returned from the infinite list query
|
|
12
12
|
* @internal
|
|
13
13
|
*/
|
|
14
|
-
interface
|
|
14
|
+
interface UseDocumentsQueryResult {
|
|
15
15
|
count: number
|
|
16
16
|
data: DocumentHandle[]
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* Configuration options for the
|
|
20
|
+
* Configuration options for the useDocuments hook
|
|
21
21
|
*
|
|
22
22
|
* @beta
|
|
23
23
|
* @category Types
|
|
24
24
|
*/
|
|
25
|
-
export interface
|
|
25
|
+
export interface DocumentsOptions extends QueryOptions {
|
|
26
26
|
/**
|
|
27
27
|
* GROQ filter expression to apply to the query
|
|
28
28
|
*/
|
|
@@ -42,12 +42,12 @@ export interface InfiniteListOptions extends QueryOptions {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
-
* Return value from the
|
|
45
|
+
* Return value from the useDocuments hook
|
|
46
46
|
*
|
|
47
47
|
* @beta
|
|
48
48
|
* @category Types
|
|
49
49
|
*/
|
|
50
|
-
export interface
|
|
50
|
+
export interface DocumentsResponse {
|
|
51
51
|
/**
|
|
52
52
|
* Array of document handles for the current batch
|
|
53
53
|
*/
|
|
@@ -78,10 +78,10 @@ export interface InfiniteList {
|
|
|
78
78
|
* @beta
|
|
79
79
|
* @category Documents
|
|
80
80
|
* @param options - Configuration options for the infinite list
|
|
81
|
-
* @returns An object containing the list of document handles, the loading state, the total count of
|
|
81
|
+
* @returns An object containing the list of document handles, the loading state, the total count of retrieved document handles, and a function to load more
|
|
82
82
|
* @example
|
|
83
83
|
* ```tsx
|
|
84
|
-
* const {data, hasMore, isPending, loadMore} =
|
|
84
|
+
* const {data, hasMore, isPending, loadMore} = useDocuments({
|
|
85
85
|
* filter: '_type == "post"',
|
|
86
86
|
* search: searchTerm,
|
|
87
87
|
* batchSize: 10,
|
|
@@ -104,14 +104,14 @@ export interface InfiniteList {
|
|
|
104
104
|
* ```
|
|
105
105
|
*
|
|
106
106
|
*/
|
|
107
|
-
export function
|
|
107
|
+
export function useDocuments({
|
|
108
108
|
batchSize = DEFAULT_BATCH_SIZE,
|
|
109
109
|
params,
|
|
110
110
|
search,
|
|
111
111
|
filter,
|
|
112
112
|
orderings,
|
|
113
113
|
...options
|
|
114
|
-
}:
|
|
114
|
+
}: DocumentsOptions): DocumentsResponse {
|
|
115
115
|
const perspective = options.perspective ?? DEFAULT_PERSPECTIVE
|
|
116
116
|
const [limit, setLimit] = useState(batchSize)
|
|
117
117
|
|
|
@@ -155,7 +155,7 @@ export function useInfiniteList({
|
|
|
155
155
|
const {
|
|
156
156
|
data: {count, data},
|
|
157
157
|
isPending,
|
|
158
|
-
} = useQuery<
|
|
158
|
+
} = useQuery<UseDocumentsQueryResult>(`{"count":${countQuery},"data":${dataQuery}}`, {
|
|
159
159
|
...options,
|
|
160
160
|
params,
|
|
161
161
|
perspective,
|
|
@@ -3,11 +3,11 @@ import {describe, vi} from 'vitest'
|
|
|
3
3
|
|
|
4
4
|
import {evaluateSync, parse} from '../_synchronous-groq-js.mjs'
|
|
5
5
|
import {useQuery} from '../query/useQuery'
|
|
6
|
-
import {
|
|
6
|
+
import {usePaginatedDocuments} from './usePaginatedDocuments'
|
|
7
7
|
|
|
8
8
|
vi.mock('../query/useQuery')
|
|
9
9
|
|
|
10
|
-
describe('
|
|
10
|
+
describe('usePaginatedDocuments', () => {
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
const dataset = [
|
|
13
13
|
{
|
|
@@ -76,14 +76,14 @@ describe('usePaginatedList', () => {
|
|
|
76
76
|
|
|
77
77
|
it('should respect custom page size', () => {
|
|
78
78
|
const customPageSize = 2
|
|
79
|
-
const {result} = renderHook(() =>
|
|
79
|
+
const {result} = renderHook(() => usePaginatedDocuments({pageSize: customPageSize}))
|
|
80
80
|
|
|
81
81
|
expect(result.current.pageSize).toBe(customPageSize)
|
|
82
82
|
expect(result.current.data.length).toBeLessThanOrEqual(customPageSize)
|
|
83
83
|
})
|
|
84
84
|
|
|
85
85
|
it('should filter by document type', () => {
|
|
86
|
-
const {result} = renderHook(() =>
|
|
86
|
+
const {result} = renderHook(() => usePaginatedDocuments({filter: '_type == "movie"'}))
|
|
87
87
|
|
|
88
88
|
expect(result.current.data.every((doc) => doc._type === 'movie')).toBe(true)
|
|
89
89
|
expect(result.current.count).toBe(5) // 5 movies in the dataset
|
|
@@ -91,7 +91,7 @@ describe('usePaginatedList', () => {
|
|
|
91
91
|
|
|
92
92
|
// groq-js doesn't support search filters yet
|
|
93
93
|
it.skip('should apply search filter', () => {
|
|
94
|
-
const {result} = renderHook(() =>
|
|
94
|
+
const {result} = renderHook(() => usePaginatedDocuments({search: 'inter'}))
|
|
95
95
|
|
|
96
96
|
// Should match "Interstellar"
|
|
97
97
|
expect(result.current.data.some((doc) => doc._id === 'movie3')).toBe(true)
|
|
@@ -99,7 +99,7 @@ describe('usePaginatedList', () => {
|
|
|
99
99
|
|
|
100
100
|
it('should apply ordering', () => {
|
|
101
101
|
const {result} = renderHook(() =>
|
|
102
|
-
|
|
102
|
+
usePaginatedDocuments({
|
|
103
103
|
filter: '_type == "movie"',
|
|
104
104
|
orderings: [{field: 'releaseYear', direction: 'desc'}],
|
|
105
105
|
}),
|
|
@@ -111,7 +111,7 @@ describe('usePaginatedList', () => {
|
|
|
111
111
|
|
|
112
112
|
it('should calculate pagination values correctly', () => {
|
|
113
113
|
const pageSize = 2
|
|
114
|
-
const {result} = renderHook(() =>
|
|
114
|
+
const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
|
|
115
115
|
|
|
116
116
|
expect(result.current.currentPage).toBe(1)
|
|
117
117
|
expect(result.current.totalPages).toBe(3) // 6 items with page size 2
|
|
@@ -122,7 +122,7 @@ describe('usePaginatedList', () => {
|
|
|
122
122
|
|
|
123
123
|
it('should navigate to next page', () => {
|
|
124
124
|
const pageSize = 2
|
|
125
|
-
const {result} = renderHook(() =>
|
|
125
|
+
const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
|
|
126
126
|
|
|
127
127
|
expect(result.current.currentPage).toBe(1)
|
|
128
128
|
expect(result.current.data.length).toBe(pageSize)
|
|
@@ -138,7 +138,7 @@ describe('usePaginatedList', () => {
|
|
|
138
138
|
|
|
139
139
|
it('should navigate to previous page', () => {
|
|
140
140
|
const pageSize = 2
|
|
141
|
-
const {result} = renderHook(() =>
|
|
141
|
+
const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
|
|
142
142
|
|
|
143
143
|
// Go to page 2 first
|
|
144
144
|
act(() => {
|
|
@@ -158,7 +158,7 @@ describe('usePaginatedList', () => {
|
|
|
158
158
|
|
|
159
159
|
it('should navigate to first page', () => {
|
|
160
160
|
const pageSize = 2
|
|
161
|
-
const {result} = renderHook(() =>
|
|
161
|
+
const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
|
|
162
162
|
|
|
163
163
|
// Go to last page first
|
|
164
164
|
act(() => {
|
|
@@ -178,7 +178,7 @@ describe('usePaginatedList', () => {
|
|
|
178
178
|
|
|
179
179
|
it('should navigate to last page', () => {
|
|
180
180
|
const pageSize = 2
|
|
181
|
-
const {result} = renderHook(() =>
|
|
181
|
+
const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
|
|
182
182
|
|
|
183
183
|
act(() => {
|
|
184
184
|
result.current.lastPage()
|
|
@@ -190,7 +190,7 @@ describe('usePaginatedList', () => {
|
|
|
190
190
|
|
|
191
191
|
it('should navigate to specific page', () => {
|
|
192
192
|
const pageSize = 2
|
|
193
|
-
const {result} = renderHook(() =>
|
|
193
|
+
const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
|
|
194
194
|
|
|
195
195
|
act(() => {
|
|
196
196
|
result.current.goToPage(2) // Go to page 2
|
|
@@ -215,7 +215,7 @@ describe('usePaginatedList', () => {
|
|
|
215
215
|
|
|
216
216
|
it('should set page availability flags correctly', () => {
|
|
217
217
|
const pageSize = 2
|
|
218
|
-
const {result} = renderHook(() =>
|
|
218
|
+
const {result} = renderHook(() => usePaginatedDocuments({pageSize}))
|
|
219
219
|
// On first page
|
|
220
220
|
expect(result.current.hasFirstPage).toBe(false)
|
|
221
221
|
expect(result.current.hasPreviousPage).toBe(false)
|
|
@@ -241,7 +241,7 @@ describe('usePaginatedList', () => {
|
|
|
241
241
|
|
|
242
242
|
// New test case for resetting the current page when filter changes
|
|
243
243
|
it('should reset current page when filter changes', () => {
|
|
244
|
-
const {result, rerender} = renderHook((props) =>
|
|
244
|
+
const {result, rerender} = renderHook((props) => usePaginatedDocuments(props), {
|
|
245
245
|
initialProps: {pageSize: 2, filter: ''},
|
|
246
246
|
})
|
|
247
247
|
// Initially, current page should be 1
|
package/src/hooks/{paginatedList/usePaginatedList.ts → paginatedDocuments/usePaginatedDocuments.ts}
RENAMED
|
@@ -7,12 +7,12 @@ import {useQuery} from '../query/useQuery'
|
|
|
7
7
|
const DEFAULT_PERSPECTIVE = 'drafts'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Configuration options for the
|
|
10
|
+
* Configuration options for the usePaginatedDocuments hook
|
|
11
11
|
*
|
|
12
12
|
* @beta
|
|
13
13
|
* @category Types
|
|
14
14
|
*/
|
|
15
|
-
export interface
|
|
15
|
+
export interface PaginatedDocumentsOptions extends QueryOptions {
|
|
16
16
|
/**
|
|
17
17
|
* GROQ filter expression to apply to the query
|
|
18
18
|
*/
|
|
@@ -32,12 +32,12 @@ export interface PaginatedListOptions extends QueryOptions {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
* Return value from the
|
|
35
|
+
* Return value from the usePaginatedDocuments hook
|
|
36
36
|
*
|
|
37
37
|
* @beta
|
|
38
38
|
* @category Types
|
|
39
39
|
*/
|
|
40
|
-
export interface
|
|
40
|
+
export interface PaginatedDocumentsResponse {
|
|
41
41
|
/**
|
|
42
42
|
* Array of document handles for the current page
|
|
43
43
|
*/
|
|
@@ -136,7 +136,7 @@ export interface PaginatedList {
|
|
|
136
136
|
* previousPage,
|
|
137
137
|
* hasNextPage,
|
|
138
138
|
* hasPreviousPage
|
|
139
|
-
* } =
|
|
139
|
+
* } = usePaginatedDocuments({
|
|
140
140
|
* filter: '_type == "post"',
|
|
141
141
|
* search: searchTerm,
|
|
142
142
|
* pageSize: 10,
|
|
@@ -160,14 +160,14 @@ export interface PaginatedList {
|
|
|
160
160
|
* ```
|
|
161
161
|
*
|
|
162
162
|
*/
|
|
163
|
-
export function
|
|
163
|
+
export function usePaginatedDocuments({
|
|
164
164
|
filter = '',
|
|
165
165
|
pageSize = 25,
|
|
166
166
|
params = {},
|
|
167
167
|
orderings,
|
|
168
168
|
search,
|
|
169
169
|
...options
|
|
170
|
-
}:
|
|
170
|
+
}: PaginatedDocumentsOptions = {}): PaginatedDocumentsResponse {
|
|
171
171
|
const [pageIndex, setPageIndex] = useState(0)
|
|
172
172
|
const key = JSON.stringify({filter, search, params, orderings, pageSize})
|
|
173
173
|
// Reset the pageIndex to 0 whenever any query parameters (filter, search,
|
|
@@ -51,12 +51,12 @@ export interface UsePreviewResults {
|
|
|
51
51
|
* }
|
|
52
52
|
*
|
|
53
53
|
* // DocumentList.jsx
|
|
54
|
-
* const { data
|
|
54
|
+
* const { data } = useDocuments({ filter: '_type == "movie"' })
|
|
55
55
|
* return (
|
|
56
56
|
* <div>
|
|
57
57
|
* <h1>Movies</h1>
|
|
58
58
|
* <ul>
|
|
59
|
-
* {
|
|
59
|
+
* {data.map(movie => (
|
|
60
60
|
* <li key={movie._id}>
|
|
61
61
|
* <Suspense fallback='Loading…'>
|
|
62
62
|
* <PreviewComponent document={movie} />
|
|
@@ -65,10 +65,10 @@ export interface UseProjectionResults<TResult extends object> {
|
|
|
65
65
|
* }
|
|
66
66
|
* ```
|
|
67
67
|
*
|
|
68
|
-
* @example Combining with
|
|
68
|
+
* @example Combining with useDocuments to render a collection with specific fields
|
|
69
69
|
* ```
|
|
70
70
|
* // DocumentList.jsx
|
|
71
|
-
* const { data } =
|
|
71
|
+
* const { data } = useDocuments({ filter: '_type == "article"' })
|
|
72
72
|
* return (
|
|
73
73
|
* <div>
|
|
74
74
|
* <h1>Books</h1>
|
|
@@ -32,7 +32,10 @@ type UseProject = {
|
|
|
32
32
|
(projectId: string): SanityProject
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* @public
|
|
37
|
+
* @function
|
|
38
|
+
*/
|
|
36
39
|
export const useProject: UseProject = createStateSourceHook({
|
|
37
40
|
// remove `undefined` since we're suspending when that is the case
|
|
38
41
|
getState: getProjectState as (
|
|
@@ -6,16 +6,17 @@ import {createStateSourceHook} from '../helpers/createStateSourceHook'
|
|
|
6
6
|
/**
|
|
7
7
|
* @public
|
|
8
8
|
* @category Types
|
|
9
|
+
* @interface
|
|
9
10
|
*/
|
|
10
11
|
export type ProjectWithoutMembers = Omit<SanityProject, 'members'>
|
|
11
12
|
|
|
12
13
|
type UseProjects = {
|
|
13
14
|
/**
|
|
14
15
|
*
|
|
15
|
-
* Returns metadata for each project
|
|
16
|
+
* Returns metadata for each project you have access to.
|
|
16
17
|
*
|
|
17
18
|
* @category Projects
|
|
18
|
-
* @returns An array of metadata (minus the projects’ members) for each project
|
|
19
|
+
* @returns An array of metadata (minus the projects’ members) for each project
|
|
19
20
|
* @example
|
|
20
21
|
* ```tsx
|
|
21
22
|
* const projects = useProjects()
|
|
@@ -32,7 +33,10 @@ type UseProjects = {
|
|
|
32
33
|
(): ProjectWithoutMembers[]
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* @public
|
|
38
|
+
* @function
|
|
39
|
+
*/
|
|
36
40
|
export const useProjects: UseProjects = createStateSourceHook({
|
|
37
41
|
// remove `undefined` since we're suspending when that is the case
|
|
38
42
|
getState: getProjectsState as (instance: SanityInstance) => StateSource<ProjectWithoutMembers[]>,
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {handleCallback} from '@sanity/sdk'
|
|
2
|
-
import {identity} from 'rxjs'
|
|
3
|
-
import {describe, it} from 'vitest'
|
|
4
|
-
|
|
5
|
-
import {createCallbackHook} from '../helpers/createCallbackHook'
|
|
6
|
-
|
|
7
|
-
vi.mock('../helpers/createCallbackHook', () => ({createCallbackHook: vi.fn(identity)}))
|
|
8
|
-
vi.mock('@sanity/sdk', () => ({handleCallback: vi.fn()}))
|
|
9
|
-
|
|
10
|
-
describe('useHandleCallback', () => {
|
|
11
|
-
it('calls `createCallbackHook` with `handleCallback`', async () => {
|
|
12
|
-
const {useHandleCallback} = await import('./useHandleCallback')
|
|
13
|
-
expect(createCallbackHook).toHaveBeenCalledWith(handleCallback)
|
|
14
|
-
expect(useHandleCallback).toBe(handleCallback)
|
|
15
|
-
})
|
|
16
|
-
})
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import {applyActions, createDocument, type ResourceId} from '@sanity/sdk'
|
|
2
|
-
import {describe, it} from 'vitest'
|
|
3
|
-
|
|
4
|
-
import {createCallbackHook} from '../helpers/createCallbackHook'
|
|
5
|
-
|
|
6
|
-
vi.mock('../helpers/createCallbackHook', () => ({
|
|
7
|
-
createCallbackHook: vi.fn((cb) => () => cb),
|
|
8
|
-
}))
|
|
9
|
-
vi.mock('@sanity/sdk', async (importOriginal) => {
|
|
10
|
-
const original = await importOriginal<typeof import('@sanity/sdk')>()
|
|
11
|
-
return {...original, applyActions: vi.fn()}
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
describe('useApplyActions', () => {
|
|
15
|
-
it('calls `createCallbackHook` with `applyActions`', async () => {
|
|
16
|
-
const {useApplyActions} = await import('./useApplyActions')
|
|
17
|
-
const resourceId: ResourceId = 'project1.dataset1'
|
|
18
|
-
expect(createCallbackHook).not.toHaveBeenCalled()
|
|
19
|
-
|
|
20
|
-
expect(applyActions).not.toHaveBeenCalled()
|
|
21
|
-
const apply = useApplyActions(resourceId)
|
|
22
|
-
apply(createDocument({_type: 'author'}))
|
|
23
|
-
expect(applyActions).toHaveBeenCalledWith(createDocument({_type: 'author'}))
|
|
24
|
-
})
|
|
25
|
-
})
|