@flamingo-stack/openframe-frontend-core 0.0.215 → 0.0.216

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 (228) hide show
  1. package/dist/chunk-2V4SACHE.js +302 -0
  2. package/dist/chunk-2V4SACHE.js.map +1 -0
  3. package/dist/chunk-572WQWIX.cjs +348 -0
  4. package/dist/chunk-572WQWIX.cjs.map +1 -0
  5. package/dist/{chunk-WT5JV2GS.cjs → chunk-5V6MSE3B.cjs} +39 -39
  6. package/dist/chunk-5V6MSE3B.cjs.map +1 -0
  7. package/dist/{chunk-WQZP3JIZ.js → chunk-CDLYRFDE.js} +1894 -1472
  8. package/dist/chunk-CDLYRFDE.js.map +1 -0
  9. package/dist/chunk-GVNQAGXB.js +232 -0
  10. package/dist/chunk-GVNQAGXB.js.map +1 -0
  11. package/dist/{chunk-P5EE2VJX.cjs → chunk-HOHDXYPR.cjs} +1 -1
  12. package/dist/chunk-HOHDXYPR.cjs.map +1 -0
  13. package/dist/chunk-IH76P5R6.cjs +232 -0
  14. package/dist/chunk-IH76P5R6.cjs.map +1 -0
  15. package/dist/{chunk-24KCAECR.cjs → chunk-JJR27M56.cjs} +3 -3
  16. package/dist/{chunk-24KCAECR.cjs.map → chunk-JJR27M56.cjs.map} +1 -1
  17. package/dist/chunk-K4DFAVSO.cjs +302 -0
  18. package/dist/chunk-K4DFAVSO.cjs.map +1 -0
  19. package/dist/{chunk-HICZPTRR.js → chunk-LCLTCCXS.js} +14 -14
  20. package/dist/chunk-LCLTCCXS.js.map +1 -0
  21. package/dist/{chunk-VFKQMAUF.cjs → chunk-OB45JHDY.cjs} +3 -3
  22. package/dist/{chunk-VFKQMAUF.cjs.map → chunk-OB45JHDY.cjs.map} +1 -1
  23. package/dist/{chunk-4XLJWX2N.js → chunk-ORJREQ2W.js} +4 -4
  24. package/dist/{chunk-7PCP7YQR.js → chunk-QTKU6ULP.js} +6 -6
  25. package/dist/{chunk-CIPO6DXK.js → chunk-QY75VKAS.js} +5 -5
  26. package/dist/{chunk-ZG2YY5E7.js → chunk-RFONYT63.js} +1 -1
  27. package/dist/chunk-RFONYT63.js.map +1 -0
  28. package/dist/{chunk-NGFP4RVL.cjs → chunk-SMCG2CCC.cjs} +30 -30
  29. package/dist/{chunk-NGFP4RVL.cjs.map → chunk-SMCG2CCC.cjs.map} +1 -1
  30. package/dist/{chunk-MX5MIFWA.js → chunk-UEBM4PC4.js} +5 -5
  31. package/dist/chunk-VC3ND5RB.js +348 -0
  32. package/dist/chunk-VC3ND5RB.js.map +1 -0
  33. package/dist/{chunk-UXZ3ZJ3M.cjs → chunk-XDPSSE4O.cjs} +4 -4
  34. package/dist/{chunk-UXZ3ZJ3M.cjs.map → chunk-XDPSSE4O.cjs.map} +1 -1
  35. package/dist/{chunk-D4MNFY67.cjs → chunk-ZGTDUPTW.cjs} +1316 -894
  36. package/dist/chunk-ZGTDUPTW.cjs.map +1 -0
  37. package/dist/components/chat/entity-cards/blog-card.d.ts +1 -1
  38. package/dist/components/chat/entity-cards/blog-card.d.ts.map +1 -1
  39. package/dist/components/chat/entity-cards/case-study-card.d.ts +1 -1
  40. package/dist/components/chat/entity-cards/case-study-card.d.ts.map +1 -1
  41. package/dist/components/chat/entity-cards/customer-interview-card.d.ts +1 -1
  42. package/dist/components/chat/entity-cards/customer-interview-card.d.ts.map +1 -1
  43. package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -1
  44. package/dist/components/chat/entity-cards/investor-update-card.d.ts +1 -1
  45. package/dist/components/chat/entity-cards/investor-update-card.d.ts.map +1 -1
  46. package/dist/components/chat/entity-cards/onboarding-guide-card.d.ts +1 -1
  47. package/dist/components/chat/entity-cards/onboarding-guide-card.d.ts.map +1 -1
  48. package/dist/components/chat/entity-cards/program-card.d.ts +1 -1
  49. package/dist/components/chat/entity-cards/program-card.d.ts.map +1 -1
  50. package/dist/components/chat/entity-cards/use-entity-card-link.d.ts +14 -0
  51. package/dist/components/chat/entity-cards/use-entity-card-link.d.ts.map +1 -0
  52. package/dist/components/chat/entity-cards/use-entity-card-placeholder.d.ts +13 -0
  53. package/dist/components/chat/entity-cards/use-entity-card-placeholder.d.ts.map +1 -0
  54. package/dist/components/chat/index.cjs +11 -11
  55. package/dist/components/chat/index.js +10 -10
  56. package/dist/components/contact/index.cjs +12 -12
  57. package/dist/components/contact/index.js +11 -11
  58. package/dist/components/features/captions-url.d.ts +18 -0
  59. package/dist/components/features/captions-url.d.ts.map +1 -0
  60. package/dist/components/features/index.cjs +23 -11
  61. package/dist/components/features/index.cjs.map +1 -1
  62. package/dist/components/features/index.d.ts +2 -0
  63. package/dist/components/features/index.d.ts.map +1 -1
  64. package/dist/components/features/index.js +24 -12
  65. package/dist/components/features/mux-origins.cjs +10 -0
  66. package/dist/components/features/mux-origins.cjs.map +1 -0
  67. package/dist/components/features/mux-origins.d.ts +26 -0
  68. package/dist/components/features/mux-origins.d.ts.map +1 -0
  69. package/dist/components/features/mux-origins.js +7 -0
  70. package/dist/components/features/mux-origins.js.map +1 -0
  71. package/dist/components/features/notifications/index.d.ts +2 -0
  72. package/dist/components/features/notifications/index.d.ts.map +1 -1
  73. package/dist/components/features/notifications/notification-drawer.d.ts +2 -1
  74. package/dist/components/features/notifications/notification-drawer.d.ts.map +1 -1
  75. package/dist/components/features/notifications/notification-popups.d.ts +10 -0
  76. package/dist/components/features/notifications/notification-popups.d.ts.map +1 -0
  77. package/dist/components/features/notifications/notifications-context.d.ts +8 -1
  78. package/dist/components/features/notifications/notifications-context.d.ts.map +1 -1
  79. package/dist/components/features/notifications/types.d.ts +1 -0
  80. package/dist/components/features/notifications/types.d.ts.map +1 -1
  81. package/dist/components/features/use-video-warmup.d.ts +53 -0
  82. package/dist/components/features/use-video-warmup.d.ts.map +1 -0
  83. package/dist/components/icons/index.cjs +3 -3
  84. package/dist/components/icons/index.js +2 -2
  85. package/dist/components/icons-v2-generated/index.cjs +2 -2
  86. package/dist/components/icons-v2-generated/index.cjs.map +1 -1
  87. package/dist/components/icons-v2-generated/index.js +4 -4
  88. package/dist/components/index.cjs +132 -102
  89. package/dist/components/index.cjs.map +1 -1
  90. package/dist/components/index.d.ts +1 -0
  91. package/dist/components/index.d.ts.map +1 -1
  92. package/dist/components/index.js +94 -64
  93. package/dist/components/index.js.map +1 -1
  94. package/dist/components/navigation/index.cjs +11 -11
  95. package/dist/components/navigation/index.js +10 -10
  96. package/dist/components/onboarding-guides/build-default-href.d.ts +15 -0
  97. package/dist/components/onboarding-guides/build-default-href.d.ts.map +1 -0
  98. package/dist/components/onboarding-guides/hooks/use-onboarding-guides.d.ts +28 -0
  99. package/dist/components/onboarding-guides/hooks/use-onboarding-guides.d.ts.map +1 -0
  100. package/dist/components/onboarding-guides/index.cjs +373 -0
  101. package/dist/components/onboarding-guides/index.cjs.map +1 -0
  102. package/dist/components/onboarding-guides/index.d.ts +25 -0
  103. package/dist/components/onboarding-guides/index.d.ts.map +1 -0
  104. package/dist/components/onboarding-guides/index.js +373 -0
  105. package/dist/components/onboarding-guides/index.js.map +1 -0
  106. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts +52 -0
  107. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -0
  108. package/dist/components/onboarding-guides/onboarding-guides-catalog-skeleton.d.ts +17 -0
  109. package/dist/components/onboarding-guides/onboarding-guides-catalog-skeleton.d.ts.map +1 -0
  110. package/dist/components/onboarding-guides/onboarding-guides-catalog-view.d.ts +43 -0
  111. package/dist/components/onboarding-guides/onboarding-guides-catalog-view.d.ts.map +1 -0
  112. package/dist/components/shared/doc-search/doc-search-bar.d.ts +59 -0
  113. package/dist/components/shared/doc-search/doc-search-bar.d.ts.map +1 -0
  114. package/dist/components/shared/doc-search/doc-search-result-row.d.ts +18 -0
  115. package/dist/components/shared/doc-search/doc-search-result-row.d.ts.map +1 -0
  116. package/dist/components/shared/doc-search/format-relative-path.d.ts +10 -0
  117. package/dist/components/shared/doc-search/format-relative-path.d.ts.map +1 -0
  118. package/dist/components/shared/doc-search/index.d.ts +8 -0
  119. package/dist/components/shared/doc-search/index.d.ts.map +1 -0
  120. package/dist/components/shared/doc-search/map-doc-search-results.d.ts +15 -0
  121. package/dist/components/shared/doc-search/map-doc-search-results.d.ts.map +1 -0
  122. package/dist/components/shared/doc-search/resolve-search-result-action.d.ts +37 -0
  123. package/dist/components/shared/doc-search/resolve-search-result-action.d.ts.map +1 -0
  124. package/dist/components/shared/doc-search/types.d.ts +29 -0
  125. package/dist/components/shared/doc-search/types.d.ts.map +1 -0
  126. package/dist/components/shared/doc-search/use-doc-search.d.ts +46 -0
  127. package/dist/components/shared/doc-search/use-doc-search.d.ts.map +1 -0
  128. package/dist/components/tickets/help-center-card.d.ts +5 -1
  129. package/dist/components/tickets/help-center-card.d.ts.map +1 -1
  130. package/dist/components/tickets/hooks/use-ticket-actions.d.ts +8 -0
  131. package/dist/components/tickets/hooks/use-ticket-actions.d.ts.map +1 -1
  132. package/dist/components/tickets/index.cjs +316 -145
  133. package/dist/components/tickets/index.cjs.map +1 -1
  134. package/dist/components/tickets/index.js +237 -66
  135. package/dist/components/tickets/index.js.map +1 -1
  136. package/dist/components/tickets/ticket-detail-drawer.d.ts +11 -2
  137. package/dist/components/tickets/ticket-detail-drawer.d.ts.map +1 -1
  138. package/dist/components/tickets/types.d.ts +50 -1
  139. package/dist/components/tickets/types.d.ts.map +1 -1
  140. package/dist/components/ui/file-manager/index.cjs +51 -51
  141. package/dist/components/ui/file-manager/index.cjs.map +1 -1
  142. package/dist/components/ui/file-manager/index.js +2 -2
  143. package/dist/components/ui/filter-pill-row.d.ts +20 -0
  144. package/dist/components/ui/filter-pill-row.d.ts.map +1 -0
  145. package/dist/components/ui/index.cjs +16 -14
  146. package/dist/components/ui/index.cjs.map +1 -1
  147. package/dist/components/ui/index.d.ts +1 -0
  148. package/dist/components/ui/index.d.ts.map +1 -1
  149. package/dist/components/ui/index.js +21 -19
  150. package/dist/components/ui/simple-markdown-renderer.d.ts.map +1 -1
  151. package/dist/contexts/chat-runtime-context.d.ts +42 -0
  152. package/dist/contexts/chat-runtime-context.d.ts.map +1 -1
  153. package/dist/contexts/index.cjs +2 -2
  154. package/dist/contexts/index.js +1 -1
  155. package/dist/embed-shims/index.cjs +3 -3
  156. package/dist/embed-shims/index.cjs.map +1 -1
  157. package/dist/embed-shims/index.js +5 -5
  158. package/dist/hooks/index.cjs +6 -6
  159. package/dist/hooks/index.js +5 -5
  160. package/dist/index.cjs +28 -14
  161. package/dist/index.cjs.map +1 -1
  162. package/dist/index.js +59 -45
  163. package/dist/utils/dev-sections/openframe-dev-sections.d.ts +2 -2
  164. package/dist/utils/dev-sections/openframe-dev-sections.d.ts.map +1 -1
  165. package/dist/utils/index.cjs +11 -5
  166. package/dist/utils/index.cjs.map +1 -1
  167. package/dist/utils/index.js +11 -5
  168. package/dist/utils/index.js.map +1 -1
  169. package/package.json +13 -1
  170. package/src/components/chat/entity-cards/blog-card.tsx +17 -5
  171. package/src/components/chat/entity-cards/case-study-card.tsx +23 -1
  172. package/src/components/chat/entity-cards/customer-interview-card.tsx +23 -1
  173. package/src/components/chat/entity-cards/dispatch.tsx +21 -0
  174. package/src/components/chat/entity-cards/investor-update-card.tsx +23 -1
  175. package/src/components/chat/entity-cards/onboarding-guide-card.tsx +30 -4
  176. package/src/components/chat/entity-cards/program-card.tsx +17 -3
  177. package/src/components/chat/entity-cards/use-entity-card-link.ts +66 -0
  178. package/src/components/chat/entity-cards/use-entity-card-placeholder.ts +50 -0
  179. package/src/components/features/captions-url.ts +25 -0
  180. package/src/components/features/index.ts +2 -0
  181. package/src/components/features/mux-origins.ts +27 -0
  182. package/src/components/features/notifications/index.ts +2 -0
  183. package/src/components/features/notifications/notification-drawer.tsx +100 -16
  184. package/src/components/features/notifications/notification-popups.tsx +105 -0
  185. package/src/components/features/notifications/notifications-context.tsx +16 -0
  186. package/src/components/features/notifications/types.ts +1 -0
  187. package/src/components/features/use-video-warmup.ts +176 -0
  188. package/src/components/index.ts +5 -0
  189. package/src/components/onboarding-guides/build-default-href.ts +16 -0
  190. package/src/components/onboarding-guides/hooks/use-onboarding-guides.ts +90 -0
  191. package/src/components/onboarding-guides/index.ts +39 -0
  192. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +215 -0
  193. package/src/components/onboarding-guides/onboarding-guides-catalog-skeleton.tsx +62 -0
  194. package/src/components/onboarding-guides/onboarding-guides-catalog-view.tsx +230 -0
  195. package/src/components/shared/doc-search/doc-search-bar.tsx +100 -0
  196. package/src/components/shared/doc-search/doc-search-result-row.tsx +73 -0
  197. package/src/components/shared/doc-search/format-relative-path.ts +17 -0
  198. package/src/components/shared/doc-search/index.ts +24 -0
  199. package/src/components/shared/doc-search/map-doc-search-results.ts +113 -0
  200. package/src/components/shared/doc-search/resolve-search-result-action.ts +68 -0
  201. package/src/components/shared/doc-search/types.ts +28 -0
  202. package/src/components/shared/doc-search/use-doc-search.ts +263 -0
  203. package/src/components/tickets/help-center-card.tsx +8 -0
  204. package/src/components/tickets/help-center-list.tsx +17 -3
  205. package/src/components/tickets/hooks/use-ticket-actions.ts +210 -14
  206. package/src/components/tickets/ticket-detail-drawer.tsx +145 -5
  207. package/src/components/tickets/types.ts +55 -0
  208. package/src/components/ui/filter-pill-row.tsx +72 -0
  209. package/src/components/ui/index.ts +1 -0
  210. package/src/components/ui/simple-markdown-renderer.tsx +24 -1
  211. package/src/components/ui/toaster.tsx +3 -3
  212. package/src/contexts/chat-runtime-context.tsx +41 -0
  213. package/src/stories/NotificationDrawer.stories.tsx +18 -2
  214. package/src/utils/dev-sections/openframe-dev-sections.ts +12 -5
  215. package/dist/chunk-2G3NXF6J.cjs +0 -521
  216. package/dist/chunk-2G3NXF6J.cjs.map +0 -1
  217. package/dist/chunk-D4MNFY67.cjs.map +0 -1
  218. package/dist/chunk-HICZPTRR.js.map +0 -1
  219. package/dist/chunk-P5EE2VJX.cjs.map +0 -1
  220. package/dist/chunk-R6MLPU4A.js +0 -521
  221. package/dist/chunk-R6MLPU4A.js.map +0 -1
  222. package/dist/chunk-WQZP3JIZ.js.map +0 -1
  223. package/dist/chunk-WT5JV2GS.cjs.map +0 -1
  224. package/dist/chunk-ZG2YY5E7.js.map +0 -1
  225. /package/dist/{chunk-4XLJWX2N.js.map → chunk-ORJREQ2W.js.map} +0 -0
  226. /package/dist/{chunk-7PCP7YQR.js.map → chunk-QTKU6ULP.js.map} +0 -0
  227. /package/dist/{chunk-CIPO6DXK.js.map → chunk-QY75VKAS.js.map} +0 -0
  228. /package/dist/{chunk-MX5MIFWA.js.map → chunk-UEBM4PC4.js.map} +0 -0
@@ -1,19 +1,21 @@
1
1
  "use client";
2
2
  import {
3
- ConversationCardRow,
4
- ConversationCardRowSkeletonList,
5
3
  DeliveryRow,
6
- DevCardRowContent,
7
- DevCardRowSkeletonList,
8
- DevSectionPage,
9
4
  EmptyState,
10
5
  UnifiedPagination,
11
6
  init_unified_pagination
12
- } from "../../chunk-R6MLPU4A.js";
13
- import "../../chunk-4XLJWX2N.js";
7
+ } from "../../chunk-2V4SACHE.js";
8
+ import {
9
+ ConversationCardRow,
10
+ ConversationCardRowSkeletonList,
11
+ DevCardRowContent,
12
+ DevCardRowSkeletonList,
13
+ DevSectionPage
14
+ } from "../../chunk-GVNQAGXB.js";
15
+ import "../../chunk-ORJREQ2W.js";
14
16
  import {
15
17
  ContactForm
16
- } from "../../chunk-7PCP7YQR.js";
18
+ } from "../../chunk-QTKU6ULP.js";
17
19
  import {
18
20
  AlertDialog,
19
21
  AlertDialogAction,
@@ -28,6 +30,7 @@ import {
28
30
  ChatAttachmentChipStrip,
29
31
  ChatTicketItem,
30
32
  Label,
33
+ SquareAvatar,
31
34
  StatusBadge,
32
35
  Textarea,
33
36
  embedAuthedFetch,
@@ -36,32 +39,32 @@ import {
36
39
  scrollElementIntoView,
37
40
  useChatAttachments,
38
41
  useChatIdentity
39
- } from "../../chunk-WQZP3JIZ.js";
40
- import {
41
- toast
42
- } from "../../chunk-HICZPTRR.js";
43
- import "../../chunk-CIPO6DXK.js";
44
- import "../../chunk-EDW2NVRV.js";
45
- import "../../chunk-W72U7OU7.js";
46
- import "../../chunk-ZG2YY5E7.js";
47
- import "../../chunk-MJNXIEV2.js";
42
+ } from "../../chunk-CDLYRFDE.js";
48
43
  import "../../chunk-LXC6P2EO.js";
49
44
  import "../../chunk-EL5YVPD5.js";
50
- import {
51
- usePathname,
52
- useRouter,
53
- useSearchParams
54
- } from "../../chunk-PLJLE4A4.js";
55
- import "../../chunk-CZR7ARBA.js";
56
45
  import {
57
46
  Button,
58
47
  Input,
59
48
  Skeleton,
60
49
  init_button2 as init_button
61
- } from "../../chunk-MX5MIFWA.js";
50
+ } from "../../chunk-UEBM4PC4.js";
51
+ import "../../chunk-OHPI2HRK.js";
52
+ import {
53
+ toast
54
+ } from "../../chunk-LCLTCCXS.js";
55
+ import {
56
+ usePathname,
57
+ useRouter,
58
+ useSearchParams
59
+ } from "../../chunk-PLJLE4A4.js";
60
+ import "../../chunk-QY75VKAS.js";
62
61
  import "../../chunk-KSOOKNBG.js";
62
+ import "../../chunk-EDW2NVRV.js";
63
63
  import "../../chunk-6U3IUD57.js";
64
- import "../../chunk-OHPI2HRK.js";
64
+ import "../../chunk-W72U7OU7.js";
65
+ import "../../chunk-RFONYT63.js";
66
+ import "../../chunk-MJNXIEV2.js";
67
+ import "../../chunk-CZR7ARBA.js";
65
68
  import "../../chunk-GGWZFCYS.js";
66
69
 
67
70
  // src/components/tickets/ticket-center.tsx
@@ -311,35 +314,47 @@ function TicketDetailDrawer({
311
314
  onSendMessage,
312
315
  onClose,
313
316
  onReopen,
314
- onActionCollapsed
317
+ onActionCollapsed,
318
+ replyError,
319
+ onClearReplyError
315
320
  }) {
316
321
  const isClosed = (ticket.status ?? "").toUpperCase() === "CLOSED";
317
322
  return /* @__PURE__ */ jsxs2("div", { className: "bg-ods-card border-t border-ods-border px-4 py-4 flex flex-col gap-4", children: [
323
+ /* @__PURE__ */ jsx3(AssignedAgentRow, { assignedOwner: ticket.assignedOwner }),
318
324
  ticket.clickup && /* @__PURE__ */ jsx3(TicketLinkedDeliveryCard, { clickup: ticket.clickup }),
319
325
  /* @__PURE__ */ jsxs2("div", { children: [
320
326
  /* @__PURE__ */ jsx3("p", { className: "text-xs font-medium text-ods-text-secondary mb-2 uppercase tracking-wider", children: "Conversation" }),
321
327
  /* @__PURE__ */ jsx3(TicketTimelinePanel, { ticket })
322
328
  ] }),
323
- /* @__PURE__ */ jsx3("div", { className: "border-t border-ods-border pt-4", children: isClosed ? /* @__PURE__ */ jsx3(
324
- ReopenAction,
325
- {
326
- ticketRef: { id: ticket.id, external_id: ticket.external_id },
327
- busy,
328
- supportSystemDown,
329
- onReopen,
330
- onActionCollapsed
331
- }
332
- ) : /* @__PURE__ */ jsx3(
333
- OpenActions,
334
- {
335
- ticket,
336
- busy,
337
- supportSystemDown,
338
- onSendMessage,
339
- onClose,
340
- onActionCollapsed
341
- }
342
- ) })
329
+ /* @__PURE__ */ jsxs2("div", { className: "border-t border-ods-border pt-4", children: [
330
+ replyError && /* @__PURE__ */ jsx3(
331
+ ReplyFailureBanner,
332
+ {
333
+ error: replyError,
334
+ onDismiss: onClearReplyError ?? (() => void 0)
335
+ }
336
+ ),
337
+ isClosed ? /* @__PURE__ */ jsx3(
338
+ ReopenAction,
339
+ {
340
+ ticketRef: { id: ticket.id, external_id: ticket.external_id },
341
+ busy,
342
+ supportSystemDown,
343
+ onReopen,
344
+ onActionCollapsed
345
+ }
346
+ ) : /* @__PURE__ */ jsx3(
347
+ OpenActions,
348
+ {
349
+ ticket,
350
+ busy,
351
+ supportSystemDown,
352
+ onSendMessage,
353
+ onClose,
354
+ onActionCollapsed
355
+ }
356
+ )
357
+ ] })
343
358
  ] });
344
359
  }
345
360
  var TURN_SEPARATOR_RE = /[\s]{1,16}---[\s]{1,16}/g;
@@ -449,8 +464,7 @@ function ReopenAction({
449
464
  onActionCollapsed
450
465
  }) {
451
466
  const handleReopen = async () => {
452
- const ok = await onReopen(ticketRef);
453
- if (ok) onActionCollapsed();
467
+ void await onReopen(ticketRef);
454
468
  };
455
469
  return /* @__PURE__ */ jsx3("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx3(
456
470
  Button,
@@ -490,9 +504,8 @@ function OpenActions({
490
504
  };
491
505
  const confirmClose = async () => {
492
506
  setCloseDialogOpen(false);
493
- const ok = await onClose(ticketRef, resolution.trim() || void 0);
507
+ await onClose(ticketRef, resolution.trim() || void 0);
494
508
  setResolution("");
495
- if (ok) onActionCollapsed();
496
509
  };
497
510
  return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-3", children: [
498
511
  /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-2", children: [
@@ -591,6 +604,56 @@ function OpenActions({
591
604
  ] }) })
592
605
  ] });
593
606
  }
607
+ function ReplyFailureBanner({
608
+ error,
609
+ onDismiss
610
+ }) {
611
+ return /* @__PURE__ */ jsxs2(
612
+ "div",
613
+ {
614
+ role: "status",
615
+ "aria-live": "polite",
616
+ className: "mb-3 flex items-start gap-3 rounded-md border border-ods-attention-red-error bg-ods-attention-red-error-secondary px-3 py-2 text-sm text-ods-attention-red-error",
617
+ children: [
618
+ /* @__PURE__ */ jsx3("span", { className: "font-medium leading-snug", children: error.message }),
619
+ /* @__PURE__ */ jsx3(
620
+ Button,
621
+ {
622
+ type: "button",
623
+ variant: "transparent",
624
+ onClick: onDismiss,
625
+ "aria-label": "Dismiss reply failure",
626
+ className: "ml-auto px-2 py-0.5 text-xs font-medium uppercase tracking-wider text-ods-attention-red-error hover:bg-ods-attention-red-error/10 border-transparent",
627
+ children: "Dismiss"
628
+ }
629
+ )
630
+ ]
631
+ }
632
+ );
633
+ }
634
+ function AssignedAgentRow({
635
+ assignedOwner
636
+ }) {
637
+ const trimmedName = assignedOwner?.name?.trim() || null;
638
+ const emailFallback = assignedOwner?.email?.trim() || null;
639
+ const displayLabel = trimmedName ?? (emailFallback ? emailFallback.split("@")[0] : null);
640
+ return /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 text-xs", children: [
641
+ /* @__PURE__ */ jsx3("span", { className: "text-ods-text-secondary uppercase tracking-wider font-medium", children: "Assigned to" }),
642
+ displayLabel ? /* @__PURE__ */ jsxs2("span", { className: "flex items-center gap-1.5 text-ods-text-primary font-medium", children: [
643
+ /* @__PURE__ */ jsx3(
644
+ SquareAvatar,
645
+ {
646
+ size: "sm",
647
+ variant: "round",
648
+ src: assignedOwner?.avatarUrl ?? void 0,
649
+ alt: displayLabel,
650
+ fallback: displayLabel
651
+ }
652
+ ),
653
+ displayLabel
654
+ ] }) : /* @__PURE__ */ jsx3("span", { className: "text-ods-text-secondary italic", children: "Unassigned" })
655
+ ] });
656
+ }
594
657
 
595
658
  // src/components/tickets/ticket-row.tsx
596
659
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
@@ -771,6 +834,12 @@ function useTicketsList(filters) {
771
834
  import { useCallback as useCallback2, useEffect, useMemo, useRef as useRef2, useState as useState3 } from "react";
772
835
  import { useQueryClient } from "@tanstack/react-query";
773
836
  var TICKET_ACTION_ENDPOINT = "/api/chat/agent/ticket-action";
837
+ var REPLY_BANNER_CODES = /* @__PURE__ */ new Set([
838
+ "HUBSPOT_5XX",
839
+ "HUBSPOT_400_VALIDATION",
840
+ "HUBSPOT_404_THREAD",
841
+ "HUBSPOT_REPLY_UNKNOWN"
842
+ ]);
774
843
  var MIRROR_SYNC_BACKOFF_MS = [3e3, 6e3, 12e3];
775
844
  function useTicketActions(options) {
776
845
  const queryClient = useQueryClient();
@@ -785,6 +854,26 @@ function useTicketActions(options) {
785
854
  setBusyRows(new Set(busyRowsRef.current));
786
855
  }, []);
787
856
  const isRowBusy = useCallback2((id) => busyRows.has(id), [busyRows]);
857
+ const [replyErrorByTicket, setReplyErrorByTicket] = useState3(() => /* @__PURE__ */ new Map());
858
+ const setReplyError = useCallback2(
859
+ (externalId, mapped) => {
860
+ setReplyErrorByTicket((prev) => {
861
+ const next = new Map(prev);
862
+ if (mapped) next.set(externalId, mapped);
863
+ else next.delete(externalId);
864
+ return next;
865
+ });
866
+ },
867
+ []
868
+ );
869
+ const replyErrorFor = useCallback2(
870
+ (externalId) => replyErrorByTicket.get(externalId) ?? null,
871
+ [replyErrorByTicket]
872
+ );
873
+ const clearReplyError = useCallback2(
874
+ (externalId) => setReplyError(externalId, null),
875
+ [setReplyError]
876
+ );
788
877
  const watcherControllersRef = useRef2(/* @__PURE__ */ new Map());
789
878
  useEffect(() => {
790
879
  return () => {
@@ -862,9 +951,11 @@ function useTicketActions(options) {
862
951
  },
863
952
  [queryClient, removeOptimistic, toast2]
864
953
  );
954
+ const lastUpdateErrorRef = useRef2(null);
865
955
  const surfaceError = useCallback2(
866
956
  (err, action) => {
867
957
  const mapped = mapTicketActionError(err);
958
+ lastUpdateErrorRef.current = mapped;
868
959
  if (mapped.supportSystemDown) onSupportSystemDown();
869
960
  toast2({
870
961
  title: `Could not ${action}`,
@@ -899,6 +990,10 @@ function useTicketActions(options) {
899
990
  // seconds via the mirror refetch. Drawer uses live chat
900
991
  // identity for own-replies during this window anyway.
901
992
  customer_name: null,
993
+ // No assignee until the real ticket lands. Drawer renders
994
+ // "Unassigned" for this brief window.
995
+ assigned_to: null,
996
+ assignedOwner: null,
902
997
  hubspot_updated_at: (/* @__PURE__ */ new Date()).toISOString(),
903
998
  _optimistic: true
904
999
  };
@@ -951,10 +1046,23 @@ function useTicketActions(options) {
951
1046
  ticket_id: ticket.external_id
952
1047
  });
953
1048
  toast2(successCopy);
954
- await Promise.all([
955
- queryClient.invalidateQueries({ queryKey: ["tickets"] }),
956
- queryClient.invalidateQueries({ queryKey: ["ticket-engagements"] })
957
- ]);
1049
+ const statusUpdate = serverArgs.status ?? null;
1050
+ if (statusUpdate) {
1051
+ queryClient.setQueriesData(
1052
+ { queryKey: ["tickets"] },
1053
+ (prev) => {
1054
+ if (!prev || !Array.isArray(prev.tickets)) return prev;
1055
+ let mutated = false;
1056
+ const nextTickets = prev.tickets.map((t) => {
1057
+ if (t.id !== ticket.id || t.status === statusUpdate) return t;
1058
+ mutated = true;
1059
+ return { ...t, status: statusUpdate };
1060
+ });
1061
+ return mutated ? { ...prev, tickets: nextTickets } : prev;
1062
+ }
1063
+ );
1064
+ }
1065
+ await queryClient.invalidateQueries({ queryKey: ["ticket-engagements"] });
958
1066
  return true;
959
1067
  });
960
1068
  } catch (err) {
@@ -974,12 +1082,13 @@ function useTicketActions(options) {
974
1082
  [setRowBusy, enqueue, executeTicketAction, queryClient, toast2, surfaceError, removeTicketFromCache]
975
1083
  );
976
1084
  const sendMessage = useCallback2(
977
- (ticket, text, attachments) => {
1085
+ async (ticket, text, attachments) => {
978
1086
  const trimmed = text.trim();
979
1087
  const hasText = trimmed.length > 0;
980
1088
  const hasFiles = attachments.length > 0;
981
- if (!hasText && !hasFiles) return Promise.resolve(false);
982
- return updateTicket(
1089
+ if (!hasText && !hasFiles) return false;
1090
+ lastUpdateErrorRef.current = null;
1091
+ const ok = await updateTicket(
983
1092
  ticket,
984
1093
  {
985
1094
  ...hasText ? { content_addendum: trimmed } : {},
@@ -988,8 +1097,18 @@ function useTicketActions(options) {
988
1097
  TOAST_COPY.comment_success,
989
1098
  "send message"
990
1099
  );
1100
+ if (ok) {
1101
+ clearReplyError(ticket.external_id);
1102
+ } else {
1103
+ const mapped = lastUpdateErrorRef.current;
1104
+ if (mapped && REPLY_BANNER_CODES.has(mapped.code)) {
1105
+ setReplyError(ticket.external_id, mapped);
1106
+ }
1107
+ lastUpdateErrorRef.current = null;
1108
+ }
1109
+ return ok;
991
1110
  },
992
- [updateTicket]
1111
+ [updateTicket, clearReplyError, setReplyError]
993
1112
  );
994
1113
  const closeTicket = useCallback2(
995
1114
  (ticket, resolution) => updateTicket(
@@ -1014,9 +1133,20 @@ function useTicketActions(options) {
1014
1133
  closeTicket,
1015
1134
  reopenTicket,
1016
1135
  isSubmittingForm,
1017
- isRowBusy
1136
+ isRowBusy,
1137
+ replyErrorFor,
1138
+ clearReplyError
1018
1139
  }),
1019
- [submitTicket, sendMessage, closeTicket, reopenTicket, isSubmittingForm, isRowBusy]
1140
+ [
1141
+ submitTicket,
1142
+ sendMessage,
1143
+ closeTicket,
1144
+ reopenTicket,
1145
+ isSubmittingForm,
1146
+ isRowBusy,
1147
+ replyErrorFor,
1148
+ clearReplyError
1149
+ ]
1020
1150
  );
1021
1151
  }
1022
1152
  var TicketActionFailure = class extends Error {
@@ -1075,6 +1205,34 @@ function mapTicketActionError(err) {
1075
1205
  supportSystemDown: false,
1076
1206
  removeRowFromCache: false
1077
1207
  };
1208
+ case "HUBSPOT_5XX":
1209
+ return {
1210
+ code: err.code,
1211
+ message: "We couldn't reach the support system. Your reply wasn't sent \u2014 please retry in a moment.",
1212
+ supportSystemDown: false,
1213
+ removeRowFromCache: false
1214
+ };
1215
+ case "HUBSPOT_400_VALIDATION":
1216
+ return {
1217
+ code: err.code,
1218
+ message: "Your reply was rejected. Please rephrase or remove unsupported content and try again.",
1219
+ supportSystemDown: false,
1220
+ removeRowFromCache: false
1221
+ };
1222
+ case "HUBSPOT_404_THREAD":
1223
+ return {
1224
+ code: err.code,
1225
+ message: "This conversation is no longer accepting replies. Open a new ticket to continue.",
1226
+ supportSystemDown: false,
1227
+ removeRowFromCache: false
1228
+ };
1229
+ case "HUBSPOT_REPLY_UNKNOWN":
1230
+ return {
1231
+ code: err.code,
1232
+ message: "Your reply didn't go through. Please retry.",
1233
+ supportSystemDown: false,
1234
+ removeRowFromCache: false
1235
+ };
1078
1236
  default:
1079
1237
  return {
1080
1238
  code: "UNKNOWN",
@@ -1098,9 +1256,11 @@ function cryptoRandomId() {
1098
1256
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
1099
1257
  }
1100
1258
  function cacheContainsTicket(queryClient, expectedTicketId) {
1101
- const entries = queryClient.getQueriesData({ queryKey: ["tickets"] });
1259
+ const entries = queryClient.getQueriesData({
1260
+ queryKey: ["tickets"]
1261
+ });
1102
1262
  for (const [, data] of entries) {
1103
- if (Array.isArray(data) && data.some((t) => t.external_id === expectedTicketId)) {
1263
+ if (data && Array.isArray(data.tickets) && data.tickets.some((t) => t.external_id === expectedTicketId)) {
1104
1264
  return true;
1105
1265
  }
1106
1266
  }
@@ -1274,7 +1434,9 @@ function HelpCenterCard({
1274
1434
  onSendMessage,
1275
1435
  onClose,
1276
1436
  onReopen,
1277
- onActionCollapsed
1437
+ onActionCollapsed,
1438
+ replyError,
1439
+ onClearReplyError
1278
1440
  }) {
1279
1441
  const optimistic = isOptimistic(ticket);
1280
1442
  const rawStatus = (ticket.status ?? "OPEN").toUpperCase();
@@ -1361,7 +1523,9 @@ function HelpCenterCard({
1361
1523
  onSendMessage,
1362
1524
  onClose,
1363
1525
  onReopen,
1364
- onActionCollapsed
1526
+ onActionCollapsed,
1527
+ replyError,
1528
+ onClearReplyError
1365
1529
  }
1366
1530
  ) })
1367
1531
  ]
@@ -1561,7 +1725,12 @@ function HelpCenterListAuthed({
1561
1725
  (ticketId) => {
1562
1726
  queryClient.setQueriesData(
1563
1727
  { queryKey: ["tickets"] },
1564
- (prev) => (prev ?? []).filter((t) => t.id !== ticketId)
1728
+ (prev) => {
1729
+ if (!prev || !Array.isArray(prev.tickets)) return prev;
1730
+ const nextTickets = prev.tickets.filter((t) => t.id !== ticketId);
1731
+ if (nextTickets.length === prev.tickets.length) return prev;
1732
+ return { ...prev, tickets: nextTickets };
1733
+ }
1565
1734
  );
1566
1735
  setExpandedTicketId((prev) => prev === ticketId ? null : prev);
1567
1736
  },
@@ -1647,7 +1816,9 @@ function HelpCenterListAuthed({
1647
1816
  onSendMessage: actions.sendMessage,
1648
1817
  onClose: actions.closeTicket,
1649
1818
  onReopen: actions.reopenTicket,
1650
- onActionCollapsed: () => setExpandedTicketId(null)
1819
+ onActionCollapsed: () => setExpandedTicketId(null),
1820
+ replyError: actions.replyErrorFor(ticket.external_id),
1821
+ onClearReplyError: () => actions.clearReplyError(ticket.external_id)
1651
1822
  },
1652
1823
  ticket.id
1653
1824
  )) })