@workhive/api 1.3.4 → 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 +141 -6
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +228 -12
  4. package/dist/context.d.ts +103 -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 +370 -14
  104. package/dist/types.d.ts.map +1 -1
  105. package/package.json +1 -1
@@ -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"}
@@ -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 update thread status across a query cache prefix (works for both flat and infinite data). */
5
+ function setStatusOnThread(queryClient, queryKeyPrefix, threadId, status) {
6
+ // Handle InfiniteData shape (threadsInfinitePrefix)
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, status } : t),
15
+ })),
16
+ };
17
+ });
18
+ }
4
19
  export function useUpdateInboxThreadStatus() {
5
20
  const client = useApiClient();
6
21
  const queryClient = useQueryClient();
7
22
  return useMutation({
8
23
  mutationFn: ({ threadId, status, }) => client.updateInboxThreadStatus(threadId, status),
9
24
  onMutate: async ({ threadId, status }) => {
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, status } : t),
19
- };
31
+ const previousGmail = queryClient.getQueriesData({
32
+ queryKey: gmailKeys.threadsInfinitePrefix,
33
+ exact: false,
20
34
  });
21
- return { previous };
35
+ setStatusOnThread(queryClient, inboxKeys.threadsInfinitePrefix, threadId, status);
36
+ setStatusOnThread(queryClient, gmailKeys.threadsInfinitePrefix, threadId, status);
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: gmailKeys.threadsInfinitePrefix });
33
55
  },
34
56
  });
35
57
  }
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @workhive/api – shared API client, types, and hooks for WorkHive SaaS and mobile.
3
3
  */
4
- export { createApiClient } from './client';
4
+ export { createApiClient, ApiRequestError } from './client';
5
5
  export type { ApiClientConfig, ApiClient } from './client';
6
6
  export { ApiProvider, useApiClient } from './context';
7
- export { contactKeys, inboxKeys } from './query-keys';
8
- export type { FlattenedLead, LeadSubmissionsResponse, ContactLeadSubmission, ContactLeadSubmissionsResponse, TaskStatus, TaskListItem, TaskCallOutcomeType, TaskChatOutcomeType, TaskOutcomeType, MeetingStatus, MeetingProvider, MeetingMode, MeetingNoSaleReason, MeetingCallOutcome, Meeting, MeetingAttachment, MeetingOutcomePayload, CreateMeetingPayload, PipelineCard, PostMeetingBookedPromptResponse, Pipeline, PipelineStage, TeamMember, TeamMembersResponse, MeUser, MeMembership, MeOrganization, MeResponse, RescheduleMeetingPayload, GetAvailabilitySlotsParams, GetAvailabilitySlotsResponse, AvailabilitySlot, EventType, EventTypeHost, PhoneNumberRecord, PhoneNumberAssignmentRecord, PhoneNumbersResponse, UpdatePhoneNumberBody, InboxThreadListItem, InboxThreadsResponse, InboxMessageAttachment, InboxMessage, InboxMessagesResponse, TranscriptUtterance, InboxCallEvent, InboxCallListItem, InboxCallsResponse, CreateInboxCallPayload, VoiceTokenResponse, UploadInboxMediaResponse, SendInboxMessagePayload, SendInboxMessageResponse, MessageSnippet, MessageSnippetsResponse, CreateMessageSnippetPayload, UpdateMessageSnippetPayload, InboxGif, InboxGifsResponse, } from './types';
9
- export { useLeads, useContactLeadSubmissions, useContactMeetings, useContactCalls, useTasks, useMeetings, usePipelines, useStages, useTeamMembers, useMe, usePhoneNumbers, usePhoneNumber, useInboxThreads, useInboxThreadsInfinite, useInboxMessages, useInboxCalls, useInboxCallsInfinite, useSendInboxMessage, useMarkInboxThreadRead, useMarkInboxThreadUnread, useUpdateInboxThreadStatus, useDeleteInboxThread, useMessageSnippets, } from './hooks';
10
- export type { GetLeadSubmissionsParams, GetTasksParams, GetMeetingsParams, GetPipelinesParams, GetInboxThreadsParams, GetInboxThreadsInfiniteParams, UseInboxCallsOptions, UseInboxCallsInfiniteOptions, } from './hooks';
7
+ export { cardKeys, contactKeys, inboxKeys, gmailKeys, meKeys, phoneNumberKeys, snippetKeys, taskKeys } from './query-keys';
8
+ export type { FlattenedLead, LeadSubmissionsResponse, ContactLeadSubmission, ContactLeadSubmissionsResponse, WorkspaceType, TaskStatus, TaskListItem, CreateTaskInput, TaskCallOutcomeType, TaskChatOutcomeType, TaskOutcomeType, MeetingStatus, MeetingProvider, MeetingMode, MeetingNoSaleReason, MeetingCallOutcome, Meeting, MeetingAttachment, MeetingOutcomePayload, CreateMeetingPayload, PipelineCard, PipelineCardOwner, PipelineCardContact, PipelineCardStage, PipelineCardAccount, PipelineCardProduct, PipelineCardDealCategory, PipelineCardsResponse, CreateCardPayload, PostMeetingBookedPromptResponse, Pipeline, PipelineStage, TeamMember, TeamMembersResponse, MeUser, MeMembership, MeOrganization, MeOrganizationBilling, MeCreditPack, MeResponse, SeatUpdateResponse, RescheduleMeetingPayload, GetAvailabilitySlotsParams, GetAvailabilitySlotsResponse, AvailabilitySlot, EventType, EventTypeHost, PhoneNumberRecord, PhoneNumberAssignmentRecord, PhoneNumbersResponse, UpdatePhoneNumberBody, InboxThreadListItem, InboxThreadsResponse, InboxMessageAttachment, InboxMessage, InboxMessagesResponse, TranscriptUtterance, InboxCallEvent, InboxCallListItem, InboxCallsResponse, CreateInboxCallPayload, MissedUnseenCountResponse, InboxBadgeCountResponse, VoiceTokenResponse, UploadInboxMediaResponse, SendInboxMessagePayload, SendInboxMessageResponse, MessageSnippet, MessageSnippetsResponse, CreateMessageSnippetPayload, UpdateMessageSnippetPayload, InboxGif, InboxGifsResponse, RegisterPushTokenPayload, RegisterPushTokenResponse, UnregisterPushTokenResponse, GmailConnectionRecord, GmailConnectionsResponse, GmailConnectionHealth, SendGmailMessagePayload, SendGmailMessageResponse, LinkGmailThreadContactPayload, LinkGmailThreadContactResponse, GmailThreadsPageResponse, GmailThreadSearchResponse, GmailConnectionMember, GmailSignatureResponse, InboxThreadSearchResponse, EmailDraft, CreateEmailDraftPayload, UpdateEmailDraftPayload, CreateEmailDraftResponse, EmailDraftsListResponse, } from './types';
9
+ export { useLeads, useContactLeadSubmissions, useContactMeetings, useContactCalls, useTasks, useCreateTask, useMeetings, usePipelines, useStages, useTeamMembers, useMe, usePhoneNumbers, usePhoneNumber, useInboxThreads, useInboxThreadsInfinite, useInboxMessages, useInboxCalls, useInboxCallsInfinite, useSendInboxMessage, useMarkInboxThreadRead, useMarkInboxThreadUnread, useUpdateInboxThreadStatus, useDeleteInboxThread, useInboxBadgeCount, useMissedUnseenCount, useMessageSnippets, useCard, useCards, usePatchCard, useCreateCard, useDeleteCard, useBillingStatus, useGmailConnections, useTriggerGmailSync, useGmailThreads, useGmailThreadSearchInfinite, useGmailMessages, useSendGmailMessage, useLinkGmailThreadContact, useInboxThreadSearch, useGmailConnectionMembers, useGmailSignature, useAddGmailConnectionMember, useRemoveGmailConnectionMember, useEmailDrafts, useCreateEmailDraft, useUpdateEmailDraft, useDeleteEmailDraft, } from './hooks';
10
+ export type { UseCardsParams, PatchCardVariables, CreateCardVariables, DeleteCardVariables, GetLeadSubmissionsParams, GetTasksParams, GetMeetingsParams, GetPipelinesParams, GetInboxThreadsParams, GetInboxThreadsInfiniteParams, UseInboxCallsOptions, UseInboxCallsInfiniteOptions, } from './hooks';
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAG1D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAGrD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAGrD,YAAY,EACV,aAAa,EACb,uBAAuB,EACvB,qBAAqB,EACrB,8BAA8B,EAC9B,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,OAAO,EACP,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,+BAA+B,EAC/B,QAAQ,EACR,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,MAAM,EACN,YAAY,EACZ,cAAc,EACd,UAAU,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,4BAA4B,EAC5B,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,QAAQ,EACR,iBAAiB,GAClB,MAAM,SAAS,CAAA;AAGhB,OAAO,EACL,QAAQ,EACR,yBAAyB,EACzB,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,SAAS,EACT,cAAc,EACd,KAAK,EACL,eAAe,EACf,cAAc,EACd,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,SAAS,CAAA;AAChB,YAAY,EACV,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,6BAA6B,EAC7B,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2,10 +2,10 @@
2
2
  * @workhive/api – shared API client, types, and hooks for WorkHive SaaS and mobile.
3
3
  */
4
4
  // Client
5
- export { createApiClient } from './client';
5
+ export { createApiClient, ApiRequestError } from './client';
6
6
  // Context (React)
7
7
  export { ApiProvider, useApiClient } from './context';
8
8
  // Query keys (for invalidators and consistent keys)
9
- export { contactKeys, inboxKeys } from './query-keys';
9
+ export { cardKeys, contactKeys, inboxKeys, gmailKeys, meKeys, phoneNumberKeys, snippetKeys, taskKeys } from './query-keys';
10
10
  // Hooks
11
- export { useLeads, useContactLeadSubmissions, useContactMeetings, useContactCalls, useTasks, useMeetings, usePipelines, useStages, useTeamMembers, useMe, usePhoneNumbers, usePhoneNumber, useInboxThreads, useInboxThreadsInfinite, useInboxMessages, useInboxCalls, useInboxCallsInfinite, useSendInboxMessage, useMarkInboxThreadRead, useMarkInboxThreadUnread, useUpdateInboxThreadStatus, useDeleteInboxThread, useMessageSnippets, } from './hooks';
11
+ export { useLeads, useContactLeadSubmissions, useContactMeetings, useContactCalls, useTasks, useCreateTask, useMeetings, usePipelines, useStages, useTeamMembers, useMe, usePhoneNumbers, usePhoneNumber, useInboxThreads, useInboxThreadsInfinite, useInboxMessages, useInboxCalls, useInboxCallsInfinite, useSendInboxMessage, useMarkInboxThreadRead, useMarkInboxThreadUnread, useUpdateInboxThreadStatus, useDeleteInboxThread, useInboxBadgeCount, useMissedUnseenCount, useMessageSnippets, useCard, useCards, usePatchCard, useCreateCard, useDeleteCard, useBillingStatus, useGmailConnections, useTriggerGmailSync, useGmailThreads, useGmailThreadSearchInfinite, useGmailMessages, useSendGmailMessage, useLinkGmailThreadContact, useInboxThreadSearch, useGmailConnectionMembers, useGmailSignature, useAddGmailConnectionMember, useRemoveGmailConnectionMember, useEmailDrafts, useCreateEmailDraft, useUpdateEmailDraft, useDeleteEmailDraft, } from './hooks';
@@ -2,21 +2,79 @@
2
2
  * Query key factories for React Query.
3
3
  * Use these for consistency and so invalidators can target the same keys.
4
4
  */
5
+ /** Current user + org (GET /api/me) — useMe */
6
+ export declare const meKeys: {
7
+ all: readonly ["me"];
8
+ };
9
+ export declare const cardKeys: {
10
+ all: readonly ["cards"];
11
+ lists: () => readonly ["cards", "list"];
12
+ list: (pipelineId: string, filters?: {
13
+ showArchivedOnly?: boolean;
14
+ }) => readonly ["cards", "list", string, {
15
+ showArchivedOnly?: boolean;
16
+ } | undefined];
17
+ details: () => readonly ["cards", "detail"];
18
+ detail: (cardId: string) => readonly ["cards", "detail", string];
19
+ };
5
20
  export declare const contactKeys: {
6
21
  /** Contact's past calls (GET /api/contacts/[id]/calls) */
7
22
  calls: (contactId: string) => readonly ["contact-calls", string];
8
23
  /** Contact's meetings (GET /api/contacts/[id]/meetings) */
9
24
  meetings: (contactId: string) => readonly ["contact-meetings", string];
10
25
  };
26
+ export declare const phoneNumberKeys: {
27
+ all: readonly ["phone-numbers"];
28
+ list: () => readonly ["phone-numbers"];
29
+ details: () => readonly ["phone-number"];
30
+ detail: (phoneNumberId: string) => readonly ["phone-number", string];
31
+ };
11
32
  /** Inbox threads and calls list keys. Include all params that affect the response so filter changes reset pagination. */
12
33
  export declare const inboxKeys: {
13
34
  all: readonly ["inbox"];
35
+ threads: () => readonly ["inbox", "threads"];
36
+ threadsInfinitePrefix: readonly ["inbox", "threads-infinite"];
14
37
  threadsInfinite: (phoneNumberId: string, filters?: {
15
38
  status?: "active" | "archived";
16
39
  unreadOnly?: boolean;
17
40
  }) => readonly ["inbox", "threads-infinite", string, "active" | "archived" | undefined, boolean | undefined];
41
+ messages: (threadId: string) => readonly ["inbox", "messages", string];
18
42
  callsInfinite: (phoneNumberId: string, filters?: {
19
43
  missedOnly?: boolean;
20
44
  }) => readonly ["inbox", "calls-infinite", string, boolean | undefined];
45
+ badgeCount: () => readonly ["inbox", "badge-count"];
46
+ missedUnseenCount: (phoneNumberId: string) => readonly ["inbox", "missed-unseen-count", string];
47
+ threadSearch: (phoneNumberId: string, query: string) => readonly ["inbox", "thread-search", string, string];
48
+ };
49
+ export declare const snippetKeys: {
50
+ all: readonly ["message-snippets"];
51
+ list: (channel?: "sms" | "email") => readonly ["message-snippets"] | readonly ["message-snippets", "sms" | "email"];
52
+ };
53
+ /** Gmail email inbox keys */
54
+ export declare const gmailKeys: {
55
+ all: readonly ["gmail"];
56
+ connections: () => readonly ["gmail", "connections"];
57
+ /** @deprecated Use ['gmail', 'threads'] for invalidation */
58
+ threadsInfinitePrefix: readonly ["gmail", "threads"];
59
+ threads: (connectionId: string, filters?: {
60
+ status?: string;
61
+ unreadOnly?: boolean;
62
+ page?: number;
63
+ }) => readonly ["gmail", "threads", string, string | undefined, boolean | undefined, number | undefined];
64
+ searchInfinitePrefix: readonly ["gmail", "search-infinite"];
65
+ searchInfinite: (connectionId: string, query: string) => readonly ["gmail", "search-infinite", string, string];
66
+ messages: (threadId: string) => readonly ["gmail", "messages", string];
67
+ threadSearch: (connectionId: string, query: string) => readonly ["gmail", "thread-search", string, string];
68
+ connectionHealth: (connectionId: string) => readonly ["gmail", "connection-health", string];
69
+ members: (connectionId: string) => readonly ["gmail", "members", string];
70
+ signature: (connectionId: string) => readonly ["gmail", "signature", string];
71
+ drafts: (connectionId: string) => readonly ["gmail", "drafts", string];
72
+ draft: (draftId: string) => readonly ["gmail", "drafts", "detail", string];
73
+ };
74
+ export declare const taskKeys: {
75
+ all: readonly ["tasks"];
76
+ lists: () => readonly ["tasks", "list"];
77
+ list: (filters?: Record<string, unknown>) => readonly ["tasks", "list", Record<string, unknown> | undefined];
78
+ byContact: (contactId: string) => readonly ["tasks", "by-contact", string];
21
79
  };
22
80
  //# sourceMappingURL=query-keys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-keys.d.ts","sourceRoot":"","sources":["../src/query-keys.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,WAAW;IACtB,0DAA0D;uBACvC,MAAM;IACzB,2DAA2D;0BACrC,MAAM;CAC7B,CAAA;AAED,yHAAyH;AACzH,eAAO,MAAM,SAAS;;qCAGH,MAAM,YACX;QAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE;mCAGnD,MAAM,YACX;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE;CAErC,CAAA"}
1
+ {"version":3,"file":"query-keys.d.ts","sourceRoot":"","sources":["../src/query-keys.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,eAAO,MAAM,MAAM;;CAElB,CAAA;AAED,eAAO,MAAM,QAAQ;;;uBAGA,MAAM,YAAY;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE;2BAAT,OAAO;;;qBAGhD,MAAM;CACxB,CAAA;AAED,eAAO,MAAM,WAAW;IACtB,0DAA0D;uBACvC,MAAM;IACzB,2DAA2D;0BACrC,MAAM;CAC7B,CAAA;AAED,eAAO,MAAM,eAAe;;;;4BAIF,MAAM;CAC/B,CAAA;AAED,yHAAyH;AACzH,eAAO,MAAM,SAAS;;;;qCAKH,MAAM,YACX;QAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE;yBAE/C,MAAM;mCAEV,MAAM,YACX;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE;;uCAGD,MAAM;kCAEX,MAAM,SAAS,MAAM;CAEpD,CAAA;AAED,eAAO,MAAM,WAAW;;qBAEL,KAAK,GAAG,OAAO;CAEjC,CAAA;AAED,6BAA6B;AAC7B,eAAO,MAAM,SAAS;;;IAGpB,4DAA4D;;4BAG5C,MAAM,YACV;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;;mCAGrC,MAAM,SAAS,MAAM;yBAE/B,MAAM;iCACE,MAAM,SAAS,MAAM;qCAEjB,MAAM;4BAEf,MAAM;8BACJ,MAAM;2BACT,MAAM;qBACZ,MAAM;CACxB,CAAA;AAED,eAAO,MAAM,QAAQ;;;qBAGF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;2BACjB,MAAM;CAC9B,CAAA"}
@@ -2,15 +2,65 @@
2
2
  * Query key factories for React Query.
3
3
  * Use these for consistency and so invalidators can target the same keys.
4
4
  */
5
+ /** Current user + org (GET /api/me) — useMe */
6
+ export const meKeys = {
7
+ all: ['me'],
8
+ };
9
+ export const cardKeys = {
10
+ all: ['cards'],
11
+ lists: () => [...cardKeys.all, 'list'],
12
+ list: (pipelineId, filters) => [...cardKeys.lists(), pipelineId, filters],
13
+ details: () => [...cardKeys.all, 'detail'],
14
+ detail: (cardId) => [...cardKeys.details(), cardId],
15
+ };
5
16
  export const contactKeys = {
6
17
  /** Contact's past calls (GET /api/contacts/[id]/calls) */
7
18
  calls: (contactId) => ['contact-calls', contactId],
8
19
  /** Contact's meetings (GET /api/contacts/[id]/meetings) */
9
20
  meetings: (contactId) => ['contact-meetings', contactId],
10
21
  };
22
+ export const phoneNumberKeys = {
23
+ all: ['phone-numbers'],
24
+ list: () => [...phoneNumberKeys.all],
25
+ details: () => ['phone-number'],
26
+ detail: (phoneNumberId) => [...phoneNumberKeys.details(), phoneNumberId],
27
+ };
11
28
  /** Inbox threads and calls list keys. Include all params that affect the response so filter changes reset pagination. */
12
29
  export const inboxKeys = {
13
30
  all: ['inbox'],
31
+ threads: () => ['inbox', 'threads'],
32
+ threadsInfinitePrefix: ['inbox', 'threads-infinite'],
14
33
  threadsInfinite: (phoneNumberId, filters) => ['inbox', 'threads-infinite', phoneNumberId, filters?.status, filters?.unreadOnly],
34
+ messages: (threadId) => ['inbox', 'messages', threadId],
15
35
  callsInfinite: (phoneNumberId, filters) => ['inbox', 'calls-infinite', phoneNumberId, filters?.missedOnly],
36
+ badgeCount: () => ['inbox', 'badge-count'],
37
+ missedUnseenCount: (phoneNumberId) => ['inbox', 'missed-unseen-count', phoneNumberId],
38
+ threadSearch: (phoneNumberId, query) => ['inbox', 'thread-search', phoneNumberId, query],
39
+ };
40
+ export const snippetKeys = {
41
+ all: ['message-snippets'],
42
+ list: (channel) => channel ? [...snippetKeys.all, channel] : snippetKeys.all,
43
+ };
44
+ /** Gmail email inbox keys */
45
+ export const gmailKeys = {
46
+ all: ['gmail'],
47
+ connections: () => ['gmail', 'connections'],
48
+ /** @deprecated Use ['gmail', 'threads'] for invalidation */
49
+ threadsInfinitePrefix: ['gmail', 'threads'],
50
+ threads: (connectionId, filters) => ['gmail', 'threads', connectionId, filters?.status, filters?.unreadOnly, filters?.page],
51
+ searchInfinitePrefix: ['gmail', 'search-infinite'],
52
+ searchInfinite: (connectionId, query) => ['gmail', 'search-infinite', connectionId, query],
53
+ messages: (threadId) => ['gmail', 'messages', threadId],
54
+ threadSearch: (connectionId, query) => ['gmail', 'thread-search', connectionId, query],
55
+ connectionHealth: (connectionId) => ['gmail', 'connection-health', connectionId],
56
+ members: (connectionId) => ['gmail', 'members', connectionId],
57
+ signature: (connectionId) => ['gmail', 'signature', connectionId],
58
+ drafts: (connectionId) => ['gmail', 'drafts', connectionId],
59
+ draft: (draftId) => ['gmail', 'drafts', 'detail', draftId],
60
+ };
61
+ export const taskKeys = {
62
+ all: ['tasks'],
63
+ lists: () => [...taskKeys.all, 'list'],
64
+ list: (filters) => [...taskKeys.lists(), filters],
65
+ byContact: (contactId) => [...taskKeys.all, 'by-contact', contactId],
16
66
  };