@flamingo-stack/openframe-frontend-core 0.0.503 → 0.0.504-snapshot.20260801181709
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-SGWPW2AO.cjs → chunk-2A74VRAF.cjs} +18 -18
- package/dist/{chunk-SGWPW2AO.cjs.map → chunk-2A74VRAF.cjs.map} +1 -1
- package/dist/{chunk-LILQJ3UZ.cjs → chunk-3ENGUBJP.cjs} +1 -1
- package/dist/chunk-3ENGUBJP.cjs.map +1 -0
- package/dist/{chunk-AWDHRIL3.cjs → chunk-4ST2BOWJ.cjs} +75 -75
- package/dist/{chunk-AWDHRIL3.cjs.map → chunk-4ST2BOWJ.cjs.map} +1 -1
- package/dist/{chunk-SFJRMBJC.js → chunk-5SVNA7IU.js} +2 -2
- package/dist/{chunk-OAWFYZZT.js → chunk-7DOSAJDK.js} +3 -3
- package/dist/{chunk-J4T5ZBWG.cjs → chunk-BZRP54IO.cjs} +19 -19
- package/dist/{chunk-J4T5ZBWG.cjs.map → chunk-BZRP54IO.cjs.map} +1 -1
- package/dist/{chunk-BZF63JXP.js → chunk-CRJVO4KO.js} +6 -6
- package/dist/{chunk-5RIHLXEP.cjs → chunk-DDVQ5NKK.cjs} +33 -33
- package/dist/{chunk-5RIHLXEP.cjs.map → chunk-DDVQ5NKK.cjs.map} +1 -1
- package/dist/{chunk-HR6F6IP4.js → chunk-DIKJLAMY.js} +78 -43
- package/dist/chunk-DIKJLAMY.js.map +1 -0
- package/dist/{chunk-VO2ZONMR.js → chunk-FNTFWP2A.js} +3 -3
- package/dist/{chunk-2OXJ6NHI.cjs → chunk-GJZ42TTG.cjs} +7 -7
- package/dist/{chunk-2OXJ6NHI.cjs.map → chunk-GJZ42TTG.cjs.map} +1 -1
- package/dist/{chunk-JIZJDAXI.cjs → chunk-GXRVBKYX.cjs} +12 -12
- package/dist/{chunk-JIZJDAXI.cjs.map → chunk-GXRVBKYX.cjs.map} +1 -1
- package/dist/{chunk-F7AD5CUU.js → chunk-H3N4P3CG.js} +3 -3
- package/dist/chunk-H3N4P3CG.js.map +1 -0
- package/dist/{chunk-VCPTU4IW.js → chunk-HWER6KGU.js} +7 -7
- package/dist/{chunk-4SR2QHMB.js → chunk-ITVWX5HX.js} +3 -3
- package/dist/{chunk-FFXNRJ5S.cjs → chunk-LOBR7IC6.cjs} +6 -6
- package/dist/chunk-LOBR7IC6.cjs.map +1 -0
- package/dist/{chunk-72DF3QTA.cjs → chunk-MJQ263KS.cjs} +14 -14
- package/dist/{chunk-72DF3QTA.cjs.map → chunk-MJQ263KS.cjs.map} +1 -1
- package/dist/{chunk-FTOVZ7O2.js → chunk-NPO6CHCR.js} +7 -7
- package/dist/{chunk-XV5SXALY.js → chunk-NT5FX7GZ.js} +3 -3
- package/dist/{chunk-UCV4LFUG.cjs → chunk-NY75FKN6.cjs} +40 -40
- package/dist/{chunk-UCV4LFUG.cjs.map → chunk-NY75FKN6.cjs.map} +1 -1
- package/dist/{chunk-4UNQMYP7.cjs → chunk-O32Y4E4R.cjs} +3 -3
- package/dist/{chunk-4UNQMYP7.cjs.map → chunk-O32Y4E4R.cjs.map} +1 -1
- package/dist/{chunk-CLQEBWV7.js → chunk-QE55ROZW.js} +4 -4
- package/dist/{chunk-WHJGRRK2.js → chunk-QW7SW5HY.js} +52 -43
- package/dist/chunk-QW7SW5HY.js.map +1 -0
- package/dist/{chunk-JGXAVNZQ.js → chunk-R6CKL7IR.js} +2464 -1886
- package/dist/chunk-R6CKL7IR.js.map +1 -0
- package/dist/{chunk-L5CI57RM.cjs → chunk-T3BF6JTQ.cjs} +52 -43
- package/dist/chunk-T3BF6JTQ.cjs.map +1 -0
- package/dist/{chunk-G43CEISB.js → chunk-TA3VJ2QO.js} +4 -4
- package/dist/{chunk-7L2RVINX.cjs → chunk-TRS4CIAS.cjs} +35 -35
- package/dist/{chunk-7L2RVINX.cjs.map → chunk-TRS4CIAS.cjs.map} +1 -1
- package/dist/{chunk-DMXB3VE2.cjs → chunk-U3YLML53.cjs} +1837 -1259
- package/dist/chunk-U3YLML53.cjs.map +1 -0
- package/dist/{chunk-3T4SMJM5.cjs → chunk-VDKNUC3N.cjs} +181 -146
- package/dist/chunk-VDKNUC3N.cjs.map +1 -0
- package/dist/{chunk-RR3Z52X5.cjs → chunk-W3QCFQ56.cjs} +42 -42
- package/dist/{chunk-RR3Z52X5.cjs.map → chunk-W3QCFQ56.cjs.map} +1 -1
- package/dist/{chunk-VYEDTVIZ.js → chunk-XJPMTJAR.js} +4 -4
- package/dist/{chunk-6GT557KN.js → chunk-XKIA4XVE.js} +1 -1
- package/dist/chunk-XKIA4XVE.js.map +1 -0
- package/dist/components/case-studies/index.cjs +11 -11
- package/dist/components/case-studies/index.js +5 -5
- package/dist/components/chat/index.cjs +5 -5
- package/dist/components/chat/index.js +4 -4
- package/dist/components/contact/index.cjs +6 -6
- package/dist/components/contact/index.js +5 -5
- package/dist/components/docs/index.cjs +8 -8
- package/dist/components/docs/index.js +7 -7
- package/dist/components/embeds/index.cjs +6 -6
- package/dist/components/embeds/index.js +5 -5
- package/dist/components/faq/index.cjs +7 -7
- package/dist/components/faq/index.js +6 -6
- package/dist/components/features/index.cjs +5 -5
- package/dist/components/features/index.js +4 -4
- package/dist/components/help-center-pages/index.cjs +24 -24
- package/dist/components/help-center-pages/index.js +15 -15
- package/dist/components/index.cjs +169 -165
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +17 -13
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/app-header.d.ts +8 -0
- package/dist/components/navigation/app-header.d.ts.map +1 -1
- package/dist/components/navigation/header-button.d.ts +5 -1
- package/dist/components/navigation/header-button.d.ts.map +1 -1
- package/dist/components/navigation/header.d.ts.map +1 -1
- package/dist/components/navigation/index.cjs +9 -5
- package/dist/components/navigation/index.cjs.map +1 -1
- package/dist/components/navigation/index.d.ts +4 -0
- package/dist/components/navigation/index.d.ts.map +1 -1
- package/dist/components/navigation/index.js +8 -4
- package/dist/components/navigation/mingo-ai-button.d.ts.map +1 -1
- package/dist/components/navigation/navigation-sidebar-item.d.ts.map +1 -1
- package/dist/components/navigation/ticket-alerts-button.d.ts +29 -0
- package/dist/components/navigation/ticket-alerts-button.d.ts.map +1 -0
- package/dist/components/navigation/top-navigation.d.ts +5 -1
- package/dist/components/navigation/top-navigation.d.ts.map +1 -1
- package/dist/components/navigation/unread-dot.d.ts +19 -0
- package/dist/components/navigation/unread-dot.d.ts.map +1 -0
- package/dist/components/onboarding-guides/index.cjs +9 -9
- package/dist/components/onboarding-guides/index.js +8 -8
- package/dist/components/related-content/index.cjs +7 -7
- package/dist/components/related-content/index.js +6 -6
- package/dist/components/tickets/help-center-card.d.ts.map +1 -1
- package/dist/components/tickets/hooks/use-ticket-actions.d.ts.map +1 -1
- package/dist/components/tickets/hooks/use-ticket-engagements.d.ts +1 -9
- package/dist/components/tickets/hooks/use-ticket-engagements.d.ts.map +1 -1
- package/dist/components/tickets/hooks/use-tickets-list.d.ts +0 -7
- package/dist/components/tickets/hooks/use-tickets-list.d.ts.map +1 -1
- package/dist/components/tickets/index.cjs +15 -8
- package/dist/components/tickets/index.cjs.map +1 -1
- package/dist/components/tickets/index.d.ts +2 -1
- package/dist/components/tickets/index.d.ts.map +1 -1
- package/dist/components/tickets/index.js +14 -7
- package/dist/components/tickets/ticket-detail-drawer.d.ts.map +1 -1
- package/dist/components/tickets/ticket-live-provider.d.ts +58 -0
- package/dist/components/tickets/ticket-live-provider.d.ts.map +1 -0
- package/dist/components/tickets/types.d.ts +58 -11
- package/dist/components/tickets/types.d.ts.map +1 -1
- package/dist/components/ui/button/button.d.ts +6 -5
- package/dist/components/ui/button/button.d.ts.map +1 -1
- package/dist/components/ui/file-manager/index.cjs +50 -50
- package/dist/components/ui/file-manager/index.js +1 -1
- package/dist/components/ui/index.cjs +5 -5
- package/dist/components/ui/index.js +4 -4
- package/dist/contexts/chat-runtime-context.d.ts +8 -0
- package/dist/contexts/chat-runtime-context.d.ts.map +1 -1
- package/dist/contexts/index.cjs +2 -2
- package/dist/contexts/index.js +1 -1
- package/dist/hooks/index.cjs +3 -3
- package/dist/hooks/index.js +2 -2
- package/dist/hooks/ui/use-header-height.d.ts.map +1 -1
- package/dist/index.cjs +11 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +10 -4
- package/dist/types/navigation.d.ts +10 -0
- package/dist/types/navigation.d.ts.map +1 -1
- package/dist/utils/index.cjs +171 -0
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +171 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/sse-subscription.d.ts +60 -0
- package/dist/utils/sse-subscription.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/features/time-tracker/time-tracker-header-button.tsx +1 -1
- package/src/components/navigation/app-header.tsx +36 -20
- package/src/components/navigation/header-button.tsx +18 -2
- package/src/components/navigation/header-mingo-button.tsx +2 -2
- package/src/components/navigation/header-skeleton.tsx +4 -4
- package/src/components/navigation/header.tsx +41 -21
- package/src/components/navigation/index.ts +4 -0
- package/src/components/navigation/mingo-ai-button.tsx +23 -22
- package/src/components/navigation/mobile-burger-menu.tsx +3 -3
- package/src/components/navigation/navigation-sidebar-item.tsx +2 -3
- package/src/components/navigation/ticket-alerts-button.tsx +61 -0
- package/src/components/navigation/top-navigation.tsx +17 -1
- package/src/components/navigation/unread-dot.tsx +34 -0
- package/src/components/tickets/.types.md +1 -2
- package/src/components/tickets/help-center-card.tsx +16 -0
- package/src/components/tickets/help-center-list.tsx +6 -6
- package/src/components/tickets/hooks/.use-ticket-engagements.md +3 -12
- package/src/components/tickets/hooks/.use-tickets-list.md +0 -2
- package/src/components/tickets/hooks/use-ticket-actions.ts +9 -0
- package/src/components/tickets/hooks/use-ticket-engagements.ts +4 -13
- package/src/components/tickets/hooks/use-tickets-list.ts +2 -13
- package/src/components/tickets/index.ts +10 -0
- package/src/components/tickets/ticket-detail-drawer.tsx +45 -13
- package/src/components/tickets/ticket-live-provider.tsx +474 -0
- package/src/components/tickets/types.ts +62 -11
- package/src/components/ui/button/button.tsx +165 -133
- package/src/contexts/chat-runtime-context.tsx +8 -0
- package/src/hooks/ui/use-header-height.ts +3 -1
- package/src/stories/TopNavigation.stories.tsx +20 -1
- package/src/types/navigation.ts +10 -0
- package/src/utils/index.ts +12 -0
- package/src/utils/sse-subscription.ts +276 -0
- package/dist/chunk-3T4SMJM5.cjs.map +0 -1
- package/dist/chunk-6GT557KN.js.map +0 -1
- package/dist/chunk-DMXB3VE2.cjs.map +0 -1
- package/dist/chunk-F7AD5CUU.js.map +0 -1
- package/dist/chunk-FFXNRJ5S.cjs.map +0 -1
- package/dist/chunk-HR6F6IP4.js.map +0 -1
- package/dist/chunk-JGXAVNZQ.js.map +0 -1
- package/dist/chunk-L5CI57RM.cjs.map +0 -1
- package/dist/chunk-LILQJ3UZ.cjs.map +0 -1
- package/dist/chunk-WHJGRRK2.js.map +0 -1
- /package/dist/{chunk-SFJRMBJC.js.map → chunk-5SVNA7IU.js.map} +0 -0
- /package/dist/{chunk-OAWFYZZT.js.map → chunk-7DOSAJDK.js.map} +0 -0
- /package/dist/{chunk-BZF63JXP.js.map → chunk-CRJVO4KO.js.map} +0 -0
- /package/dist/{chunk-VO2ZONMR.js.map → chunk-FNTFWP2A.js.map} +0 -0
- /package/dist/{chunk-VCPTU4IW.js.map → chunk-HWER6KGU.js.map} +0 -0
- /package/dist/{chunk-4SR2QHMB.js.map → chunk-ITVWX5HX.js.map} +0 -0
- /package/dist/{chunk-FTOVZ7O2.js.map → chunk-NPO6CHCR.js.map} +0 -0
- /package/dist/{chunk-XV5SXALY.js.map → chunk-NT5FX7GZ.js.map} +0 -0
- /package/dist/{chunk-CLQEBWV7.js.map → chunk-QE55ROZW.js.map} +0 -0
- /package/dist/{chunk-G43CEISB.js.map → chunk-TA3VJ2QO.js.map} +0 -0
- /package/dist/{chunk-VYEDTVIZ.js.map → chunk-XJPMTJAR.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
ContactForm
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QE55ROZW.js";
|
|
5
5
|
import {
|
|
6
6
|
DeliveryRow,
|
|
7
7
|
DevCardRowContent,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
EmptyState,
|
|
11
11
|
UnifiedPagination,
|
|
12
12
|
init_unified_pagination
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-7DOSAJDK.js";
|
|
14
14
|
import {
|
|
15
15
|
AlertDialog,
|
|
16
16
|
AlertDialogAction,
|
|
@@ -36,18 +36,19 @@ import {
|
|
|
36
36
|
formatRelativeTime,
|
|
37
37
|
getStatusColorScheme,
|
|
38
38
|
useChatAttachments,
|
|
39
|
-
useChatIdentity
|
|
40
|
-
|
|
39
|
+
useChatIdentity,
|
|
40
|
+
useOptionalTicketLive
|
|
41
|
+
} from "./chunk-R6CKL7IR.js";
|
|
41
42
|
import {
|
|
42
43
|
STICKY_HEADER_OFFSET_PX,
|
|
43
44
|
embedAuthedFetch,
|
|
44
45
|
scrollElementIntoView,
|
|
45
46
|
toast,
|
|
46
47
|
useScrollToHash
|
|
47
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-H3N4P3CG.js";
|
|
48
49
|
import {
|
|
49
50
|
useRequiredChatRuntime
|
|
50
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-XKIA4XVE.js";
|
|
51
52
|
import {
|
|
52
53
|
usePathname,
|
|
53
54
|
useRouter,
|
|
@@ -58,7 +59,7 @@ import {
|
|
|
58
59
|
Input,
|
|
59
60
|
Skeleton,
|
|
60
61
|
init_button2 as init_button
|
|
61
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-QW7SW5HY.js";
|
|
62
63
|
|
|
63
64
|
// src/components/tickets/ticket-center.tsx
|
|
64
65
|
import { useCallback as useCallback4, useState as useState4 } from "react";
|
|
@@ -75,7 +76,7 @@ function isOptimistic(t) {
|
|
|
75
76
|
return t._optimistic === true;
|
|
76
77
|
}
|
|
77
78
|
var TICKET_TEXT_MAX_CHARS = 5e3;
|
|
78
|
-
var
|
|
79
|
+
var TICKET_MARK_READ_DEBOUNCE_MS = 2e3;
|
|
79
80
|
var TOAST_COPY = {
|
|
80
81
|
open_success: { title: "Ticket opened", description: "We received your message and will follow up shortly." },
|
|
81
82
|
open_mirror_pending: { title: "Ticket opened", description: "Syncing \u2014 your ticket will appear momentarily." },
|
|
@@ -211,7 +212,7 @@ function TicketOpenForm({
|
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
// src/components/tickets/ticket-row.tsx
|
|
214
|
-
import { useCallback as useCallback2, useRef } from "react";
|
|
215
|
+
import { useCallback as useCallback2, useRef as useRef2 } from "react";
|
|
215
216
|
|
|
216
217
|
// src/components/collapsible.tsx
|
|
217
218
|
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
@@ -220,12 +221,13 @@ var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
|
|
|
220
221
|
|
|
221
222
|
// src/components/tickets/ticket-detail-drawer.tsx
|
|
222
223
|
init_button();
|
|
224
|
+
import { useEffect, useRef } from "react";
|
|
223
225
|
import { useStickToBottom } from "use-stick-to-bottom";
|
|
224
226
|
|
|
225
227
|
// src/components/tickets/hooks/use-ticket-engagements.ts
|
|
226
228
|
import { useQuery } from "@tanstack/react-query";
|
|
227
229
|
var LIST_ENGAGEMENTS_ENDPOINT = "/api/chat/agent/list-engagements";
|
|
228
|
-
function useTicketEngagements(externalTicketId, enabled = true
|
|
230
|
+
function useTicketEngagements(externalTicketId, enabled = true) {
|
|
229
231
|
const identity = useChatIdentity();
|
|
230
232
|
const identityKey = identity.user?.email ?? "anon";
|
|
231
233
|
const listEngagementsEndpoint = useRequiredChatRuntime().endpoints.listEngagementsUrl ?? LIST_ENGAGEMENTS_ENDPOINT;
|
|
@@ -241,11 +243,10 @@ function useTicketEngagements(externalTicketId, enabled = true, refetchInterval
|
|
|
241
243
|
gcTime: 0,
|
|
242
244
|
refetchOnMount: "always",
|
|
243
245
|
refetchOnWindowFocus: true,
|
|
244
|
-
//
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
//
|
|
248
|
-
refetchInterval,
|
|
246
|
+
// NO interval polling (deleted 2026-08): new agent replies arrive via
|
|
247
|
+
// `TicketLiveProvider`'s stream-driven invalidation of
|
|
248
|
+
// `['ticket-engagements', id]`; focus/mount refetch is the no-stream
|
|
249
|
+
// fallback.
|
|
249
250
|
queryFn: async () => {
|
|
250
251
|
const response = await embedAuthedFetch(listEngagementsEndpoint, {
|
|
251
252
|
method: "POST",
|
|
@@ -504,11 +505,33 @@ var TICKET_FEED_SKELETON_ROWS = 6;
|
|
|
504
505
|
function TicketTimelinePanel({ ticket }) {
|
|
505
506
|
const identity = useChatIdentity();
|
|
506
507
|
const externalId = isOptimistic(ticket) ? null : ticket.external_id;
|
|
507
|
-
const { engagements, isLoading } = useTicketEngagements(
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
);
|
|
508
|
+
const { engagements, isLoading } = useTicketEngagements(externalId, !!externalId);
|
|
509
|
+
const live = useOptionalTicketLive();
|
|
510
|
+
const setOpenTicketId = live?.setOpenTicketId;
|
|
511
|
+
const markRead = live?.markRead;
|
|
512
|
+
const markReadDebounceRef = useRef(null);
|
|
513
|
+
useEffect(() => {
|
|
514
|
+
if (!externalId || !setOpenTicketId || !markRead) return;
|
|
515
|
+
setOpenTicketId(externalId);
|
|
516
|
+
void markRead(externalId);
|
|
517
|
+
return () => {
|
|
518
|
+
if (markReadDebounceRef.current) {
|
|
519
|
+
clearTimeout(markReadDebounceRef.current);
|
|
520
|
+
markReadDebounceRef.current = null;
|
|
521
|
+
void markRead(externalId);
|
|
522
|
+
}
|
|
523
|
+
setOpenTicketId(null);
|
|
524
|
+
};
|
|
525
|
+
}, [externalId, setOpenTicketId, markRead]);
|
|
526
|
+
const engagementsCount = engagements.length;
|
|
527
|
+
useEffect(() => {
|
|
528
|
+
if (!externalId || !markRead || engagementsCount === 0) return;
|
|
529
|
+
if (markReadDebounceRef.current) clearTimeout(markReadDebounceRef.current);
|
|
530
|
+
markReadDebounceRef.current = setTimeout(() => {
|
|
531
|
+
markReadDebounceRef.current = null;
|
|
532
|
+
void markRead(externalId);
|
|
533
|
+
}, TICKET_MARK_READ_DEBOUNCE_MS);
|
|
534
|
+
}, [engagementsCount, externalId, markRead]);
|
|
512
535
|
const { scrollRef, contentRef } = useStickToBottom({ initial: "instant", resize: "smooth" });
|
|
513
536
|
const bodyTurns = ticket.body ? ticket.body.split(TURN_SEPARATOR_RE).map((t) => t.trim()).filter(Boolean) : [];
|
|
514
537
|
const customerEngagementBodies = new Set(
|
|
@@ -693,7 +716,7 @@ function TicketRow({
|
|
|
693
716
|
id
|
|
694
717
|
}) {
|
|
695
718
|
const optimistic = isOptimistic(ticket);
|
|
696
|
-
const rowRef =
|
|
719
|
+
const rowRef = useRef2(null);
|
|
697
720
|
const handleClick = useCallback2(() => {
|
|
698
721
|
onToggle(ticket.id);
|
|
699
722
|
scrollElementIntoView(rowRef.current, {
|
|
@@ -783,7 +806,6 @@ function useTicketsList(filters) {
|
|
|
783
806
|
const pageSize = Math.max(1, Math.min(100, Math.floor(filters.pageSize ?? DEFAULT_PAGE_SIZE) || DEFAULT_PAGE_SIZE));
|
|
784
807
|
const enabled = !!customerEmail;
|
|
785
808
|
const identityKey = customerEmail || "anon";
|
|
786
|
-
const refetchInterval = filters.refetchInterval ?? false;
|
|
787
809
|
const query = useQuery2({
|
|
788
810
|
queryKey: ["tickets", "self", identityKey, search, statusFilter, page, pageSize],
|
|
789
811
|
enabled,
|
|
@@ -796,10 +818,8 @@ function useTicketsList(filters) {
|
|
|
796
818
|
gcTime: 0,
|
|
797
819
|
refetchOnMount: "always",
|
|
798
820
|
refetchOnWindowFocus: true,
|
|
799
|
-
//
|
|
800
|
-
//
|
|
801
|
-
// pauses on a hidden tab — no wasted requests when the user tabs away.
|
|
802
|
-
refetchInterval,
|
|
821
|
+
// NO interval polling (deleted 2026-08): live freshness is push-driven
|
|
822
|
+
// — `TicketLiveProvider` invalidates `['tickets']` on stream events.
|
|
803
823
|
queryFn: async () => {
|
|
804
824
|
const body = {
|
|
805
825
|
query: search,
|
|
@@ -861,7 +881,7 @@ function useTicketsList(filters) {
|
|
|
861
881
|
}
|
|
862
882
|
|
|
863
883
|
// src/components/tickets/hooks/use-ticket-actions.ts
|
|
864
|
-
import { useCallback as useCallback3, useEffect, useMemo, useRef as
|
|
884
|
+
import { useCallback as useCallback3, useEffect as useEffect2, useMemo, useRef as useRef3, useState as useState3 } from "react";
|
|
865
885
|
import { useQueryClient } from "@tanstack/react-query";
|
|
866
886
|
var TICKET_ACTION_ENDPOINT = "/api/chat/agent/ticket-action";
|
|
867
887
|
var REPLY_BANNER_CODES = /* @__PURE__ */ new Set([
|
|
@@ -874,10 +894,12 @@ var MIRROR_SYNC_BACKOFF_MS = [3e3, 6e3, 12e3];
|
|
|
874
894
|
function useTicketActions(options) {
|
|
875
895
|
const queryClient = useQueryClient();
|
|
876
896
|
const ticketActionEndpoint = useRequiredChatRuntime().endpoints.ticketActionUrl ?? TICKET_ACTION_ENDPOINT;
|
|
897
|
+
const ticketLive = useOptionalTicketLive();
|
|
898
|
+
const notifyTicketCreated = ticketLive?.notifyTicketCreated;
|
|
877
899
|
const { prependOptimistic, removeOptimistic, removeTicketFromCache, toast: toast2, onSupportSystemDown } = options;
|
|
878
|
-
const formInFlightRef =
|
|
900
|
+
const formInFlightRef = useRef3(false);
|
|
879
901
|
const [isSubmittingForm, setIsSubmittingForm] = useState3(false);
|
|
880
|
-
const busyRowsRef =
|
|
902
|
+
const busyRowsRef = useRef3(/* @__PURE__ */ new Set());
|
|
881
903
|
const [busyRows, setBusyRows] = useState3(() => /* @__PURE__ */ new Set());
|
|
882
904
|
const setRowBusy = useCallback3((id, busy) => {
|
|
883
905
|
if (busy) busyRowsRef.current.add(id);
|
|
@@ -905,8 +927,8 @@ function useTicketActions(options) {
|
|
|
905
927
|
(externalId) => setReplyError(externalId, null),
|
|
906
928
|
[setReplyError]
|
|
907
929
|
);
|
|
908
|
-
const watcherControllersRef =
|
|
909
|
-
|
|
930
|
+
const watcherControllersRef = useRef3(/* @__PURE__ */ new Map());
|
|
931
|
+
useEffect2(() => {
|
|
910
932
|
return () => {
|
|
911
933
|
for (const controller of watcherControllersRef.current.values()) {
|
|
912
934
|
controller.abort();
|
|
@@ -914,7 +936,7 @@ function useTicketActions(options) {
|
|
|
914
936
|
watcherControllersRef.current.clear();
|
|
915
937
|
};
|
|
916
938
|
}, []);
|
|
917
|
-
const queueRef =
|
|
939
|
+
const queueRef = useRef3(Promise.resolve());
|
|
918
940
|
const enqueue = useCallback3((work) => {
|
|
919
941
|
const next = queueRef.current.then(work, work);
|
|
920
942
|
queueRef.current = next.catch(() => void 0);
|
|
@@ -982,7 +1004,7 @@ function useTicketActions(options) {
|
|
|
982
1004
|
},
|
|
983
1005
|
[queryClient, removeOptimistic, toast2]
|
|
984
1006
|
);
|
|
985
|
-
const lastUpdateErrorRef =
|
|
1007
|
+
const lastUpdateErrorRef = useRef3(null);
|
|
986
1008
|
const surfaceError = useCallback3(
|
|
987
1009
|
(err, action) => {
|
|
988
1010
|
const mapped = mapTicketActionError(err);
|
|
@@ -1044,6 +1066,7 @@ function useTicketActions(options) {
|
|
|
1044
1066
|
await queryClient.invalidateQueries({ queryKey: ["tickets"] });
|
|
1045
1067
|
removeOptimistic(placeholderId);
|
|
1046
1068
|
}
|
|
1069
|
+
notifyTicketCreated?.();
|
|
1047
1070
|
return true;
|
|
1048
1071
|
});
|
|
1049
1072
|
} catch (err) {
|
|
@@ -1063,6 +1086,7 @@ function useTicketActions(options) {
|
|
|
1063
1086
|
queryClient,
|
|
1064
1087
|
toast2,
|
|
1065
1088
|
watchMirrorSync,
|
|
1089
|
+
notifyTicketCreated,
|
|
1066
1090
|
surfaceError
|
|
1067
1091
|
]
|
|
1068
1092
|
);
|
|
@@ -1454,7 +1478,7 @@ import { useQueryClient as useQueryClient3 } from "@tanstack/react-query";
|
|
|
1454
1478
|
init_unified_pagination();
|
|
1455
1479
|
|
|
1456
1480
|
// src/components/tickets/help-center-card.tsx
|
|
1457
|
-
import { useCallback as useCallback5, useEffect as
|
|
1481
|
+
import { useCallback as useCallback5, useEffect as useEffect3, useRef as useRef4 } from "react";
|
|
1458
1482
|
import { Fragment, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1459
1483
|
function HelpCenterCard({
|
|
1460
1484
|
ticket,
|
|
@@ -1479,11 +1503,11 @@ function HelpCenterCard({
|
|
|
1479
1503
|
const description = ticket.preview ?? ticket.body ?? "";
|
|
1480
1504
|
const isExpandable = !optimistic;
|
|
1481
1505
|
const isExpanded = expanded && isExpandable;
|
|
1482
|
-
const rowRef =
|
|
1506
|
+
const rowRef = useRef4(null);
|
|
1483
1507
|
const handleClick = useCallback5(() => {
|
|
1484
1508
|
onToggle(ticket.id);
|
|
1485
1509
|
}, [onToggle, ticket.id]);
|
|
1486
|
-
|
|
1510
|
+
useEffect3(() => {
|
|
1487
1511
|
if (!isExpanded) return;
|
|
1488
1512
|
const raf = requestAnimationFrame(() => {
|
|
1489
1513
|
scrollElementIntoView(rowRef.current, {
|
|
@@ -1492,7 +1516,18 @@ function HelpCenterCard({
|
|
|
1492
1516
|
});
|
|
1493
1517
|
return () => cancelAnimationFrame(raf);
|
|
1494
1518
|
}, [isExpanded]);
|
|
1519
|
+
const live = useOptionalTicketLive();
|
|
1520
|
+
const unreadCount = !optimistic && ticket.external_id && live?.unreadByTicket[ticket.external_id] || 0;
|
|
1495
1521
|
const rightBadges = /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
1522
|
+
unreadCount > 0 && /* @__PURE__ */ jsx7(
|
|
1523
|
+
StatusBadge,
|
|
1524
|
+
{
|
|
1525
|
+
text: `${unreadCount} NEW`,
|
|
1526
|
+
colorScheme: "warning",
|
|
1527
|
+
variant: "card",
|
|
1528
|
+
className: "border border-ods-border"
|
|
1529
|
+
}
|
|
1530
|
+
),
|
|
1496
1531
|
/* @__PURE__ */ jsx7(
|
|
1497
1532
|
StatusBadge,
|
|
1498
1533
|
{
|
|
@@ -1768,12 +1803,12 @@ function HelpCenterListAuthed({
|
|
|
1768
1803
|
customerEmail: sessionEmail,
|
|
1769
1804
|
search,
|
|
1770
1805
|
status,
|
|
1771
|
-
page
|
|
1772
|
-
//
|
|
1773
|
-
//
|
|
1774
|
-
//
|
|
1775
|
-
//
|
|
1776
|
-
|
|
1806
|
+
page
|
|
1807
|
+
// No interval polling (deleted 2026-08): `TicketLiveProvider`
|
|
1808
|
+
// invalidates `['tickets']` on stream events; focus/mount refetch
|
|
1809
|
+
// covers hosts without a stream. Disclosed trade-off: a bare
|
|
1810
|
+
// status/pipeline change with no accompanying reply has no live
|
|
1811
|
+
// path until the next event/focus/reconnect.
|
|
1777
1812
|
});
|
|
1778
1813
|
const expandedTicketId = ticketParam && tickets.find((t) => t.external_id === ticketParam)?.id || null;
|
|
1779
1814
|
const prependOptimistic = useCallback6((placeholder) => {
|
|
@@ -1913,4 +1948,4 @@ export {
|
|
|
1913
1948
|
HelpCenterCreateForm,
|
|
1914
1949
|
HelpCenterList
|
|
1915
1950
|
};
|
|
1916
|
-
//# sourceMappingURL=chunk-
|
|
1951
|
+
//# sourceMappingURL=chunk-DIKJLAMY.js.map
|