convex-feedback 0.1.5 → 0.2.0-beta.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.
Files changed (69) hide show
  1. package/README.md +70 -27
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/client/api.d.ts +76 -1
  4. package/dist/client/api.d.ts.map +1 -1
  5. package/dist/client/config.d.ts +1 -1
  6. package/dist/client/index.d.ts +9 -5
  7. package/dist/client/index.d.ts.map +1 -1
  8. package/dist/client/index.js +253 -8
  9. package/dist/client/index.js.map +1 -1
  10. package/dist/component/_generated/api.d.ts +4 -0
  11. package/dist/component/_generated/api.d.ts.map +1 -1
  12. package/dist/component/_generated/api.js.map +1 -1
  13. package/dist/component/_generated/component.d.ts +293 -5
  14. package/dist/component/_generated/component.d.ts.map +1 -1
  15. package/dist/component/admin.d.ts +130 -0
  16. package/dist/component/admin.d.ts.map +1 -0
  17. package/dist/component/admin.js +125 -0
  18. package/dist/component/admin.js.map +1 -0
  19. package/dist/component/comments.d.ts +7 -5
  20. package/dist/component/comments.d.ts.map +1 -1
  21. package/dist/component/comments.js +3 -3
  22. package/dist/component/comments.js.map +1 -1
  23. package/dist/component/entries.d.ts +29 -18
  24. package/dist/component/entries.d.ts.map +1 -1
  25. package/dist/component/entries.js +27 -6
  26. package/dist/component/entries.js.map +1 -1
  27. package/dist/component/helpers.d.ts +3 -1
  28. package/dist/component/helpers.d.ts.map +1 -1
  29. package/dist/component/helpers.js +28 -0
  30. package/dist/component/helpers.js.map +1 -1
  31. package/dist/component/model.d.ts +140 -24
  32. package/dist/component/model.d.ts.map +1 -1
  33. package/dist/component/model.js +30 -1
  34. package/dist/component/model.js.map +1 -1
  35. package/dist/component/roadmap.d.ts +166 -0
  36. package/dist/component/roadmap.d.ts.map +1 -0
  37. package/dist/component/roadmap.js +534 -0
  38. package/dist/component/roadmap.js.map +1 -0
  39. package/dist/component/schema.d.ts +61 -5
  40. package/dist/component/schema.d.ts.map +1 -1
  41. package/dist/component/schema.js +48 -2
  42. package/dist/component/schema.js.map +1 -1
  43. package/dist/component/tags.d.ts +58 -0
  44. package/dist/component/tags.d.ts.map +1 -0
  45. package/dist/component/tags.js +216 -0
  46. package/dist/component/tags.js.map +1 -0
  47. package/dist/react/index.d.ts +169 -12
  48. package/dist/react/index.d.ts.map +1 -1
  49. package/dist/react/index.js +72 -1
  50. package/dist/react/index.js.map +1 -1
  51. package/dist/test.d.ts +61 -5
  52. package/dist/test.d.ts.map +1 -1
  53. package/package.json +1 -1
  54. package/src/client/README.md +1 -1
  55. package/src/client/api.ts +176 -0
  56. package/src/client/config.ts +1 -1
  57. package/src/client/index.ts +330 -13
  58. package/src/component/README.md +1 -1
  59. package/src/component/_generated/api.ts +4 -0
  60. package/src/component/_generated/component.ts +371 -9
  61. package/src/component/admin.ts +180 -0
  62. package/src/component/comments.ts +3 -2
  63. package/src/component/entries.ts +29 -5
  64. package/src/component/helpers.ts +44 -1
  65. package/src/component/model.ts +65 -4
  66. package/src/component/roadmap.ts +627 -0
  67. package/src/component/schema.ts +51 -1
  68. package/src/react/README.md +2 -2
  69. package/src/react/index.ts +139 -4
@@ -1,7 +1,7 @@
1
1
  # React hooks layer
2
2
 
3
- `createFeedbackHooks(api, options?)` binds the host application's public Convex API to headless React hooks.
3
+ `createFeedbackHooks(api?, options?)` binds the host application's public Convex API to headless React hooks. With no API argument it uses `anyApi.feedback`; pass a generated API namespace when the host module has another name.
4
4
 
5
- The hooks expose entries, search/similarity, lazy direct-child comment pagination, mutations, and the configured client page sizes. Reply queries are not mounted by the hook layer automatically; the UI decides when a comment is expanded.
5
+ The hooks expose public entries, search/similarity, lazy direct-child comment pagination, mutations, admin inbox queries, and roadmap operations. Reply queries are not mounted by the hook layer automatically; the UI decides when a comment is expanded.
6
6
 
7
7
  Page-size defaults are client concerns. The server-side component still enforces its configured hard maximum. Keep the two aligned when overriding defaults.
@@ -2,14 +2,17 @@
2
2
 
3
3
  import { usePaginatedQuery } from "convex-helpers/react";
4
4
  import { useMutation, useQuery } from "convex/react";
5
+ import { anyApi } from "convex/server";
5
6
 
6
7
  import type { FeedbackPublicApi } from "../client/api.js";
7
8
  import type {
8
9
  CommentSort,
9
10
  EntryKind,
11
+ EntryPriority,
10
12
  EntrySort,
11
13
  EntryStatus,
12
14
  EntryStatusFilter,
15
+ RoadmapStatus,
13
16
  SimilarEntriesResult,
14
17
  } from "../component/model.js";
15
18
 
@@ -23,7 +26,8 @@ import type {
23
26
  */
24
27
  export interface FeedbackHooksOptions {
25
28
  /**
26
- * Number of entries initially requested by `useEntries`.
29
+ * Number of entries initially requested by entry-list hooks, including the
30
+ * public board, admin inbox, admin search, and roadmap attachments.
27
31
  *
28
32
  * @default 20
29
33
  */
@@ -43,6 +47,13 @@ export interface FeedbackHooksOptions {
43
47
  * @default 10
44
48
  */
45
49
  replyPageSize?: number;
50
+
51
+ /**
52
+ * Number of roadmap items initially requested by `useRoadmap`.
53
+ *
54
+ * @default 30
55
+ */
56
+ roadmapPageSize?: number;
46
57
  }
47
58
 
48
59
  /**
@@ -136,6 +147,16 @@ export interface SearchEntriesArgs {
136
147
  limit?: number;
137
148
  }
138
149
 
150
+ export interface UseAdminEntriesArgs {
151
+ kinds?: readonly EntryKind[];
152
+ status?: EntryStatus;
153
+ priority?: EntryPriority;
154
+ }
155
+
156
+ export interface UseAdminSearchEntriesArgs extends UseAdminEntriesArgs {
157
+ searchQuery: string;
158
+ }
159
+
139
160
  /**
140
161
  * Arguments accepted by `useSimilarEntries`.
141
162
  */
@@ -200,6 +221,7 @@ function createFeedbackHooksImplementation<RateLimitResult>(
200
221
  const entryPageSize = positivePageSize(options.entryPageSize, 20);
201
222
  const commentPageSize = positivePageSize(options.commentPageSize, 20);
202
223
  const replyPageSize = positivePageSize(options.replyPageSize, 10);
224
+ const roadmapPageSize = positivePageSize(options.roadmapPageSize, 30);
203
225
 
204
226
  return {
205
227
  /**
@@ -210,6 +232,7 @@ function createFeedbackHooksImplementation<RateLimitResult>(
210
232
  entries: entryPageSize,
211
233
  comments: commentPageSize,
212
234
  replies: replyPageSize,
235
+ roadmap: roadmapPageSize,
213
236
  } as const,
214
237
 
215
238
  /**
@@ -268,6 +291,80 @@ function createFeedbackHooksImplementation<RateLimitResult>(
268
291
  return searchQuery.length === 0 ? [] : result;
269
292
  },
270
293
 
294
+ /** Returns whether the authenticated host actor is an admin. */
295
+ useIsAdmin() {
296
+ return useQuery(api.isAdmin, {});
297
+ },
298
+
299
+ /** Returns whether the current request has an authenticated actor. */
300
+ useIsAuthenticated() {
301
+ return useQuery(api.isAuthenticated, {});
302
+ },
303
+
304
+ /** Returns a cursor-paginated admin inbox with private triage relationships. */
305
+ useAdminEntries(args: UseAdminEntriesArgs = {}) {
306
+ return usePaginatedQuery(
307
+ api.adminListEntries,
308
+ {
309
+ ...(args.kinds === undefined ? {} : { kinds: [...args.kinds] }),
310
+ ...(args.status === undefined ? {} : { status: args.status }),
311
+ ...(args.priority === undefined ? {} : { priority: args.priority }),
312
+ },
313
+ { initialNumItems: entryPageSize },
314
+ );
315
+ },
316
+
317
+ /** Returns one admin-enriched feedback entry. */
318
+ useAdminEntry(entryId: string | null | undefined) {
319
+ return useQuery(
320
+ api.adminGetEntry,
321
+ entryId === null || entryId === undefined ? "skip" : { entryId },
322
+ );
323
+ },
324
+
325
+ /** Searches the admin inbox with triage filters. */
326
+ useAdminSearchEntries(args: UseAdminSearchEntriesArgs) {
327
+ const searchQuery = args.searchQuery.trim();
328
+ return usePaginatedQuery(
329
+ api.adminSearchEntries,
330
+ searchQuery.length === 0
331
+ ? "skip"
332
+ : {
333
+ searchQuery,
334
+ ...(args.kinds === undefined ? {} : { kinds: [...args.kinds] }),
335
+ ...(args.status === undefined ? {} : { status: args.status }),
336
+ ...(args.priority === undefined
337
+ ? {}
338
+ : { priority: args.priority }),
339
+ },
340
+ { initialNumItems: entryPageSize },
341
+ );
342
+ },
343
+
344
+ useRoadmap(status?: RoadmapStatus) {
345
+ return usePaginatedQuery(
346
+ api.listRoadmap,
347
+ status === undefined ? {} : { status },
348
+ { initialNumItems: roadmapPageSize },
349
+ );
350
+ },
351
+
352
+ useSearchRoadmap(searchQuery: string, limit = 10) {
353
+ const normalized = searchQuery.trim();
354
+ return useQuery(
355
+ api.searchRoadmap,
356
+ normalized.length === 0 ? "skip" : { searchQuery: normalized, limit },
357
+ );
358
+ },
359
+
360
+ useRoadmapFeedback(roadmapId: string | null | undefined) {
361
+ return usePaginatedQuery(
362
+ api.listRoadmapFeedback,
363
+ roadmapId === null || roadmapId === undefined ? "skip" : { roadmapId },
364
+ { initialNumItems: entryPageSize },
365
+ );
366
+ },
367
+
271
368
  /**
272
369
  * Reactively finds exact and similar entries for a proposed draft.
273
370
  *
@@ -320,6 +417,38 @@ function createFeedbackHooksImplementation<RateLimitResult>(
320
417
  return useMutation(api.setEntryStatus);
321
418
  },
322
419
 
420
+ useSetEntryPriority() {
421
+ return useMutation(api.setEntryPriority);
422
+ },
423
+
424
+ useCreateRoadmap() {
425
+ return useMutation(api.createRoadmap);
426
+ },
427
+
428
+ useCreateRoadmapForEntry() {
429
+ return useMutation(api.createRoadmapForEntry);
430
+ },
431
+
432
+ useUpdateRoadmap() {
433
+ return useMutation(api.updateRoadmap);
434
+ },
435
+
436
+ useDeleteRoadmap() {
437
+ return useMutation(api.deleteRoadmap);
438
+ },
439
+
440
+ useMoveRoadmapItem() {
441
+ return useMutation(api.moveRoadmapItem);
442
+ },
443
+
444
+ useAttachFeedbackToRoadmap() {
445
+ return useMutation(api.attachFeedbackToRoadmap);
446
+ },
447
+
448
+ useDetachFeedbackFromRoadmap() {
449
+ return useMutation(api.detachFeedbackFromRoadmap);
450
+ },
451
+
323
452
  /** Returns the idempotent entry-upvote state mutation. */
324
453
  useSetEntryUpvote() {
325
454
  return useMutation(api.setEntryUpvote);
@@ -353,18 +482,24 @@ type CreatedFeedbackHooks<RateLimitResult> = ReturnType<
353
482
 
354
483
  /** Creates hooks for a feedback API whose rate limiters reject by throwing. */
355
484
  export function createFeedbackHooks(
356
- api: FeedbackPublicApi<string | undefined, never>,
485
+ api?: FeedbackPublicApi<string | undefined, never>,
357
486
  options?: FeedbackHooksOptions,
358
487
  ): CreatedFeedbackHooks<never>;
359
488
 
360
489
  /** Creates hooks carrying a validated non-throwing rate-limit result. */
361
490
  export function createFeedbackHooks<RateLimitResult>(
362
- api: FeedbackPublicApi<string | undefined, RateLimitResult>,
491
+ api?: FeedbackPublicApi<string | undefined, RateLimitResult>,
363
492
  options?: FeedbackHooksOptions,
364
493
  ): CreatedFeedbackHooks<RateLimitResult>;
365
494
 
366
495
  export function createFeedbackHooks<RateLimitResult>(
367
- api: FeedbackPublicApi<string | undefined, RateLimitResult>,
496
+ api: FeedbackPublicApi<
497
+ string | undefined,
498
+ RateLimitResult
499
+ > = anyApi.feedback as unknown as FeedbackPublicApi<
500
+ string | undefined,
501
+ RateLimitResult
502
+ >,
368
503
  options: FeedbackHooksOptions = {},
369
504
  ): CreatedFeedbackHooks<RateLimitResult> {
370
505
  return createFeedbackHooksImplementation(api, options);