@sanity/sdk-react 3.11.0-next.20261029105031 → 3.11.0
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 +13 -9
- package/dist/_exports/collaboration.d.ts +255 -0
- package/dist/_exports/collaboration.d.ts.map +1 -0
- package/dist/_exports/collaboration.js +244 -0
- package/dist/_exports/collaboration.js.map +1 -0
- package/dist/_exports/dashboard.js +2 -1
- package/dist/_exports/dashboard.js.map +1 -1
- package/dist/index.d.ts +16 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -159
- package/dist/index.js.map +1 -1
- package/dist/useCommentList-CXi_IIwA.js +167 -0
- package/dist/useCommentList-CXi_IIwA.js.map +1 -0
- package/dist/useNormalizedResourceOptions-BKg7aOKA.d.ts +22 -0
- package/dist/useNormalizedResourceOptions-BKg7aOKA.d.ts.map +1 -0
- package/dist/useSanityInstance-C0a_Ou_p.js +10 -0
- package/dist/useSanityInstance-C0a_Ou_p.js.map +1 -0
- package/dist/{useStudioWorkspacesByProjectIdDataset-FRofq7KL.js → useStudioWorkspacesByProjectIdDataset-Cx-Q44d0.js} +4 -8
- package/dist/useStudioWorkspacesByProjectIdDataset-Cx-Q44d0.js.map +1 -0
- package/package.json +3 -2
- package/src/_exports/collaboration.ts +13 -0
- package/src/_exports/sdk-react.ts +6 -3
- package/src/hooks/comments/legacy/noCommentsError.ts +20 -0
- package/src/hooks/comments/legacy/useCommentActions.test.tsx +150 -0
- package/src/hooks/comments/legacy/useCommentActions.ts +116 -0
- package/src/hooks/comments/legacy/useCommentThreads.test.tsx +107 -0
- package/src/hooks/comments/legacy/useCommentThreads.ts +83 -0
- package/src/hooks/comments/legacy/useComments.test.tsx +242 -0
- package/src/hooks/comments/legacy/useComments.ts +68 -0
- package/src/hooks/comments/useCommentActions.test.tsx +33 -13
- package/src/hooks/comments/useCommentActions.ts +31 -11
- package/src/hooks/comments/useCommentList.ts +34 -19
- package/src/hooks/comments/useCommentThreads.test.tsx +207 -19
- package/src/hooks/comments/useCommentThreads.ts +33 -27
- package/src/hooks/comments/useComments.test.tsx +33 -126
- package/src/hooks/comments/useComments.ts +31 -12
- package/src/hooks/comments/useCommentsQuery.test.tsx +259 -0
- package/src/hooks/comments/useCommentsQuery.ts +105 -0
- package/src/hooks/document/useEditDocument.ts +0 -1
- package/dist/useStudioWorkspacesByProjectIdDataset-FRofq7KL.js.map +0 -1
package/README.md
CHANGED
|
@@ -798,15 +798,18 @@ function DocStatus({handle}: {handle: DocumentHandle}) {
|
|
|
798
798
|
|
|
799
799
|
## Quick Reference
|
|
800
800
|
|
|
801
|
-
| Task | Hook/Function
|
|
802
|
-
| --------------------- |
|
|
803
|
-
| List documents | `useDocuments`, `usePaginatedDocuments`
|
|
804
|
-
| Read document | `useDocument`, `useDocumentProjection`
|
|
805
|
-
| Edit field | `useEditDocument`
|
|
806
|
-
| Publish/Delete/Create | `useApplyDocumentActions` + action creators
|
|
807
|
-
| GROQ query | `useQuery`
|
|
808
|
-
| Check permissions | `useDocumentPermissions`
|
|
809
|
-
| Listen to changes | `useDocumentEvent`
|
|
801
|
+
| Task | Hook/Function |
|
|
802
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
803
|
+
| List documents | `useDocuments`, `usePaginatedDocuments` |
|
|
804
|
+
| Read document | `useDocument`, `useDocumentProjection` |
|
|
805
|
+
| Edit field | `useEditDocument` |
|
|
806
|
+
| Publish/Delete/Create | `useApplyDocumentActions` + action creators |
|
|
807
|
+
| GROQ query | `useQuery` |
|
|
808
|
+
| Check permissions | `useDocumentPermissions` |
|
|
809
|
+
| Listen to changes | `useDocumentEvent` |
|
|
810
|
+
| Comments | `useComments`, `useCommentThreads`, `useCommentsQuery`, `useCommentActions`, from `@sanity/sdk-react/collaboration` |
|
|
811
|
+
|
|
812
|
+
Comments have their own guide: [Collaboration](./guides/Collaboration.md).
|
|
810
813
|
|
|
811
814
|
---
|
|
812
815
|
|
|
@@ -815,6 +818,7 @@ function DocStatus({handle}: {handle: DocumentHandle}) {
|
|
|
815
818
|
- **[Sanity Docs](https://sanity.io/docs/app-sdk)** — Conceptual overview, quickstart guide, and step-by-step walkthrough
|
|
816
819
|
- **[App SDK Reference](https://reference.sanity.io/_sanity/sdk-react)** — In-depth API documentation
|
|
817
820
|
- **[SDK Explorer](https://sdk-explorer.sanity.io)** — Example implementations
|
|
821
|
+
- **[Collaboration Guide](./guides/Collaboration.md)** — Reading and writing comments
|
|
818
822
|
- **[Migration Guide](./guides/0-Migration-Guide.md)** — Upgrading from previous versions
|
|
819
823
|
- **[Learn Course](https://www.sanity.io/learn/course/build-content-apps-with-sanity-app-sdk)** — Interactive video tutorial
|
|
820
824
|
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { t as WithResourceNameSupport } from "../useNormalizedResourceOptions-BKg7aOKA.js";
|
|
2
|
+
import { Comment, CommentThread, CommentsOptions, CommentsQueryOptions, CreateCommentOptions, ReactionOptions, RemoveCommentOptions, ReplyToCommentOptions, SetCommentStatusOptions, UpdateCommentAnchorOptions, UpdateCommentOptions } from "@sanity/sdk/collaboration";
|
|
3
|
+
export * from "@sanity/sdk/collaboration";
|
|
4
|
+
/**
|
|
5
|
+
* @beta
|
|
6
|
+
* @category Types
|
|
7
|
+
* @category Comments
|
|
8
|
+
*/
|
|
9
|
+
interface CommentActions {
|
|
10
|
+
/** Starts a thread on one of a document's fields. */
|
|
11
|
+
createComment: (options: WithResourceNameSupport<CreateCommentOptions>) => Promise<Comment>;
|
|
12
|
+
/** Adds a reply to an existing thread. */
|
|
13
|
+
replyToComment: (options: WithResourceNameSupport<ReplyToCommentOptions>) => Promise<Comment>;
|
|
14
|
+
/** Rewrites a comment's message. */
|
|
15
|
+
updateComment: (options: WithResourceNameSupport<UpdateCommentOptions>) => Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Re-anchors a comment to a different run of text, without marking it edited.
|
|
18
|
+
*/
|
|
19
|
+
updateCommentAnchor: (options: WithResourceNameSupport<UpdateCommentAnchorOptions>) => Promise<void>;
|
|
20
|
+
/** Resolves or reopens a thread. Pass the thread's first comment. */
|
|
21
|
+
setCommentStatus: (options: WithResourceNameSupport<SetCommentStatusOptions>) => Promise<void>;
|
|
22
|
+
/** Deletes a comment, and its replies when it starts a thread. */
|
|
23
|
+
removeComment: (options: WithResourceNameSupport<RemoveCommentOptions>) => Promise<void>;
|
|
24
|
+
/** Adds the current user's reaction to a comment. */
|
|
25
|
+
addReaction: (options: WithResourceNameSupport<ReactionOptions>) => Promise<void>;
|
|
26
|
+
/** Removes the current user's reaction from a comment. */
|
|
27
|
+
removeReaction: (options: WithResourceNameSupport<ReactionOptions>) => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns the comment write actions, bound to the current instance.
|
|
31
|
+
*
|
|
32
|
+
* Each writes optimistically: the change shows immediately and is rolled back
|
|
33
|
+
* if the server rejects it, so an app can render straight from
|
|
34
|
+
* {@link useCommentThreads} without tracking pending state itself.
|
|
35
|
+
*
|
|
36
|
+
* Creating is the exception, and `replyToComment` counts as creating. A comment
|
|
37
|
+
* that fails to post stays on screen carrying `state.createError` rather than
|
|
38
|
+
* disappearing, so passing the same `commentId` again retries it instead of
|
|
39
|
+
* losing what someone typed.
|
|
40
|
+
*
|
|
41
|
+
* The resource is resolved when an action is called rather than when the hook
|
|
42
|
+
* runs, so one set of callbacks works across several resources. Pass `resource`
|
|
43
|
+
* or `resourceName` per call to choose; otherwise the surrounding
|
|
44
|
+
* `ResourceProvider` decides. The organization the comments live in is
|
|
45
|
+
* resolved per call as well: the one the Dashboard opened the app in, else
|
|
46
|
+
* `organizationId` on the Sanity config, else the organization owning the
|
|
47
|
+
* resource's project. It cannot be passed on the call.
|
|
48
|
+
*
|
|
49
|
+
* @category Comments
|
|
50
|
+
* @function
|
|
51
|
+
* @returns The write actions
|
|
52
|
+
*
|
|
53
|
+
* @example Resolve a thread
|
|
54
|
+
* ```tsx
|
|
55
|
+
* function ResolveButton({commentId}: {commentId: string}) {
|
|
56
|
+
* const {setCommentStatus} = useCommentActions()
|
|
57
|
+
*
|
|
58
|
+
* return (
|
|
59
|
+
* <button onClick={() => setCommentStatus({commentId, status: 'resolved'})}>
|
|
60
|
+
* Resolve
|
|
61
|
+
* </button>
|
|
62
|
+
* )
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @beta
|
|
67
|
+
*/
|
|
68
|
+
export declare function useCommentActions(): CommentActions;
|
|
69
|
+
/**
|
|
70
|
+
* @beta
|
|
71
|
+
* @category Types
|
|
72
|
+
* @category Comments
|
|
73
|
+
*/
|
|
74
|
+
interface UseCommentsResult {
|
|
75
|
+
/** Every matching comment, newest first, replies included. */
|
|
76
|
+
comments: Comment[];
|
|
77
|
+
/** True while switching to a different document or filter. */
|
|
78
|
+
isPending: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Set when the comments have stopped following the server: the listener
|
|
81
|
+
* failed after they had loaded, so what you are reading is the list as it
|
|
82
|
+
* last stood rather than as it is. Clears when a listener comes back.
|
|
83
|
+
*/
|
|
84
|
+
error?: unknown;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Reads a document's comments and keeps them up to date.
|
|
88
|
+
*
|
|
89
|
+
* The list is flat, replies included, which suits a count or a feed. Reach for
|
|
90
|
+
* {@link useCommentThreads} to read the same comments grouped, where a reply
|
|
91
|
+
* sits under the comment it answers and filtering by `status` or `fieldPath`
|
|
92
|
+
* selects whole threads rather than individual comments. Both read the same
|
|
93
|
+
* document and share a listener, so using them side by side costs nothing
|
|
94
|
+
* extra. {@link useCommentsQuery} covers anything that is not one document's
|
|
95
|
+
* comments.
|
|
96
|
+
*
|
|
97
|
+
* Suspends until the comments have loaded. Switching document or filter is a
|
|
98
|
+
* transition, so the previous list stays on screen and `isPending` goes true
|
|
99
|
+
* rather than the component suspending again.
|
|
100
|
+
*
|
|
101
|
+
* @category Comments
|
|
102
|
+
* @function
|
|
103
|
+
* @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`
|
|
104
|
+
* @returns The matching comments, and whether a switch is in flight
|
|
105
|
+
*
|
|
106
|
+
* @example Count the open comments on a field
|
|
107
|
+
* ```tsx
|
|
108
|
+
* function TitleCommentCount({documentId}: {documentId: string}) {
|
|
109
|
+
* const {comments} = useComments({
|
|
110
|
+
* documentId,
|
|
111
|
+
* documentType: 'article',
|
|
112
|
+
* fieldPath: 'title',
|
|
113
|
+
* status: 'open',
|
|
114
|
+
* })
|
|
115
|
+
*
|
|
116
|
+
* return <span>{comments.length}</span>
|
|
117
|
+
* }
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @beta
|
|
121
|
+
*/
|
|
122
|
+
export declare function useComments(options: WithResourceNameSupport<CommentsOptions>): UseCommentsResult;
|
|
123
|
+
/**
|
|
124
|
+
* @beta
|
|
125
|
+
* @category Types
|
|
126
|
+
*/
|
|
127
|
+
interface UseCommentsQueryResult {
|
|
128
|
+
/** Every matching comment, newest first, replies included. */
|
|
129
|
+
comments: Comment[];
|
|
130
|
+
/** True while switching to a different filter. */
|
|
131
|
+
isPending: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Set when the comments have stopped following the server: the listener
|
|
134
|
+
* failed after they had loaded, so what you are reading is the list as it
|
|
135
|
+
* last stood rather than as it is. Clears when a listener comes back.
|
|
136
|
+
*/
|
|
137
|
+
error?: unknown;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Reads comments matching a GROQ filter and keeps them up to date.
|
|
141
|
+
*
|
|
142
|
+
* The escape hatch for anything that is not "comments on this document":
|
|
143
|
+
* cross-document views, per-user views, organization-wide activity. The list is
|
|
144
|
+
* flat, replies included; reach for {@link useCommentThreads} to read one
|
|
145
|
+
* document's comments grouped into threads.
|
|
146
|
+
*
|
|
147
|
+
* `_type == "sanity.comment"` is applied for you. Comments are stored per
|
|
148
|
+
* organization, resolved rather than configured: the one the Dashboard opened
|
|
149
|
+
* the app in, else `organizationId` on the Sanity config, else the organization
|
|
150
|
+
* owning the resource's project. The filter runs over every comment that
|
|
151
|
+
* organization can read, not only the ones in the resource's dataset: comment
|
|
152
|
+
* queries are routed by organization and the resource is not sent with them.
|
|
153
|
+
* To keep to one dataset, add a `target.document._ref` prefix condition
|
|
154
|
+
* yourself. Refs are `dataset:{projectId}.{dataset}:{documentId}`.
|
|
155
|
+
*
|
|
156
|
+
* Suspends until the comments have loaded. Switching filter is a transition, so
|
|
157
|
+
* the previous list stays on screen and `isPending` goes true rather than the
|
|
158
|
+
* component suspending again.
|
|
159
|
+
*
|
|
160
|
+
* Writes show here before the server confirms them, the same as they do on a
|
|
161
|
+
* document's comments, because the filter is matched against the written
|
|
162
|
+
* comment locally. That holds for writes through the resource the query is
|
|
163
|
+
* bound to; comments written through another dataset arrive once the server
|
|
164
|
+
* confirms them. A filter that cannot be answered that way — one that
|
|
165
|
+
* dereferences, runs a `*[...]` of its own, or calls a context-dependent
|
|
166
|
+
* function such as `sanity::dataset()` or `now()` — still works, but only
|
|
167
|
+
* follows the server, and costs a connection of its own rather than sharing one.
|
|
168
|
+
*
|
|
169
|
+
* @category Comments
|
|
170
|
+
* @function
|
|
171
|
+
* @param options - The GROQ `filter` to match, and any `params` it reads
|
|
172
|
+
* @returns The matching comments, and whether a switch is in flight
|
|
173
|
+
*
|
|
174
|
+
* @example Every comment mentioning the current user
|
|
175
|
+
* ```tsx
|
|
176
|
+
* function Mentions({userId}: {userId: string}) {
|
|
177
|
+
* const {comments} = useCommentsQuery({
|
|
178
|
+
* filter: 'count(message[].children[_type == "mention" && userId == $userId]) > 0',
|
|
179
|
+
* params: {userId},
|
|
180
|
+
* })
|
|
181
|
+
*
|
|
182
|
+
* return <span>{comments.length}</span>
|
|
183
|
+
* }
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* @example Open comments in one dataset
|
|
187
|
+
* ```tsx
|
|
188
|
+
* function OpenInProduction() {
|
|
189
|
+
* const {comments} = useCommentsQuery({
|
|
190
|
+
* filter: 'string::startsWith(target.document._ref, $prefix) && status == "open"',
|
|
191
|
+
* params: {prefix: 'dataset:abc123.production:'},
|
|
192
|
+
* })
|
|
193
|
+
*
|
|
194
|
+
* return <span>{comments.length}</span>
|
|
195
|
+
* }
|
|
196
|
+
* ```
|
|
197
|
+
*
|
|
198
|
+
* @beta
|
|
199
|
+
*/
|
|
200
|
+
export declare function useCommentsQuery(options: WithResourceNameSupport<CommentsQueryOptions>): UseCommentsQueryResult;
|
|
201
|
+
/**
|
|
202
|
+
* @beta
|
|
203
|
+
* @category Types
|
|
204
|
+
* @category Comments
|
|
205
|
+
*/
|
|
206
|
+
interface UseCommentThreadsResult {
|
|
207
|
+
/** Matching threads, newest first, each with its replies oldest first. */
|
|
208
|
+
threads: CommentThread[];
|
|
209
|
+
/** True while switching to a different document or filter. */
|
|
210
|
+
isPending: boolean;
|
|
211
|
+
/**
|
|
212
|
+
* Set when the threads have stopped following the server: the listener
|
|
213
|
+
* failed after they had loaded, so what you are reading is the list as it
|
|
214
|
+
* last stood rather than as it is. Clears when a listener comes back.
|
|
215
|
+
*/
|
|
216
|
+
error?: unknown;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Reads a document's comment threads and keeps them up to date.
|
|
220
|
+
*
|
|
221
|
+
* A thread carries its first comment plus its replies, and `status` and
|
|
222
|
+
* `fieldPath` come from that first comment, so filtering by either selects
|
|
223
|
+
* whole threads. Use {@link useComments} to read the same list flat, `scope` to
|
|
224
|
+
* say which of the document's comments to cover — by default it follows the
|
|
225
|
+
* perspective in view — and {@link useCommentsQuery} when the question is not
|
|
226
|
+
* "comments on this document".
|
|
227
|
+
*
|
|
228
|
+
* Suspends until the comments have loaded. Switching document or filter is a
|
|
229
|
+
* transition, so the previous list stays on screen and `isPending` goes true
|
|
230
|
+
* rather than the component suspending again.
|
|
231
|
+
*
|
|
232
|
+
* @category Comments
|
|
233
|
+
* @function
|
|
234
|
+
* @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`
|
|
235
|
+
* @returns The matching threads, and whether a switch is in flight
|
|
236
|
+
*
|
|
237
|
+
* @example Count the open threads on a field
|
|
238
|
+
* ```tsx
|
|
239
|
+
* function TitleCommentCount({documentId}: {documentId: string}) {
|
|
240
|
+
* const {threads} = useCommentThreads({
|
|
241
|
+
* documentId,
|
|
242
|
+
* documentType: 'article',
|
|
243
|
+
* fieldPath: 'title',
|
|
244
|
+
* status: 'open',
|
|
245
|
+
* })
|
|
246
|
+
*
|
|
247
|
+
* return <span>{threads.length}</span>
|
|
248
|
+
* }
|
|
249
|
+
* ```
|
|
250
|
+
*
|
|
251
|
+
* @beta
|
|
252
|
+
*/
|
|
253
|
+
export declare function useCommentThreads(options: WithResourceNameSupport<CommentsOptions>): UseCommentThreadsResult;
|
|
254
|
+
export type { CommentActions, UseCommentThreadsResult, UseCommentsQueryResult, UseCommentsResult };
|
|
255
|
+
//# sourceMappingURL=collaboration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collaboration.d.ts","names":["Comment","CreateCommentOptions","ReactionOptions","RemoveCommentOptions","ReplyToCommentOptions","SetCommentStatusOptions","UpdateCommentAnchorOptions","UpdateCommentOptions","WithResourceNameSupport","CommentActions","Promise","useCommentActions","Comment","CommentsOptions","WithResourceNameSupport","UseCommentsResult","useComments","Comment","CommentsQueryOptions","WithResourceNameSupport","UseCommentsQueryResult","useCommentsQuery","CommentsOptions","CommentThread","WithResourceNameSupport","UseCommentThreadsResult","useCommentThreads"],"sources":["../../src/hooks/comments/useCommentActions.ts","../../src/hooks/comments/useComments.ts","../../src/hooks/comments/useCommentsQuery.ts","../../src/hooks/comments/useCommentThreads.ts"],"mappings":";;;;;;;;UAoCiBS;;EAEf,gBAAgB,SAASD,wBAAwBP,0BAA0BS,QAAQV;;EAEnF,iBAAiB,SAASQ,wBAAwBJ,2BAA2BM,QAAQV;;EAErF,gBAAgB,SAASQ,wBAAwBD,0BAA0BG;;;;EAI3E,sBACE,SAASF,wBAAwBF,gCAC9BI;;EAEL,mBAAmB,SAASF,wBAAwBH,6BAA6BK;;EAEjF,gBAAgB,SAASF,wBAAwBL,0BAA0BO;;EAE3E,cAAc,SAASF,wBAAwBN,qBAAqBQ;;EAEpE,iBAAiB,SAASF,wBAAwBN,qBAAqBQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAkDzDC,qBAAqBF;;;;;;UCxFpBM;;EAEf,UAAUH;;EAEV;;;;;;EAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA+CcI,YAAY,SAASF,wBAAwBD,mBAAmBE;;;;;UC1D/DK;;EAEf,UAAUH;;EAEV;;;;;;EAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAwEcI,iBACd,SAASF,wBAAwBD,wBAChCE;;;;;;UCnFcK;;EAEf,SAASF;;EAET;;;;;;EAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA8CcG,kBACd,SAASF,wBAAwBF,mBAChCG"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { t as useSanityInstance } from "../useSanityInstance-C0a_Ou_p.js";
|
|
2
|
+
import { a as useEffectiveContextResource, i as normalizeResourceOptions, l as ResourcesContext, n as trackHookUsage, s as PerspectiveContext, t as useCommentList } from "../useCommentList-CXi_IIwA.js";
|
|
3
|
+
import { c } from "react-compiler-runtime";
|
|
4
|
+
import "@sanity/sdk";
|
|
5
|
+
import { getCommentsQueryOptionsKey, getDocumentCommentsOptionsKey, parseCommentsQueryOptionsKey, parseDocumentCommentsOptionsKey } from "@sanity/sdk/_internal";
|
|
6
|
+
import { useContext } from "react";
|
|
7
|
+
import { addReaction, createComment as createComment$1, getCommentThreadsState as getCommentThreadsState$1, getCommentsErrorState, getCommentsQueryErrorState, getCommentsQueryState, getCommentsState as getCommentsState$1, removeComment as removeComment$1, removeReaction, replyToComment as replyToComment$1, resolveCommentThreads as resolveCommentThreads$1, resolveComments as resolveComments$1, resolveCommentsQuery, setCommentStatus as setCommentStatus$1, updateComment as updateComment$1, updateCommentAnchor } from "@sanity/sdk/collaboration";
|
|
8
|
+
export * from "@sanity/sdk/collaboration";
|
|
9
|
+
/**
|
|
10
|
+
* Returns the comment write actions, bound to the current instance.
|
|
11
|
+
*
|
|
12
|
+
* Each writes optimistically: the change shows immediately and is rolled back
|
|
13
|
+
* if the server rejects it, so an app can render straight from
|
|
14
|
+
* {@link useCommentThreads} without tracking pending state itself.
|
|
15
|
+
*
|
|
16
|
+
* Creating is the exception, and `replyToComment` counts as creating. A comment
|
|
17
|
+
* that fails to post stays on screen carrying `state.createError` rather than
|
|
18
|
+
* disappearing, so passing the same `commentId` again retries it instead of
|
|
19
|
+
* losing what someone typed.
|
|
20
|
+
*
|
|
21
|
+
* The resource is resolved when an action is called rather than when the hook
|
|
22
|
+
* runs, so one set of callbacks works across several resources. Pass `resource`
|
|
23
|
+
* or `resourceName` per call to choose; otherwise the surrounding
|
|
24
|
+
* `ResourceProvider` decides. The organization the comments live in is
|
|
25
|
+
* resolved per call as well: the one the Dashboard opened the app in, else
|
|
26
|
+
* `organizationId` on the Sanity config, else the organization owning the
|
|
27
|
+
* resource's project. It cannot be passed on the call.
|
|
28
|
+
*
|
|
29
|
+
* @category Comments
|
|
30
|
+
* @function
|
|
31
|
+
* @returns The write actions
|
|
32
|
+
*
|
|
33
|
+
* @example Resolve a thread
|
|
34
|
+
* ```tsx
|
|
35
|
+
* function ResolveButton({commentId}: {commentId: string}) {
|
|
36
|
+
* const {setCommentStatus} = useCommentActions()
|
|
37
|
+
*
|
|
38
|
+
* return (
|
|
39
|
+
* <button onClick={() => setCommentStatus({commentId, status: 'resolved'})}>
|
|
40
|
+
* Resolve
|
|
41
|
+
* </button>
|
|
42
|
+
* )
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @beta
|
|
47
|
+
*/
|
|
48
|
+
function useCommentActions() {
|
|
49
|
+
let $ = c(7), instance = useSanityInstance();
|
|
50
|
+
trackHookUsage(instance, "useCommentActions");
|
|
51
|
+
let resources = useContext(ResourcesContext), contextResource = useEffectiveContextResource(), contextPerspective = useContext(PerspectiveContext), t0;
|
|
52
|
+
$[0] !== contextPerspective || $[1] !== contextResource || $[2] !== resources ? (t0 = (options) => normalizeResourceOptions(options, resources, contextResource, contextPerspective), $[0] = contextPerspective, $[1] = contextResource, $[2] = resources, $[3] = t0) : t0 = $[3];
|
|
53
|
+
let resolve = t0, t1;
|
|
54
|
+
return $[4] !== instance || $[5] !== resolve ? (t1 = {
|
|
55
|
+
createComment: (options_0) => createComment$1(instance, resolve(options_0)),
|
|
56
|
+
replyToComment: (options_1) => replyToComment$1(instance, resolve(options_1)),
|
|
57
|
+
updateComment: (options_2) => updateComment$1(instance, resolve(options_2)),
|
|
58
|
+
updateCommentAnchor: (options_3) => updateCommentAnchor(instance, resolve(options_3)),
|
|
59
|
+
setCommentStatus: (options_4) => setCommentStatus$1(instance, resolve(options_4)),
|
|
60
|
+
removeComment: (options_5) => removeComment$1(instance, resolve(options_5)),
|
|
61
|
+
addReaction: (options_6) => addReaction(instance, resolve(options_6)),
|
|
62
|
+
removeReaction: (options_7) => removeReaction(instance, resolve(options_7))
|
|
63
|
+
}, $[4] = instance, $[5] = resolve, $[6] = t1) : t1 = $[6], t1;
|
|
64
|
+
}
|
|
65
|
+
const SOURCE$2 = {
|
|
66
|
+
getState: getCommentsState$1,
|
|
67
|
+
getErrorState: getCommentsErrorState,
|
|
68
|
+
resolve: resolveComments$1,
|
|
69
|
+
getKey: getDocumentCommentsOptionsKey,
|
|
70
|
+
parseKey: parseDocumentCommentsOptionsKey
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Reads a document's comments and keeps them up to date.
|
|
74
|
+
*
|
|
75
|
+
* The list is flat, replies included, which suits a count or a feed. Reach for
|
|
76
|
+
* {@link useCommentThreads} to read the same comments grouped, where a reply
|
|
77
|
+
* sits under the comment it answers and filtering by `status` or `fieldPath`
|
|
78
|
+
* selects whole threads rather than individual comments. Both read the same
|
|
79
|
+
* document and share a listener, so using them side by side costs nothing
|
|
80
|
+
* extra. {@link useCommentsQuery} covers anything that is not one document's
|
|
81
|
+
* comments.
|
|
82
|
+
*
|
|
83
|
+
* Suspends until the comments have loaded. Switching document or filter is a
|
|
84
|
+
* transition, so the previous list stays on screen and `isPending` goes true
|
|
85
|
+
* rather than the component suspending again.
|
|
86
|
+
*
|
|
87
|
+
* @category Comments
|
|
88
|
+
* @function
|
|
89
|
+
* @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`
|
|
90
|
+
* @returns The matching comments, and whether a switch is in flight
|
|
91
|
+
*
|
|
92
|
+
* @example Count the open comments on a field
|
|
93
|
+
* ```tsx
|
|
94
|
+
* function TitleCommentCount({documentId}: {documentId: string}) {
|
|
95
|
+
* const {comments} = useComments({
|
|
96
|
+
* documentId,
|
|
97
|
+
* documentType: 'article',
|
|
98
|
+
* fieldPath: 'title',
|
|
99
|
+
* status: 'open',
|
|
100
|
+
* })
|
|
101
|
+
*
|
|
102
|
+
* return <span>{comments.length}</span>
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @beta
|
|
107
|
+
*/
|
|
108
|
+
function useComments(options) {
|
|
109
|
+
let $ = c(4), { value, isPending, error } = useCommentList("useComments", options, SOURCE$2), t0;
|
|
110
|
+
return $[0] !== error || $[1] !== isPending || $[2] !== value ? (t0 = {
|
|
111
|
+
comments: value,
|
|
112
|
+
isPending,
|
|
113
|
+
error
|
|
114
|
+
}, $[0] = error, $[1] = isPending, $[2] = value, $[3] = t0) : t0 = $[3], t0;
|
|
115
|
+
}
|
|
116
|
+
const SOURCE$1 = {
|
|
117
|
+
getState: getCommentsQueryState,
|
|
118
|
+
getErrorState: getCommentsQueryErrorState,
|
|
119
|
+
resolve: resolveCommentsQuery,
|
|
120
|
+
getKey: getCommentsQueryOptionsKey,
|
|
121
|
+
parseKey: parseCommentsQueryOptionsKey
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Reads comments matching a GROQ filter and keeps them up to date.
|
|
125
|
+
*
|
|
126
|
+
* The escape hatch for anything that is not "comments on this document":
|
|
127
|
+
* cross-document views, per-user views, organization-wide activity. The list is
|
|
128
|
+
* flat, replies included; reach for {@link useCommentThreads} to read one
|
|
129
|
+
* document's comments grouped into threads.
|
|
130
|
+
*
|
|
131
|
+
* `_type == "sanity.comment"` is applied for you. Comments are stored per
|
|
132
|
+
* organization, resolved rather than configured: the one the Dashboard opened
|
|
133
|
+
* the app in, else `organizationId` on the Sanity config, else the organization
|
|
134
|
+
* owning the resource's project. The filter runs over every comment that
|
|
135
|
+
* organization can read, not only the ones in the resource's dataset: comment
|
|
136
|
+
* queries are routed by organization and the resource is not sent with them.
|
|
137
|
+
* To keep to one dataset, add a `target.document._ref` prefix condition
|
|
138
|
+
* yourself. Refs are `dataset:{projectId}.{dataset}:{documentId}`.
|
|
139
|
+
*
|
|
140
|
+
* Suspends until the comments have loaded. Switching filter is a transition, so
|
|
141
|
+
* the previous list stays on screen and `isPending` goes true rather than the
|
|
142
|
+
* component suspending again.
|
|
143
|
+
*
|
|
144
|
+
* Writes show here before the server confirms them, the same as they do on a
|
|
145
|
+
* document's comments, because the filter is matched against the written
|
|
146
|
+
* comment locally. That holds for writes through the resource the query is
|
|
147
|
+
* bound to; comments written through another dataset arrive once the server
|
|
148
|
+
* confirms them. A filter that cannot be answered that way — one that
|
|
149
|
+
* dereferences, runs a `*[...]` of its own, or calls a context-dependent
|
|
150
|
+
* function such as `sanity::dataset()` or `now()` — still works, but only
|
|
151
|
+
* follows the server, and costs a connection of its own rather than sharing one.
|
|
152
|
+
*
|
|
153
|
+
* @category Comments
|
|
154
|
+
* @function
|
|
155
|
+
* @param options - The GROQ `filter` to match, and any `params` it reads
|
|
156
|
+
* @returns The matching comments, and whether a switch is in flight
|
|
157
|
+
*
|
|
158
|
+
* @example Every comment mentioning the current user
|
|
159
|
+
* ```tsx
|
|
160
|
+
* function Mentions({userId}: {userId: string}) {
|
|
161
|
+
* const {comments} = useCommentsQuery({
|
|
162
|
+
* filter: 'count(message[].children[_type == "mention" && userId == $userId]) > 0',
|
|
163
|
+
* params: {userId},
|
|
164
|
+
* })
|
|
165
|
+
*
|
|
166
|
+
* return <span>{comments.length}</span>
|
|
167
|
+
* }
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* @example Open comments in one dataset
|
|
171
|
+
* ```tsx
|
|
172
|
+
* function OpenInProduction() {
|
|
173
|
+
* const {comments} = useCommentsQuery({
|
|
174
|
+
* filter: 'string::startsWith(target.document._ref, $prefix) && status == "open"',
|
|
175
|
+
* params: {prefix: 'dataset:abc123.production:'},
|
|
176
|
+
* })
|
|
177
|
+
*
|
|
178
|
+
* return <span>{comments.length}</span>
|
|
179
|
+
* }
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @beta
|
|
183
|
+
*/
|
|
184
|
+
function useCommentsQuery(options) {
|
|
185
|
+
let $ = c(4), { value, isPending, error } = useCommentList("useCommentsQuery", options, SOURCE$1), t0;
|
|
186
|
+
return $[0] !== error || $[1] !== isPending || $[2] !== value ? (t0 = {
|
|
187
|
+
comments: value,
|
|
188
|
+
isPending,
|
|
189
|
+
error
|
|
190
|
+
}, $[0] = error, $[1] = isPending, $[2] = value, $[3] = t0) : t0 = $[3], t0;
|
|
191
|
+
}
|
|
192
|
+
const SOURCE = {
|
|
193
|
+
getState: getCommentThreadsState$1,
|
|
194
|
+
getErrorState: getCommentsErrorState,
|
|
195
|
+
resolve: resolveCommentThreads$1,
|
|
196
|
+
getKey: getDocumentCommentsOptionsKey,
|
|
197
|
+
parseKey: parseDocumentCommentsOptionsKey
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Reads a document's comment threads and keeps them up to date.
|
|
201
|
+
*
|
|
202
|
+
* A thread carries its first comment plus its replies, and `status` and
|
|
203
|
+
* `fieldPath` come from that first comment, so filtering by either selects
|
|
204
|
+
* whole threads. Use {@link useComments} to read the same list flat, `scope` to
|
|
205
|
+
* say which of the document's comments to cover — by default it follows the
|
|
206
|
+
* perspective in view — and {@link useCommentsQuery} when the question is not
|
|
207
|
+
* "comments on this document".
|
|
208
|
+
*
|
|
209
|
+
* Suspends until the comments have loaded. Switching document or filter is a
|
|
210
|
+
* transition, so the previous list stays on screen and `isPending` goes true
|
|
211
|
+
* rather than the component suspending again.
|
|
212
|
+
*
|
|
213
|
+
* @category Comments
|
|
214
|
+
* @function
|
|
215
|
+
* @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`
|
|
216
|
+
* @returns The matching threads, and whether a switch is in flight
|
|
217
|
+
*
|
|
218
|
+
* @example Count the open threads on a field
|
|
219
|
+
* ```tsx
|
|
220
|
+
* function TitleCommentCount({documentId}: {documentId: string}) {
|
|
221
|
+
* const {threads} = useCommentThreads({
|
|
222
|
+
* documentId,
|
|
223
|
+
* documentType: 'article',
|
|
224
|
+
* fieldPath: 'title',
|
|
225
|
+
* status: 'open',
|
|
226
|
+
* })
|
|
227
|
+
*
|
|
228
|
+
* return <span>{threads.length}</span>
|
|
229
|
+
* }
|
|
230
|
+
* ```
|
|
231
|
+
*
|
|
232
|
+
* @beta
|
|
233
|
+
*/
|
|
234
|
+
function useCommentThreads(options) {
|
|
235
|
+
let $ = c(4), { value, isPending, error } = useCommentList("useCommentThreads", options, SOURCE), t0;
|
|
236
|
+
return $[0] !== error || $[1] !== isPending || $[2] !== value ? (t0 = {
|
|
237
|
+
threads: value,
|
|
238
|
+
isPending,
|
|
239
|
+
error
|
|
240
|
+
}, $[0] = error, $[1] = isPending, $[2] = value, $[3] = t0) : t0 = $[3], t0;
|
|
241
|
+
}
|
|
242
|
+
export { useCommentActions, useCommentThreads, useComments, useCommentsQuery };
|
|
243
|
+
|
|
244
|
+
//# sourceMappingURL=collaboration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collaboration.js","names":["DocumentResource","PerspectiveHandle","addReaction","Comment","createComment","CreateCommentOptions","ReactionOptions","removeComment","RemoveCommentOptions","removeReaction","replyToComment","ReplyToCommentOptions","setCommentStatus","SetCommentStatusOptions","updateComment","updateCommentAnchor","UpdateCommentAnchorOptions","UpdateCommentOptions","useContext","useMemo","PerspectiveContext","ResourcesContext","useSanityInstance","normalizeResourceOptions","useEffectiveContextResource","WithResourceNameSupport","trackHookUsage","CommentActions","options","Promise","Resolvable","resource","resourceName","projectId","dataset","perspective","useCommentActions","$","_c","instance","resources","contextResource","contextPerspective","t0","resolve","t1","options_0","options_1","options_2","options_3","options_4","options_5","options_6","options_7","_c","createComment","replyToComment","updateComment","setCommentStatus","removeComment","getDocumentCommentsOptionsKey","parseDocumentCommentsOptionsKey","Comment","CommentsOptions","getCommentsErrorState","getCommentsState","resolveComments","useMemo","WithResourceNameSupport","CommentListSource","useCommentList","UseCommentsResult","comments","isPending","error","SOURCE","getState","getErrorState","resolve","getKey","parseKey","useComments","options","$","_c","value","t0","SOURCE","getCommentsState","resolveComments","_c","getCommentsQueryOptionsKey","parseCommentsQueryOptionsKey","Comment","CommentsQueryOptions","getCommentsQueryErrorState","getCommentsQueryState","resolveCommentsQuery","useMemo","WithResourceNameSupport","CommentListSource","useCommentList","UseCommentsQueryResult","comments","isPending","error","SOURCE","getState","getErrorState","resolve","getKey","parseKey","useCommentsQuery","options","$","_c","value","t0","SOURCE","_c","getDocumentCommentsOptionsKey","parseDocumentCommentsOptionsKey","CommentsOptions","CommentThread","getCommentsErrorState","getCommentThreadsState","resolveCommentThreads","useMemo","WithResourceNameSupport","CommentListSource","useCommentList","UseCommentThreadsResult","threads","isPending","error","SOURCE","getState","getErrorState","resolve","getKey","parseKey","useCommentThreads","options","$","_c","value","t0","getCommentThreadsState","resolveCommentThreads","_c"],"sources":["../../src/hooks/comments/useCommentActions.ts","../../src/hooks/comments/useComments.ts","../../src/hooks/comments/useCommentsQuery.ts","../../src/hooks/comments/useCommentThreads.ts"],"sourcesContent":["import {type DocumentResource, type PerspectiveHandle} from '@sanity/sdk'\nimport {\n addReaction,\n type Comment,\n createComment,\n type CreateCommentOptions,\n type ReactionOptions,\n removeComment,\n type RemoveCommentOptions,\n removeReaction,\n replyToComment,\n type ReplyToCommentOptions,\n setCommentStatus,\n type SetCommentStatusOptions,\n updateComment,\n updateCommentAnchor,\n type UpdateCommentAnchorOptions,\n type UpdateCommentOptions,\n} from '@sanity/sdk/collaboration'\nimport {useContext, useMemo} from 'react'\n\nimport {PerspectiveContext} from '../../context/PerspectiveContext'\nimport {ResourcesContext} from '../../context/ResourcesContext'\nimport {useSanityInstance} from '../context/useSanityInstance'\nimport {\n normalizeResourceOptions,\n useEffectiveContextResource,\n type WithResourceNameSupport,\n} from '../helpers/useNormalizedResourceOptions'\nimport {trackHookUsage} from '../helpers/useTrackHookUsage'\n\n/**\n * @beta\n * @category Types\n * @category Comments\n */\nexport interface CommentActions {\n /** Starts a thread on one of a document's fields. */\n createComment: (options: WithResourceNameSupport<CreateCommentOptions>) => Promise<Comment>\n /** Adds a reply to an existing thread. */\n replyToComment: (options: WithResourceNameSupport<ReplyToCommentOptions>) => Promise<Comment>\n /** Rewrites a comment's message. */\n updateComment: (options: WithResourceNameSupport<UpdateCommentOptions>) => Promise<void>\n /**\n * Re-anchors a comment to a different run of text, without marking it edited.\n */\n updateCommentAnchor: (\n options: WithResourceNameSupport<UpdateCommentAnchorOptions>,\n ) => Promise<void>\n /** Resolves or reopens a thread. Pass the thread's first comment. */\n setCommentStatus: (options: WithResourceNameSupport<SetCommentStatusOptions>) => Promise<void>\n /** Deletes a comment, and its replies when it starts a thread. */\n removeComment: (options: WithResourceNameSupport<RemoveCommentOptions>) => Promise<void>\n /** Adds the current user's reaction to a comment. */\n addReaction: (options: WithResourceNameSupport<ReactionOptions>) => Promise<void>\n /** Removes the current user's reaction from a comment. */\n removeReaction: (options: WithResourceNameSupport<ReactionOptions>) => Promise<void>\n}\n\ntype Resolvable = {\n resource?: DocumentResource\n resourceName?: string\n projectId?: string\n dataset?: string\n perspective?: PerspectiveHandle['perspective']\n}\n\n/**\n * Returns the comment write actions, bound to the current instance.\n *\n * Each writes optimistically: the change shows immediately and is rolled back\n * if the server rejects it, so an app can render straight from\n * {@link useCommentThreads} without tracking pending state itself.\n *\n * Creating is the exception, and `replyToComment` counts as creating. A comment\n * that fails to post stays on screen carrying `state.createError` rather than\n * disappearing, so passing the same `commentId` again retries it instead of\n * losing what someone typed.\n *\n * The resource is resolved when an action is called rather than when the hook\n * runs, so one set of callbacks works across several resources. Pass `resource`\n * or `resourceName` per call to choose; otherwise the surrounding\n * `ResourceProvider` decides. The organization the comments live in is\n * resolved per call as well: the one the Dashboard opened the app in, else\n * `organizationId` on the Sanity config, else the organization owning the\n * resource's project. It cannot be passed on the call.\n *\n * @category Comments\n * @function\n * @returns The write actions\n *\n * @example Resolve a thread\n * ```tsx\n * function ResolveButton({commentId}: {commentId: string}) {\n * const {setCommentStatus} = useCommentActions()\n *\n * return (\n * <button onClick={() => setCommentStatus({commentId, status: 'resolved'})}>\n * Resolve\n * </button>\n * )\n * }\n * ```\n *\n * @beta\n */\nexport function useCommentActions(): CommentActions {\n const instance = useSanityInstance()\n trackHookUsage(instance, 'useCommentActions')\n\n const resources = useContext(ResourcesContext)\n const contextResource = useEffectiveContextResource()\n const contextPerspective = useContext(PerspectiveContext)\n\n return useMemo(() => {\n const resolve = <T extends Resolvable>(options: T) =>\n normalizeResourceOptions(options, resources, contextResource, contextPerspective)\n\n return {\n createComment: (options) => createComment(instance, resolve(options)),\n replyToComment: (options) => replyToComment(instance, resolve(options)),\n updateComment: (options) => updateComment(instance, resolve(options)),\n updateCommentAnchor: (options) => updateCommentAnchor(instance, resolve(options)),\n setCommentStatus: (options) => setCommentStatus(instance, resolve(options)),\n removeComment: (options) => removeComment(instance, resolve(options)),\n addReaction: (options) => addReaction(instance, resolve(options)),\n removeReaction: (options) => removeReaction(instance, resolve(options)),\n }\n }, [contextPerspective, contextResource, instance, resources])\n}\n","import {getDocumentCommentsOptionsKey, parseDocumentCommentsOptionsKey} from '@sanity/sdk/_internal'\nimport {\n type Comment,\n type CommentsOptions,\n getCommentsErrorState,\n getCommentsState,\n resolveComments,\n} from '@sanity/sdk/collaboration'\nimport {useMemo} from 'react'\n\nimport {type WithResourceNameSupport} from '../helpers/useNormalizedResourceOptions'\nimport {type CommentListSource, useCommentList} from './useCommentList'\n\n/**\n * @beta\n * @category Types\n * @category Comments\n */\nexport interface UseCommentsResult {\n /** Every matching comment, newest first, replies included. */\n comments: Comment[]\n /** True while switching to a different document or filter. */\n isPending: boolean\n /**\n * Set when the comments have stopped following the server: the listener\n * failed after they had loaded, so what you are reading is the list as it\n * last stood rather than as it is. Clears when a listener comes back.\n */\n error?: unknown\n}\n\nconst SOURCE: CommentListSource<CommentsOptions, Comment[]> = {\n getState: getCommentsState,\n getErrorState: getCommentsErrorState,\n resolve: resolveComments,\n getKey: getDocumentCommentsOptionsKey,\n parseKey: parseDocumentCommentsOptionsKey,\n}\n\n/**\n * Reads a document's comments and keeps them up to date.\n *\n * The list is flat, replies included, which suits a count or a feed. Reach for\n * {@link useCommentThreads} to read the same comments grouped, where a reply\n * sits under the comment it answers and filtering by `status` or `fieldPath`\n * selects whole threads rather than individual comments. Both read the same\n * document and share a listener, so using them side by side costs nothing\n * extra. {@link useCommentsQuery} covers anything that is not one document's\n * comments.\n *\n * Suspends until the comments have loaded. Switching document or filter is a\n * transition, so the previous list stays on screen and `isPending` goes true\n * rather than the component suspending again.\n *\n * @category Comments\n * @function\n * @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`\n * @returns The matching comments, and whether a switch is in flight\n *\n * @example Count the open comments on a field\n * ```tsx\n * function TitleCommentCount({documentId}: {documentId: string}) {\n * const {comments} = useComments({\n * documentId,\n * documentType: 'article',\n * fieldPath: 'title',\n * status: 'open',\n * })\n *\n * return <span>{comments.length}</span>\n * }\n * ```\n *\n * @beta\n */\nexport function useComments(options: WithResourceNameSupport<CommentsOptions>): UseCommentsResult {\n const {value, isPending, error} = useCommentList('useComments', options, SOURCE)\n return useMemo(() => ({comments: value, isPending, error}), [error, isPending, value])\n}\n","import {getCommentsQueryOptionsKey, parseCommentsQueryOptionsKey} from '@sanity/sdk/_internal'\nimport {\n type Comment,\n type CommentsQueryOptions,\n getCommentsQueryErrorState,\n getCommentsQueryState,\n resolveCommentsQuery,\n} from '@sanity/sdk/collaboration'\nimport {useMemo} from 'react'\n\nimport {type WithResourceNameSupport} from '../helpers/useNormalizedResourceOptions'\nimport {type CommentListSource, useCommentList} from './useCommentList'\n\n/**\n * @beta\n * @category Types\n */\nexport interface UseCommentsQueryResult {\n /** Every matching comment, newest first, replies included. */\n comments: Comment[]\n /** True while switching to a different filter. */\n isPending: boolean\n /**\n * Set when the comments have stopped following the server: the listener\n * failed after they had loaded, so what you are reading is the list as it\n * last stood rather than as it is. Clears when a listener comes back.\n */\n error?: unknown\n}\n\nconst SOURCE: CommentListSource<CommentsQueryOptions, Comment[]> = {\n getState: getCommentsQueryState,\n getErrorState: getCommentsQueryErrorState,\n resolve: resolveCommentsQuery,\n getKey: getCommentsQueryOptionsKey,\n parseKey: parseCommentsQueryOptionsKey,\n}\n\n/**\n * Reads comments matching a GROQ filter and keeps them up to date.\n *\n * The escape hatch for anything that is not \"comments on this document\":\n * cross-document views, per-user views, organization-wide activity. The list is\n * flat, replies included; reach for {@link useCommentThreads} to read one\n * document's comments grouped into threads.\n *\n * `_type == \"sanity.comment\"` is applied for you. Comments are stored per\n * organization, resolved rather than configured: the one the Dashboard opened\n * the app in, else `organizationId` on the Sanity config, else the organization\n * owning the resource's project. The filter runs over every comment that\n * organization can read, not only the ones in the resource's dataset: comment\n * queries are routed by organization and the resource is not sent with them.\n * To keep to one dataset, add a `target.document._ref` prefix condition\n * yourself. Refs are `dataset:{projectId}.{dataset}:{documentId}`.\n *\n * Suspends until the comments have loaded. Switching filter is a transition, so\n * the previous list stays on screen and `isPending` goes true rather than the\n * component suspending again.\n *\n * Writes show here before the server confirms them, the same as they do on a\n * document's comments, because the filter is matched against the written\n * comment locally. That holds for writes through the resource the query is\n * bound to; comments written through another dataset arrive once the server\n * confirms them. A filter that cannot be answered that way — one that\n * dereferences, runs a `*[...]` of its own, or calls a context-dependent\n * function such as `sanity::dataset()` or `now()` — still works, but only\n * follows the server, and costs a connection of its own rather than sharing one.\n *\n * @category Comments\n * @function\n * @param options - The GROQ `filter` to match, and any `params` it reads\n * @returns The matching comments, and whether a switch is in flight\n *\n * @example Every comment mentioning the current user\n * ```tsx\n * function Mentions({userId}: {userId: string}) {\n * const {comments} = useCommentsQuery({\n * filter: 'count(message[].children[_type == \"mention\" && userId == $userId]) > 0',\n * params: {userId},\n * })\n *\n * return <span>{comments.length}</span>\n * }\n * ```\n *\n * @example Open comments in one dataset\n * ```tsx\n * function OpenInProduction() {\n * const {comments} = useCommentsQuery({\n * filter: 'string::startsWith(target.document._ref, $prefix) && status == \"open\"',\n * params: {prefix: 'dataset:abc123.production:'},\n * })\n *\n * return <span>{comments.length}</span>\n * }\n * ```\n *\n * @beta\n */\nexport function useCommentsQuery(\n options: WithResourceNameSupport<CommentsQueryOptions>,\n): UseCommentsQueryResult {\n const {value, isPending, error} = useCommentList('useCommentsQuery', options, SOURCE)\n return useMemo(() => ({comments: value, isPending, error}), [error, isPending, value])\n}\n","import {getDocumentCommentsOptionsKey, parseDocumentCommentsOptionsKey} from '@sanity/sdk/_internal'\nimport {\n type CommentsOptions,\n type CommentThread,\n getCommentsErrorState,\n getCommentThreadsState,\n resolveCommentThreads,\n} from '@sanity/sdk/collaboration'\nimport {useMemo} from 'react'\n\nimport {type WithResourceNameSupport} from '../helpers/useNormalizedResourceOptions'\nimport {type CommentListSource, useCommentList} from './useCommentList'\n\n/**\n * @beta\n * @category Types\n * @category Comments\n */\nexport interface UseCommentThreadsResult {\n /** Matching threads, newest first, each with its replies oldest first. */\n threads: CommentThread[]\n /** True while switching to a different document or filter. */\n isPending: boolean\n /**\n * Set when the threads have stopped following the server: the listener\n * failed after they had loaded, so what you are reading is the list as it\n * last stood rather than as it is. Clears when a listener comes back.\n */\n error?: unknown\n}\n\nconst SOURCE: CommentListSource<CommentsOptions, CommentThread[]> = {\n getState: getCommentThreadsState,\n getErrorState: getCommentsErrorState,\n resolve: resolveCommentThreads,\n getKey: getDocumentCommentsOptionsKey,\n parseKey: parseDocumentCommentsOptionsKey,\n}\n\n/**\n * Reads a document's comment threads and keeps them up to date.\n *\n * A thread carries its first comment plus its replies, and `status` and\n * `fieldPath` come from that first comment, so filtering by either selects\n * whole threads. Use {@link useComments} to read the same list flat, `scope` to\n * say which of the document's comments to cover — by default it follows the\n * perspective in view — and {@link useCommentsQuery} when the question is not\n * \"comments on this document\".\n *\n * Suspends until the comments have loaded. Switching document or filter is a\n * transition, so the previous list stays on screen and `isPending` goes true\n * rather than the component suspending again.\n *\n * @category Comments\n * @function\n * @param options - The document to read, optionally narrowed by `fieldPath`, `status`, or `scope`\n * @returns The matching threads, and whether a switch is in flight\n *\n * @example Count the open threads on a field\n * ```tsx\n * function TitleCommentCount({documentId}: {documentId: string}) {\n * const {threads} = useCommentThreads({\n * documentId,\n * documentType: 'article',\n * fieldPath: 'title',\n * status: 'open',\n * })\n *\n * return <span>{threads.length}</span>\n * }\n * ```\n *\n * @beta\n */\nexport function useCommentThreads(\n options: WithResourceNameSupport<CommentsOptions>,\n): UseCommentThreadsResult {\n const {value, isPending, error} = useCommentList('useCommentThreads', options, SOURCE)\n return useMemo(() => ({threads: value, isPending, error}), [error, isPending, value])\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as useSanityInstance } from "../useSanityInstance-C0a_Ou_p.js";
|
|
2
|
+
import { a as DashboardTokenRefreshProvider, i as useOrganizationId, l as createStateSourceHook, n as useTopic, r as useEmit, s as useWindowConnection, t as useStudioWorkspacesByProjectIdDataset } from "../useStudioWorkspacesByProjectIdDataset-Cx-Q44d0.js";
|
|
2
3
|
import { c } from "react-compiler-runtime";
|
|
3
4
|
import "@sanity/sdk";
|
|
4
5
|
import { createLogger, getApplicationOrigin, getWorkerClient, isMessageBusEnvironment, requireDashboardMessageBus } from "@sanity/sdk/_internal";
|