@workhive/api 1.3.3 → 1.4.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 (105) hide show
  1. package/dist/client.d.ts +160 -6
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +253 -12
  4. package/dist/context.d.ts +122 -3
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/hooks/index.d.ts +24 -1
  7. package/dist/hooks/index.d.ts.map +1 -1
  8. package/dist/hooks/index.js +20 -1
  9. package/dist/hooks/use-billing-status.d.ts +7 -0
  10. package/dist/hooks/use-billing-status.d.ts.map +1 -0
  11. package/dist/hooks/use-billing-status.js +17 -0
  12. package/dist/hooks/use-card.d.ts +2 -0
  13. package/dist/hooks/use-card.d.ts.map +1 -0
  14. package/dist/hooks/use-card.js +12 -0
  15. package/dist/hooks/use-cards.d.ts +5 -0
  16. package/dist/hooks/use-cards.d.ts.map +1 -0
  17. package/dist/hooks/use-cards.js +12 -0
  18. package/dist/hooks/use-create-card.d.ts +10 -0
  19. package/dist/hooks/use-create-card.d.ts.map +1 -0
  20. package/dist/hooks/use-create-card.js +13 -0
  21. package/dist/hooks/use-delete-card.d.ts +15 -0
  22. package/dist/hooks/use-delete-card.d.ts.map +1 -0
  23. package/dist/hooks/use-delete-card.js +38 -0
  24. package/dist/hooks/use-email-drafts.d.ts +32 -0
  25. package/dist/hooks/use-email-drafts.d.ts.map +1 -0
  26. package/dist/hooks/use-email-drafts.js +98 -0
  27. package/dist/hooks/use-gmail-connection-members.d.ts +2 -0
  28. package/dist/hooks/use-gmail-connection-members.d.ts.map +1 -0
  29. package/dist/hooks/use-gmail-connection-members.js +13 -0
  30. package/dist/hooks/use-gmail-connections.d.ts +5 -0
  31. package/dist/hooks/use-gmail-connections.d.ts.map +1 -0
  32. package/dist/hooks/use-gmail-connections.js +21 -0
  33. package/dist/hooks/use-gmail-messages.d.ts +2 -0
  34. package/dist/hooks/use-gmail-messages.d.ts.map +1 -0
  35. package/dist/hooks/use-gmail-messages.js +13 -0
  36. package/dist/hooks/use-gmail-signature.d.ts +2 -0
  37. package/dist/hooks/use-gmail-signature.d.ts.map +1 -0
  38. package/dist/hooks/use-gmail-signature.js +12 -0
  39. package/dist/hooks/use-gmail-thread-search-infinite.d.ts +2 -0
  40. package/dist/hooks/use-gmail-thread-search-infinite.d.ts.map +1 -0
  41. package/dist/hooks/use-gmail-thread-search-infinite.js +21 -0
  42. package/dist/hooks/use-gmail-thread-search.d.ts +2 -0
  43. package/dist/hooks/use-gmail-thread-search.d.ts.map +1 -0
  44. package/dist/hooks/use-gmail-thread-search.js +12 -0
  45. package/dist/hooks/use-gmail-threads-infinite.d.ts +5 -0
  46. package/dist/hooks/use-gmail-threads-infinite.d.ts.map +1 -0
  47. package/dist/hooks/use-gmail-threads-infinite.js +24 -0
  48. package/dist/hooks/use-gmail-threads.d.ts +7 -0
  49. package/dist/hooks/use-gmail-threads.d.ts.map +1 -0
  50. package/dist/hooks/use-gmail-threads.js +23 -0
  51. package/dist/hooks/use-inbox-badge-count.d.ts +6 -0
  52. package/dist/hooks/use-inbox-badge-count.d.ts.map +1 -0
  53. package/dist/hooks/use-inbox-badge-count.js +17 -0
  54. package/dist/hooks/use-inbox-thread-search.d.ts +2 -0
  55. package/dist/hooks/use-inbox-thread-search.d.ts.map +1 -0
  56. package/dist/hooks/use-inbox-thread-search.js +12 -0
  57. package/dist/hooks/use-inbox-threads-infinite.d.ts.map +1 -1
  58. package/dist/hooks/use-inbox-threads-infinite.js +1 -0
  59. package/dist/hooks/use-link-gmail-thread-contact.d.ts +7 -0
  60. package/dist/hooks/use-link-gmail-thread-contact.d.ts.map +1 -0
  61. package/dist/hooks/use-link-gmail-thread-contact.js +15 -0
  62. package/dist/hooks/use-manage-gmail-connection-members.d.ts +13 -0
  63. package/dist/hooks/use-manage-gmail-connection-members.d.ts.map +1 -0
  64. package/dist/hooks/use-manage-gmail-connection-members.js +25 -0
  65. package/dist/hooks/use-mark-inbox-thread-read.d.ts +3 -1
  66. package/dist/hooks/use-mark-inbox-thread-read.d.ts.map +1 -1
  67. package/dist/hooks/use-mark-inbox-thread-read.js +36 -14
  68. package/dist/hooks/use-mark-inbox-thread-unread.d.ts +3 -1
  69. package/dist/hooks/use-mark-inbox-thread-unread.d.ts.map +1 -1
  70. package/dist/hooks/use-mark-inbox-thread-unread.js +37 -14
  71. package/dist/hooks/use-me.d.ts.map +1 -1
  72. package/dist/hooks/use-me.js +2 -1
  73. package/dist/hooks/use-message-snippets.d.ts +1 -1
  74. package/dist/hooks/use-message-snippets.d.ts.map +1 -1
  75. package/dist/hooks/use-message-snippets.js +4 -3
  76. package/dist/hooks/use-missed-unseen-count.d.ts +8 -0
  77. package/dist/hooks/use-missed-unseen-count.d.ts.map +1 -0
  78. package/dist/hooks/use-missed-unseen-count.js +19 -0
  79. package/dist/hooks/use-patch-card.d.ts +15 -0
  80. package/dist/hooks/use-patch-card.d.ts.map +1 -0
  81. package/dist/hooks/use-patch-card.js +48 -0
  82. package/dist/hooks/use-phone-number.d.ts.map +1 -1
  83. package/dist/hooks/use-phone-number.js +2 -1
  84. package/dist/hooks/use-phone-numbers.d.ts.map +1 -1
  85. package/dist/hooks/use-phone-numbers.js +2 -1
  86. package/dist/hooks/use-send-gmail-message.d.ts +6 -0
  87. package/dist/hooks/use-send-gmail-message.d.ts.map +1 -0
  88. package/dist/hooks/use-send-gmail-message.js +21 -0
  89. package/dist/hooks/use-send-inbox-message.d.ts.map +1 -1
  90. package/dist/hooks/use-send-inbox-message.js +16 -13
  91. package/dist/hooks/use-tasks.d.ts +4 -0
  92. package/dist/hooks/use-tasks.d.ts.map +1 -1
  93. package/dist/hooks/use-tasks.js +14 -2
  94. package/dist/hooks/use-update-inbox-thread-status.d.ts +3 -1
  95. package/dist/hooks/use-update-inbox-thread-status.d.ts.map +1 -1
  96. package/dist/hooks/use-update-inbox-thread-status.js +36 -14
  97. package/dist/index.d.ts +5 -5
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +3 -3
  100. package/dist/query-keys.d.ts +58 -0
  101. package/dist/query-keys.d.ts.map +1 -1
  102. package/dist/query-keys.js +50 -0
  103. package/dist/types.d.ts +402 -14
  104. package/dist/types.d.ts.map +1 -1
  105. package/package.json +1 -1
@@ -0,0 +1,7 @@
1
+ import type { LinkGmailThreadContactPayload } from '../types';
2
+ export declare function useLinkGmailThreadContact(): import("@tanstack/react-query").UseMutationResult<import("..").LinkGmailThreadContactResponse, Error, {
3
+ connectionId: string;
4
+ threadId: string;
5
+ body: LinkGmailThreadContactPayload;
6
+ }, unknown>;
7
+ //# sourceMappingURL=use-link-gmail-thread-contact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-link-gmail-thread-contact.d.ts","sourceRoot":"","sources":["../../src/hooks/use-link-gmail-thread-contact.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAA;AAE7D,wBAAgB,yBAAyB;kBAUrB,MAAM;cACV,MAAM;UACV,6BAA6B;YAQxC"}
@@ -0,0 +1,15 @@
1
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
2
+ import { useApiClient } from '../context';
3
+ import { gmailKeys } from '../query-keys';
4
+ export function useLinkGmailThreadContact() {
5
+ const client = useApiClient();
6
+ const queryClient = useQueryClient();
7
+ return useMutation({
8
+ mutationFn: ({ connectionId, threadId, body, }) => client.linkGmailThreadContact(connectionId, threadId, body),
9
+ onSuccess: () => {
10
+ queryClient.invalidateQueries({
11
+ queryKey: gmailKeys.threadsInfinitePrefix,
12
+ });
13
+ },
14
+ });
15
+ }
@@ -0,0 +1,13 @@
1
+ export declare function useAddGmailConnectionMember(): import("@tanstack/react-query").UseMutationResult<{
2
+ member: import("..").GmailConnectionMember;
3
+ }, Error, {
4
+ connectionId: string;
5
+ userId: string;
6
+ }, unknown>;
7
+ export declare function useRemoveGmailConnectionMember(): import("@tanstack/react-query").UseMutationResult<{
8
+ success: boolean;
9
+ }, Error, {
10
+ connectionId: string;
11
+ userId: string;
12
+ }, unknown>;
13
+ //# sourceMappingURL=use-manage-gmail-connection-members.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-manage-gmail-connection-members.d.ts","sourceRoot":"","sources":["../../src/hooks/use-manage-gmail-connection-members.ts"],"names":[],"mappings":"AAIA,wBAAgB,2BAA2B;;;kBAKgB,MAAM;YAAU,MAAM;YAOhF;AAED,wBAAgB,8BAA8B;;;kBAKa,MAAM;YAAU,MAAM;YAOhF"}
@@ -0,0 +1,25 @@
1
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
2
+ import { useApiClient } from '../context';
3
+ import { gmailKeys } from '../query-keys';
4
+ export function useAddGmailConnectionMember() {
5
+ const client = useApiClient();
6
+ const queryClient = useQueryClient();
7
+ return useMutation({
8
+ mutationFn: ({ connectionId, userId }) => client.addGmailConnectionMember(connectionId, userId),
9
+ onSuccess: (_data, variables) => {
10
+ queryClient.invalidateQueries({ queryKey: gmailKeys.members(variables.connectionId) });
11
+ queryClient.invalidateQueries({ queryKey: gmailKeys.connections() });
12
+ },
13
+ });
14
+ }
15
+ export function useRemoveGmailConnectionMember() {
16
+ const client = useApiClient();
17
+ const queryClient = useQueryClient();
18
+ return useMutation({
19
+ mutationFn: ({ connectionId, userId }) => client.removeGmailConnectionMember(connectionId, userId),
20
+ onSuccess: (_data, variables) => {
21
+ queryClient.invalidateQueries({ queryKey: gmailKeys.members(variables.connectionId) });
22
+ queryClient.invalidateQueries({ queryKey: gmailKeys.connections() });
23
+ },
24
+ });
25
+ }
@@ -1,7 +1,9 @@
1
+ import { type InfiniteData } from '@tanstack/react-query';
1
2
  import type { InboxThreadsResponse } from '../types';
2
3
  export declare function useMarkInboxThreadRead(): import("@tanstack/react-query").UseMutationResult<{
3
4
  ok: true;
4
5
  }, Error, string, {
5
- previous: [readonly unknown[], InboxThreadsResponse | undefined][];
6
+ previousSms: [readonly unknown[], InfiniteData<InboxThreadsResponse, unknown> | undefined][];
7
+ previousGmail: [readonly unknown[], InfiniteData<InboxThreadsResponse, unknown> | undefined][];
6
8
  }>;
7
9
  //# sourceMappingURL=use-mark-inbox-thread-read.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-mark-inbox-thread-read.d.ts","sourceRoot":"","sources":["../../src/hooks/use-mark-inbox-thread-read.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAIpD,wBAAgB,sBAAsB;;;;GAmCrC"}
1
+ {"version":3,"file":"use-mark-inbox-thread-read.d.ts","sourceRoot":"","sources":["../../src/hooks/use-mark-inbox-thread-read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAA+B,MAAM,uBAAuB,CAAA;AAGtF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AA0BpD,wBAAgB,sBAAsB;;;;;GA4CrC"}
@@ -1,35 +1,57 @@
1
1
  import { useMutation, useQueryClient } from '@tanstack/react-query';
2
2
  import { useApiClient } from '../context';
3
- const THREADS_QUERY_KEY_PREFIX = ['inbox', 'threads'];
3
+ import { inboxKeys, gmailKeys } from '../query-keys';
4
+ /** Optimistically set unread_count on a thread across a query cache prefix. */
5
+ function setUnreadOnThread(queryClient, queryKeyPrefix, threadId, unreadCount) {
6
+ queryClient.setQueriesData({ queryKey: queryKeyPrefix, exact: false }, (data) => {
7
+ if (!data?.pages)
8
+ return data;
9
+ return {
10
+ ...data,
11
+ pages: data.pages.map((page) => ({
12
+ ...page,
13
+ threads: page.threads.map((t) => t.id === threadId ? { ...t, unread_count: unreadCount } : t),
14
+ })),
15
+ };
16
+ });
17
+ }
4
18
  export function useMarkInboxThreadRead() {
5
19
  const client = useApiClient();
6
20
  const queryClient = useQueryClient();
7
21
  return useMutation({
8
22
  mutationFn: (threadId) => client.markInboxThreadRead(threadId),
9
23
  onMutate: async (threadId) => {
10
- const previous = queryClient.getQueriesData({
11
- queryKey: THREADS_QUERY_KEY_PREFIX,
24
+ await queryClient.cancelQueries({ queryKey: inboxKeys.threadsInfinitePrefix });
25
+ await queryClient.cancelQueries({ queryKey: gmailKeys.threadsInfinitePrefix });
26
+ const previousSms = queryClient.getQueriesData({
27
+ queryKey: inboxKeys.threadsInfinitePrefix,
12
28
  exact: false,
13
29
  });
14
- queryClient.setQueriesData({ queryKey: THREADS_QUERY_KEY_PREFIX, exact: false }, (data) => {
15
- if (!data?.threads?.length)
16
- return data;
17
- return {
18
- threads: data.threads.map((t) => t.id === threadId ? { ...t, unread_count: 0 } : t),
19
- };
30
+ const previousGmail = queryClient.getQueriesData({
31
+ queryKey: gmailKeys.threadsInfinitePrefix,
32
+ exact: false,
20
33
  });
21
- return { previous };
34
+ setUnreadOnThread(queryClient, inboxKeys.threadsInfinitePrefix, threadId, 0);
35
+ setUnreadOnThread(queryClient, gmailKeys.threadsInfinitePrefix, threadId, 0);
36
+ return { previousSms, previousGmail };
22
37
  },
23
38
  onError: (_err, _variables, context) => {
24
- if (context?.previous) {
25
- context.previous.forEach(([queryKey, data]) => {
39
+ if (context?.previousSms) {
40
+ context.previousSms.forEach(([queryKey, data]) => {
41
+ queryClient.setQueryData(queryKey, data);
42
+ });
43
+ }
44
+ if (context?.previousGmail) {
45
+ context.previousGmail.forEach(([queryKey, data]) => {
26
46
  queryClient.setQueryData(queryKey, data);
27
47
  });
28
48
  }
29
49
  },
30
50
  onSettled: () => {
31
- queryClient.invalidateQueries({ queryKey: THREADS_QUERY_KEY_PREFIX });
32
- queryClient.invalidateQueries({ queryKey: ['inbox', 'threads-infinite'] });
51
+ queryClient.invalidateQueries({ queryKey: inboxKeys.threadsInfinitePrefix });
52
+ queryClient.invalidateQueries({ queryKey: inboxKeys.threads() });
53
+ queryClient.invalidateQueries({ queryKey: inboxKeys.badgeCount() });
54
+ queryClient.invalidateQueries({ queryKey: gmailKeys.threadsInfinitePrefix });
33
55
  },
34
56
  });
35
57
  }
@@ -1,7 +1,9 @@
1
+ import { type InfiniteData } from '@tanstack/react-query';
1
2
  import type { InboxThreadsResponse } from '../types';
2
3
  export declare function useMarkInboxThreadUnread(): import("@tanstack/react-query").UseMutationResult<{
3
4
  ok: true;
4
5
  }, Error, string, {
5
- previous: [readonly unknown[], InboxThreadsResponse | undefined][];
6
+ previousSms: [readonly unknown[], InfiniteData<InboxThreadsResponse, unknown> | undefined][];
7
+ previousGmail: [readonly unknown[], InfiniteData<InboxThreadsResponse, unknown> | undefined][];
6
8
  }>;
7
9
  //# sourceMappingURL=use-mark-inbox-thread-unread.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-mark-inbox-thread-unread.d.ts","sourceRoot":"","sources":["../../src/hooks/use-mark-inbox-thread-unread.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAIpD,wBAAgB,wBAAwB;;;;GAmCvC"}
1
+ {"version":3,"file":"use-mark-inbox-thread-unread.d.ts","sourceRoot":"","sources":["../../src/hooks/use-mark-inbox-thread-unread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAA+B,MAAM,uBAAuB,CAAA;AAItF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AA0BpD,wBAAgB,wBAAwB;;;;;GA4CvC"}
@@ -1,35 +1,58 @@
1
1
  import { useMutation, useQueryClient } from '@tanstack/react-query';
2
2
  import { useApiClient } from '../context';
3
- const THREADS_QUERY_KEY_PREFIX = ['inbox', 'threads'];
3
+ import { inboxKeys } from '../query-keys';
4
+ import { gmailKeys } from '../query-keys';
5
+ /** Optimistically set unread_count on a thread across both SMS and Gmail query caches. */
6
+ function setUnreadOnThread(queryClient, queryKeyPrefix, threadId, unreadCount) {
7
+ queryClient.setQueriesData({ queryKey: queryKeyPrefix, exact: false }, (data) => {
8
+ if (!data?.pages)
9
+ return data;
10
+ return {
11
+ ...data,
12
+ pages: data.pages.map((page) => ({
13
+ ...page,
14
+ threads: page.threads.map((t) => t.id === threadId ? { ...t, unread_count: unreadCount } : t),
15
+ })),
16
+ };
17
+ });
18
+ }
4
19
  export function useMarkInboxThreadUnread() {
5
20
  const client = useApiClient();
6
21
  const queryClient = useQueryClient();
7
22
  return useMutation({
8
23
  mutationFn: (threadId) => client.markInboxThreadUnread(threadId),
9
24
  onMutate: async (threadId) => {
10
- const previous = queryClient.getQueriesData({
11
- queryKey: THREADS_QUERY_KEY_PREFIX,
25
+ await queryClient.cancelQueries({ queryKey: inboxKeys.threadsInfinitePrefix });
26
+ await queryClient.cancelQueries({ queryKey: gmailKeys.threadsInfinitePrefix });
27
+ const previousSms = queryClient.getQueriesData({
28
+ queryKey: inboxKeys.threadsInfinitePrefix,
12
29
  exact: false,
13
30
  });
14
- queryClient.setQueriesData({ queryKey: THREADS_QUERY_KEY_PREFIX, exact: false }, (data) => {
15
- if (!data?.threads?.length)
16
- return data;
17
- return {
18
- threads: data.threads.map((t) => t.id === threadId ? { ...t, unread_count: (t.unread_count ?? 0) || 1 } : t),
19
- };
31
+ const previousGmail = queryClient.getQueriesData({
32
+ queryKey: gmailKeys.threadsInfinitePrefix,
33
+ exact: false,
20
34
  });
21
- return { previous };
35
+ setUnreadOnThread(queryClient, inboxKeys.threadsInfinitePrefix, threadId, 1);
36
+ setUnreadOnThread(queryClient, gmailKeys.threadsInfinitePrefix, threadId, 1);
37
+ return { previousSms, previousGmail };
22
38
  },
23
39
  onError: (_err, _variables, context) => {
24
- if (context?.previous) {
25
- context.previous.forEach(([queryKey, data]) => {
40
+ if (context?.previousSms) {
41
+ context.previousSms.forEach(([queryKey, data]) => {
42
+ queryClient.setQueryData(queryKey, data);
43
+ });
44
+ }
45
+ if (context?.previousGmail) {
46
+ context.previousGmail.forEach(([queryKey, data]) => {
26
47
  queryClient.setQueryData(queryKey, data);
27
48
  });
28
49
  }
29
50
  },
30
51
  onSettled: () => {
31
- queryClient.invalidateQueries({ queryKey: THREADS_QUERY_KEY_PREFIX });
32
- queryClient.invalidateQueries({ queryKey: ['inbox', 'threads-infinite'] });
52
+ queryClient.invalidateQueries({ queryKey: inboxKeys.threadsInfinitePrefix });
53
+ queryClient.invalidateQueries({ queryKey: inboxKeys.threads() });
54
+ queryClient.invalidateQueries({ queryKey: inboxKeys.badgeCount() });
55
+ queryClient.invalidateQueries({ queryKey: gmailKeys.threadsInfinitePrefix });
33
56
  },
34
57
  });
35
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-me.d.ts","sourceRoot":"","sources":["../../src/hooks/use-me.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,KAAK,mFAMpB"}
1
+ {"version":3,"file":"use-me.d.ts","sourceRoot":"","sources":["../../src/hooks/use-me.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,KAAK,mFAMpB"}
@@ -1,5 +1,6 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
2
  import { useApiClient } from '../context';
3
+ import { meKeys } from '../query-keys';
3
4
  /**
4
5
  * Current user (GET /api/me).
5
6
  * Use for banner avatar, profile, and org context.
@@ -7,7 +8,7 @@ import { useApiClient } from '../context';
7
8
  export function useMe() {
8
9
  const client = useApiClient();
9
10
  return useQuery({
10
- queryKey: ['me'],
11
+ queryKey: meKeys.all,
11
12
  queryFn: () => client.getMe(),
12
13
  });
13
14
  }
@@ -2,5 +2,5 @@
2
2
  * Message snippets for the current org (GET /api/settings/messaging/snippets).
3
3
  * Use in Settings Snippets section and Inbox snippet picker.
4
4
  */
5
- export declare function useMessageSnippets(): import("@tanstack/react-query").UseQueryResult<import("..").MessageSnippetsResponse, Error>;
5
+ export declare function useMessageSnippets(channel?: 'sms' | 'email'): import("@tanstack/react-query").UseQueryResult<import("..").MessageSnippetsResponse, Error>;
6
6
  //# sourceMappingURL=use-message-snippets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-message-snippets.d.ts","sourceRoot":"","sources":["../../src/hooks/use-message-snippets.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,kBAAkB,gGAMjC"}
1
+ {"version":3,"file":"use-message-snippets.d.ts","sourceRoot":"","sources":["../../src/hooks/use-message-snippets.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,OAAO,+FAM3D"}
@@ -1,13 +1,14 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
2
  import { useApiClient } from '../context';
3
+ import { snippetKeys } from '../query-keys';
3
4
  /**
4
5
  * Message snippets for the current org (GET /api/settings/messaging/snippets).
5
6
  * Use in Settings Snippets section and Inbox snippet picker.
6
7
  */
7
- export function useMessageSnippets() {
8
+ export function useMessageSnippets(channel) {
8
9
  const client = useApiClient();
9
10
  return useQuery({
10
- queryKey: ['message-snippets'],
11
- queryFn: () => client.getMessageSnippets(),
11
+ queryKey: snippetKeys.list(channel),
12
+ queryFn: () => client.getMessageSnippets(channel),
12
13
  });
13
14
  }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Per-phone-number unseen missed call count.
3
+ * Used for the Calls tab badge inside the inbox page.
4
+ */
5
+ export declare function useMissedUnseenCount(phoneNumberId: string | undefined, options?: {
6
+ enabled?: boolean;
7
+ }): import("@tanstack/react-query").UseQueryResult<import("..").MissedUnseenCountResponse, Error>;
8
+ //# sourceMappingURL=use-missed-unseen-count.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-missed-unseen-count.d.ts","sourceRoot":"","sources":["../../src/hooks/use-missed-unseen-count.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,iGAWhC"}
@@ -0,0 +1,19 @@
1
+ import { useQuery } from '@tanstack/react-query';
2
+ import { useApiClient } from '../context';
3
+ import { inboxKeys } from '../query-keys';
4
+ const MISSED_REFETCH_MS = 30000;
5
+ /**
6
+ * Per-phone-number unseen missed call count.
7
+ * Used for the Calls tab badge inside the inbox page.
8
+ */
9
+ export function useMissedUnseenCount(phoneNumberId, options) {
10
+ const client = useApiClient();
11
+ const enabled = options?.enabled !== false && Boolean(phoneNumberId);
12
+ return useQuery({
13
+ queryKey: inboxKeys.missedUnseenCount(phoneNumberId ?? ''),
14
+ queryFn: () => client.getMissedUnseenCount(phoneNumberId),
15
+ enabled,
16
+ refetchInterval: enabled ? MISSED_REFETCH_MS : false,
17
+ staleTime: MISSED_REFETCH_MS / 2,
18
+ });
19
+ }
@@ -0,0 +1,15 @@
1
+ import type { PipelineCard, PipelineCardsResponse } from '../types';
2
+ export interface PatchCardVariables {
3
+ pipelineId: string;
4
+ cardId: string;
5
+ data: Record<string, unknown>;
6
+ /** Richer shape applied to the cache optimistically. Falls back to `data` when omitted. */
7
+ optimisticData?: Record<string, unknown>;
8
+ }
9
+ export declare function usePatchCard(): import("@tanstack/react-query").UseMutationResult<{
10
+ card: PipelineCard;
11
+ }, Error, PatchCardVariables, {
12
+ previousCard: PipelineCard | undefined;
13
+ previousLists: [readonly unknown[], PipelineCardsResponse | undefined][];
14
+ }>;
15
+ //# sourceMappingURL=use-patch-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-patch-card.d.ts","sourceRoot":"","sources":["../../src/hooks/use-patch-card.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAEnE,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,2FAA2F;IAC3F,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACzC;AAED,wBAAgB,YAAY;;;;;GA+D3B"}
@@ -0,0 +1,48 @@
1
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
2
+ import { useApiClient } from '../context';
3
+ import { cardKeys } from '../query-keys';
4
+ export function usePatchCard() {
5
+ const client = useApiClient();
6
+ const queryClient = useQueryClient();
7
+ return useMutation({
8
+ mutationFn: ({ pipelineId, cardId, data }) => client.patchCard(pipelineId, cardId, data),
9
+ onMutate: async ({ cardId, data, optimisticData }) => {
10
+ const patch = optimisticData ?? data;
11
+ await queryClient.cancelQueries({ queryKey: cardKeys.detail(cardId) });
12
+ await queryClient.cancelQueries({ queryKey: cardKeys.lists() });
13
+ const previousCard = queryClient.getQueryData(cardKeys.detail(cardId));
14
+ const previousLists = queryClient.getQueriesData({
15
+ queryKey: cardKeys.lists(),
16
+ });
17
+ if (previousCard) {
18
+ queryClient.setQueryData(cardKeys.detail(cardId), {
19
+ ...previousCard,
20
+ ...patch,
21
+ });
22
+ }
23
+ queryClient.setQueriesData({ queryKey: cardKeys.lists() }, (old) => {
24
+ if (!old?.cards)
25
+ return old;
26
+ return {
27
+ ...old,
28
+ cards: old.cards.map((card) => card.id === cardId ? { ...card, ...patch } : card),
29
+ };
30
+ });
31
+ return { previousCard, previousLists };
32
+ },
33
+ onError: (_err, variables, context) => {
34
+ if (context?.previousCard) {
35
+ queryClient.setQueryData(cardKeys.detail(variables.cardId), context.previousCard);
36
+ }
37
+ if (context?.previousLists) {
38
+ context.previousLists.forEach(([queryKey, data]) => {
39
+ queryClient.setQueryData(queryKey, data);
40
+ });
41
+ }
42
+ },
43
+ onSuccess: (_data, { pipelineId, cardId }) => {
44
+ queryClient.invalidateQueries({ queryKey: cardKeys.detail(cardId) });
45
+ queryClient.invalidateQueries({ queryKey: cardKeys.list(pipelineId) });
46
+ },
47
+ });
48
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"use-phone-number.d.ts","sourceRoot":"","sources":["../../src/hooks/use-phone-number.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS;;UAO/D"}
1
+ {"version":3,"file":"use-phone-number.d.ts","sourceRoot":"","sources":["../../src/hooks/use-phone-number.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS;;UAO/D"}
@@ -1,5 +1,6 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
2
  import { useApiClient } from '../context';
3
+ import { phoneNumberKeys } from '../query-keys';
3
4
  /**
4
5
  * Single phone number (GET /api/phone-numbers/[id]).
5
6
  * Use for phone number settings/detail page; includes call_recording_transcribe_enabled and assignments.
@@ -7,7 +8,7 @@ import { useApiClient } from '../context';
7
8
  export function usePhoneNumber(phoneNumberId) {
8
9
  const client = useApiClient();
9
10
  return useQuery({
10
- queryKey: ['phone-number', phoneNumberId],
11
+ queryKey: phoneNumberKeys.detail(phoneNumberId ?? ''),
11
12
  queryFn: () => client.getPhoneNumber(phoneNumberId),
12
13
  enabled: Boolean(phoneNumberId),
13
14
  });
@@ -1 +1 @@
1
- {"version":3,"file":"use-phone-numbers.d.ts","sourceRoot":"","sources":["../../src/hooks/use-phone-numbers.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,eAAe,6FAM9B"}
1
+ {"version":3,"file":"use-phone-numbers.d.ts","sourceRoot":"","sources":["../../src/hooks/use-phone-numbers.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,eAAe,6FAM9B"}
@@ -1,5 +1,6 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
2
  import { useApiClient } from '../context';
3
+ import { phoneNumberKeys } from '../query-keys';
3
4
  /**
4
5
  * Phone numbers for the org (GET /api/phone-numbers).
5
6
  * Use for header phone-number switch; filter by current user id in assignments
@@ -8,7 +9,7 @@ import { useApiClient } from '../context';
8
9
  export function usePhoneNumbers() {
9
10
  const client = useApiClient();
10
11
  return useQuery({
11
- queryKey: ['phone-numbers'],
12
+ queryKey: phoneNumberKeys.list(),
12
13
  queryFn: () => client.getPhoneNumbers(),
13
14
  });
14
15
  }
@@ -0,0 +1,6 @@
1
+ import type { SendGmailMessagePayload } from '../types';
2
+ export declare function useSendGmailMessage(): import("@tanstack/react-query").UseMutationResult<import("..").SendGmailMessageResponse, Error, {
3
+ connectionId: string;
4
+ body: SendGmailMessagePayload;
5
+ }, unknown>;
6
+ //# sourceMappingURL=use-send-gmail-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-send-gmail-message.d.ts","sourceRoot":"","sources":["../../src/hooks/use-send-gmail-message.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAA;AAEvD,wBAAgB,mBAAmB;kBASf,MAAM;UACd,uBAAuB;YAclC"}
@@ -0,0 +1,21 @@
1
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
2
+ import { useApiClient } from '../context';
3
+ import { gmailKeys } from '../query-keys';
4
+ export function useSendGmailMessage() {
5
+ const client = useApiClient();
6
+ const queryClient = useQueryClient();
7
+ return useMutation({
8
+ mutationFn: ({ connectionId, body, }) => client.sendGmailMessage(connectionId, body),
9
+ onSuccess: (_data, variables) => {
10
+ // Invalidate threads and messages to pick up the new message
11
+ queryClient.invalidateQueries({
12
+ queryKey: gmailKeys.threadsInfinitePrefix,
13
+ });
14
+ if (_data.threadId) {
15
+ queryClient.invalidateQueries({
16
+ queryKey: gmailKeys.messages(_data.threadId),
17
+ });
18
+ }
19
+ },
20
+ });
21
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"use-send-inbox-message.d.ts","sourceRoot":"","sources":["../../src/hooks/use-send-inbox-message.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACxB,MAAM,UAAU,CAAA;AAkDjB,wBAAgB,mBAAmB;mBAQd,MAAM;UACf,uBAAuB;;;;;;;GA4ElC"}
1
+ {"version":3,"file":"use-send-inbox-message.d.ts","sourceRoot":"","sources":["../../src/hooks/use-send-inbox-message.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACxB,MAAM,UAAU,CAAA;AA+CjB,wBAAgB,mBAAmB;mBAQd,MAAM;UACf,uBAAuB;;;;;;;GA+ElC"}
@@ -1,7 +1,7 @@
1
1
  import { useMutation, useQueryClient } from '@tanstack/react-query';
2
+ import { ApiRequestError } from '../client';
2
3
  import { useApiClient } from '../context';
3
- const THREADS_QUERY_KEY_PREFIX = ['inbox', 'threads'];
4
- const MESSAGES_QUERY_KEY_PREFIX = ['inbox', 'messages'];
4
+ import { inboxKeys, meKeys } from '../query-keys';
5
5
  function buildOptimisticMessage(threadId, body, tempId) {
6
6
  const occurredAt = new Date().toISOString();
7
7
  const rawMediaUrl = Array.isArray(body.media_url)
@@ -49,7 +49,7 @@ export function useSendInboxMessage() {
49
49
  const threadId = body.thread_id;
50
50
  if (!threadId)
51
51
  return { previousMessages: null };
52
- const messagesKey = [...MESSAGES_QUERY_KEY_PREFIX, threadId];
52
+ const messagesKey = inboxKeys.messages(threadId);
53
53
  const previousMessages = queryClient.getQueryData(messagesKey);
54
54
  const tempId = `optimistic-${Date.now()}`;
55
55
  const optimisticMessage = buildOptimisticMessage(threadId, body, tempId);
@@ -58,10 +58,10 @@ export function useSendInboxMessage() {
58
58
  return { messages: [...messages, optimisticMessage] };
59
59
  });
60
60
  const previousThreads = queryClient.getQueriesData({
61
- queryKey: THREADS_QUERY_KEY_PREFIX,
61
+ queryKey: inboxKeys.threads(),
62
62
  exact: false,
63
63
  });
64
- queryClient.setQueriesData({ queryKey: THREADS_QUERY_KEY_PREFIX, exact: false }, (data) => {
64
+ queryClient.setQueriesData({ queryKey: inboxKeys.threads(), exact: false }, (data) => {
65
65
  if (!data?.threads?.length)
66
66
  return data;
67
67
  return {
@@ -86,7 +86,7 @@ export function useSendInboxMessage() {
86
86
  previousThreads,
87
87
  };
88
88
  },
89
- onError: (_err, _variables, context) => {
89
+ onError: (err, _variables, context) => {
90
90
  if (context?.previousMessages) {
91
91
  const [queryKey, data] = context.previousMessages;
92
92
  queryClient.setQueryData(queryKey, data);
@@ -96,19 +96,22 @@ export function useSendInboxMessage() {
96
96
  queryClient.setQueryData(queryKey, data);
97
97
  });
98
98
  }
99
+ // Send failed before deducting (or balance already wrong); refresh me so banner reflects current credits
100
+ if (err instanceof ApiRequestError && err.status === 402) {
101
+ void queryClient.invalidateQueries({ queryKey: meKeys.all });
102
+ }
99
103
  },
100
104
  onSuccess: (data, { phoneNumberId, body }) => {
101
- // Invalidate so refetch runs; do not remove the optimistic message here — the refetch
102
- // replaces the cache with server data, avoiding a flicker where the message disappears
103
- // before the real one appears.
104
- queryClient.invalidateQueries({ queryKey: ['inbox', 'threads', phoneNumberId] });
105
- queryClient.invalidateQueries({ queryKey: ['inbox', 'threads-infinite'] });
105
+ queryClient.invalidateQueries({ queryKey: [...inboxKeys.threads(), phoneNumberId] });
106
+ queryClient.invalidateQueries({ queryKey: inboxKeys.threadsInfinitePrefix });
106
107
  if (body.thread_id) {
107
- queryClient.invalidateQueries({ queryKey: ['inbox', 'messages', body.thread_id] });
108
+ queryClient.invalidateQueries({ queryKey: inboxKeys.messages(body.thread_id) });
108
109
  }
109
110
  if (data?.threadId) {
110
- queryClient.invalidateQueries({ queryKey: ['inbox', 'messages', data.threadId] });
111
+ queryClient.invalidateQueries({ queryKey: inboxKeys.messages(data.threadId) });
111
112
  }
113
+ // Credits deducted server-side; refresh /api/me so composer banner + balance stay accurate
114
+ void queryClient.invalidateQueries({ queryKey: meKeys.all });
112
115
  },
113
116
  });
114
117
  }
@@ -1,6 +1,10 @@
1
1
  import { useApiClient } from '../context';
2
+ import type { CreateTaskInput } from '../types';
2
3
  export type GetTasksParams = Parameters<ReturnType<typeof useApiClient>['getTasks']>[0];
3
4
  export declare function useTasks(params?: GetTasksParams): import("@tanstack/react-query").UseQueryResult<{
4
5
  tasks: import("..").TaskListItem[];
5
6
  }, Error>;
7
+ export declare function useCreateTask(): import("@tanstack/react-query").UseMutationResult<{
8
+ task: import("..").TaskListItem;
9
+ }, Error, CreateTaskInput, unknown>;
6
10
  //# sourceMappingURL=use-tasks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-tasks.d.ts","sourceRoot":"","sources":["../../src/hooks/use-tasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,MAAM,cAAc,GAAG,UAAU,CACrC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,UAAU,CAAC,CAC5C,CAAC,CAAC,CAAC,CAAA;AAEJ,wBAAgB,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc;;UAM/C"}
1
+ {"version":3,"file":"use-tasks.d.ts","sourceRoot":"","sources":["../../src/hooks/use-tasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,MAAM,MAAM,cAAc,GAAG,UAAU,CACrC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,UAAU,CAAC,CAC5C,CAAC,CAAC,CAAC,CAAA;AAEJ,wBAAgB,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc;;UAO/C;AAED,wBAAgB,aAAa;;oCAU5B"}
@@ -1,9 +1,21 @@
1
- import { useQuery } from '@tanstack/react-query';
1
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
2
2
  import { useApiClient } from '../context';
3
+ import { taskKeys } from '../query-keys';
3
4
  export function useTasks(params) {
4
5
  const client = useApiClient();
5
6
  return useQuery({
6
- queryKey: ['tasks', params],
7
+ queryKey: taskKeys.list(params),
7
8
  queryFn: () => client.getTasks(params),
9
+ staleTime: 30 * 1000,
10
+ });
11
+ }
12
+ export function useCreateTask() {
13
+ const client = useApiClient();
14
+ const queryClient = useQueryClient();
15
+ return useMutation({
16
+ mutationFn: (input) => client.createTask(input),
17
+ onSuccess: () => {
18
+ queryClient.invalidateQueries({ queryKey: taskKeys.lists() });
19
+ },
8
20
  });
9
21
  }
@@ -1,3 +1,4 @@
1
+ import { type InfiniteData } from '@tanstack/react-query';
1
2
  import type { InboxThreadsResponse } from '../types';
2
3
  export declare function useUpdateInboxThreadStatus(): import("@tanstack/react-query").UseMutationResult<{
3
4
  ok: true;
@@ -6,6 +7,7 @@ export declare function useUpdateInboxThreadStatus(): import("@tanstack/react-qu
6
7
  threadId: string;
7
8
  status: "active" | "archived";
8
9
  }, {
9
- previous: [readonly unknown[], InboxThreadsResponse | undefined][];
10
+ previousSms: [readonly unknown[], InfiniteData<InboxThreadsResponse, unknown> | undefined][];
11
+ previousGmail: [readonly unknown[], InfiniteData<InboxThreadsResponse, unknown> | undefined][];
10
12
  }>;
11
13
  //# sourceMappingURL=use-update-inbox-thread-status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-update-inbox-thread-status.d.ts","sourceRoot":"","sources":["../../src/hooks/use-update-inbox-thread-status.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAIpD,wBAAgB,0BAA0B;;;;cAQ1B,MAAM;YACR,QAAQ,GAAG,UAAU;;;GAgClC"}
1
+ {"version":3,"file":"use-update-inbox-thread-status.d.ts","sourceRoot":"","sources":["../../src/hooks/use-update-inbox-thread-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAA+B,MAAM,uBAAuB,CAAA;AAGtF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AA2BpD,wBAAgB,0BAA0B;;;;cAQ1B,MAAM;YACR,QAAQ,GAAG,UAAU;;;;GAwClC"}