@consilioweb/payload-support 0.9.13 → 0.10.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.
- package/dist/components/TicketConversation/locales/en.json +8 -0
- package/dist/components/TicketConversation/locales/fr.json +9 -1
- package/dist/styles/TicketDetail.module.scss +270 -20
- package/dist/styles/TicketInbox.module.scss +112 -50
- package/dist/views/TicketDetailView/client.cjs +80 -13
- package/dist/views/TicketDetailView/client.js +80 -13
- package/dist/views/TicketInboxView/client.cjs +116 -58
- package/dist/views/TicketInboxView/client.js +116 -58
- package/dist/views/shared/StatusPill.cjs +36 -0
- package/dist/views/shared/StatusPill.js +30 -0
- package/dist/views/shared/StatusPill.module.scss +66 -0
- package/dist/views/shared/index.cjs +14 -0
- package/dist/views/shared/index.js +2 -0
- package/dist/views/shared/sla.cjs +37 -0
- package/dist/views/shared/sla.js +34 -0
- package/package.json +1 -1
- package/src/components/TicketConversation/locales/en.json +8 -0
- package/src/components/TicketConversation/locales/fr.json +9 -1
- package/src/styles/TicketDetail.module.scss +270 -20
- package/src/styles/TicketInbox.module.scss +112 -50
- package/src/views/TicketDetailView/client.tsx +88 -27
- package/src/views/TicketInboxView/client.tsx +106 -50
- package/src/views/shared/StatusPill.module.scss +66 -0
- package/src/views/shared/StatusPill.tsx +44 -0
- package/src/views/shared/index.ts +4 -0
- package/src/views/shared/sla.ts +56 -0
|
@@ -8,6 +8,7 @@ var index = require('../../components/RichTextEditor/index');
|
|
|
8
8
|
var CodeBlock = require('../../components/TicketConversation/components/CodeBlock');
|
|
9
9
|
var CodeBlockInserter = require('../../components/TicketConversation/components/CodeBlockInserter');
|
|
10
10
|
var config = require('../shared/config');
|
|
11
|
+
var sla = require('../shared/sla');
|
|
11
12
|
var useTranslation = require('../../components/TicketConversation/hooks/useTranslation');
|
|
12
13
|
var s = require('../../styles/TicketDetail.module.scss');
|
|
13
14
|
|
|
@@ -669,6 +670,46 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
669
670
|
] })
|
|
670
671
|
] })
|
|
671
672
|
] }),
|
|
673
|
+
(() => {
|
|
674
|
+
const slaInfo = sla.computeSlaState({
|
|
675
|
+
slaFirstResponseDue: ticket.slaFirstResponseDue,
|
|
676
|
+
slaFirstResponseBreached: ticket.slaFirstResponseBreached,
|
|
677
|
+
slaResolutionDue: ticket.slaResolutionDue,
|
|
678
|
+
slaResolutionBreached: ticket.slaResolutionBreached,
|
|
679
|
+
firstResponseAt: ticket.firstResponseAt
|
|
680
|
+
});
|
|
681
|
+
if (slaInfo.state !== "breach") return null;
|
|
682
|
+
const duration = sla.formatSlaRemaining(slaInfo.remainingMs).replace(/^−/, "");
|
|
683
|
+
const target = slaInfo.due ? new Date(slaInfo.due).toLocaleString("fr-FR", { day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit" }) : "";
|
|
684
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.slaBanner, role: "alert", children: [
|
|
685
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.slaBannerIcon, "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
686
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 9v4M12 17h.01" }),
|
|
687
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10.3 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" })
|
|
688
|
+
] }) }),
|
|
689
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.slaBannerBody, children: [
|
|
690
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: t("inbox.slaBanner.breached") }),
|
|
691
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.slaBannerSep, children: "\u2014" }),
|
|
692
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: t("inbox.slaBanner.responseAwaitedFor", { duration }) }),
|
|
693
|
+
target && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: s__default.default.slaBannerTarget, children: [
|
|
694
|
+
"\xB7 ",
|
|
695
|
+
t("inbox.slaBanner.target", { target })
|
|
696
|
+
] })
|
|
697
|
+
] }),
|
|
698
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
699
|
+
"button",
|
|
700
|
+
{
|
|
701
|
+
type: "button",
|
|
702
|
+
className: s__default.default.slaBannerCta,
|
|
703
|
+
onClick: () => handleStatusChange("escalated"),
|
|
704
|
+
"aria-label": t("inbox.slaBanner.escalate"),
|
|
705
|
+
children: [
|
|
706
|
+
"\u2191 ",
|
|
707
|
+
t("inbox.slaBanner.escalate")
|
|
708
|
+
]
|
|
709
|
+
}
|
|
710
|
+
)
|
|
711
|
+
] });
|
|
712
|
+
})(),
|
|
672
713
|
otherViewers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
673
714
|
display: "flex",
|
|
674
715
|
alignItems: "center",
|
|
@@ -695,8 +736,17 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
695
736
|
const isPendingDelete = undoToast?.msgId === msg.id;
|
|
696
737
|
return /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
|
|
697
738
|
showDate && /* @__PURE__ */ jsxRuntime.jsx("div", { className: s__default.default.dateSeparator, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.dateSeparatorText, children: dateLabel(msg.createdAt) }) }),
|
|
698
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${s__default.default.message} ${msg.isInternal ? s__default.default.messageInternal : ""}`, style: isPendingDelete ? { opacity: 0.3, pointerEvents: "none" } : void 0, children: [
|
|
699
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
739
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${s__default.default.message} ${isAdmin ? s__default.default.messageAdmin : s__default.default.messageClient} ${msg.isInternal ? s__default.default.messageInternal : ""}`, style: isPendingDelete ? { opacity: 0.3, pointerEvents: "none" } : void 0, children: [
|
|
740
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
741
|
+
"div",
|
|
742
|
+
{
|
|
743
|
+
className: s__default.default.avatar,
|
|
744
|
+
style: {
|
|
745
|
+
backgroundColor: isAdmin ? "var(--theme-info-500, #2a6bd8)" : msg.authorType === "email" ? "var(--theme-warning-500, #c97a0a)" : "var(--theme-accent-500, #6b46e8)"
|
|
746
|
+
},
|
|
747
|
+
children: isAdmin ? "CW" : initials
|
|
748
|
+
}
|
|
749
|
+
),
|
|
700
750
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.messageContent, children: [
|
|
701
751
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.messageHeader, children: [
|
|
702
752
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.messageAuthor, children: isAdmin ? "Support" : msg.authorType === "email" ? "Email" : client?.firstName || "Client" }),
|
|
@@ -798,7 +848,17 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
798
848
|
children: [
|
|
799
849
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.composerToolbar, children: [
|
|
800
850
|
features.ai && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
801
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
851
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
852
|
+
"button",
|
|
853
|
+
{
|
|
854
|
+
className: `${s__default.default.toolbarBtn} ${s__default.default.toolbarBtnAi}`,
|
|
855
|
+
"data-tooltip": t("detail.iaSuggestion"),
|
|
856
|
+
"aria-label": t("detail.iaSuggestion"),
|
|
857
|
+
onClick: handleAiSuggest,
|
|
858
|
+
disabled: aiReplying || messages.length === 0,
|
|
859
|
+
children: aiReplying ? "\u2026" : `\u2728 ${t("detail.iaSuggestion")}`
|
|
860
|
+
}
|
|
861
|
+
),
|
|
802
862
|
/* @__PURE__ */ jsxRuntime.jsx(RewriteDropdown, { disabled: aiRewriting || !replyBody.trim(), loading: aiRewriting, onSelect: (style) => handleAiRewrite(style), toolbarBtnClass: s__default.default.toolbarBtn })
|
|
803
863
|
] }),
|
|
804
864
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -921,6 +981,10 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
921
981
|
] })
|
|
922
982
|
] })
|
|
923
983
|
] }),
|
|
984
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: s__default.default.sendShortcut, "aria-hidden": true, children: [
|
|
985
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { children: "\u2318" }),
|
|
986
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { children: "\u21B5" })
|
|
987
|
+
] }),
|
|
924
988
|
/* @__PURE__ */ jsxRuntime.jsx("button", { className: `${s__default.default.sendBtn} ${isInternal ? s__default.default.sendBtnInternal : ""}`, onClick: handleSend, disabled: sending || !replyBody.trim(), "data-action": "send-reply", children: sending ? t("detail.sending") : sendAsClient ? "Ajouter message client" : isInternal ? t("detail.sendNote") : t("detail.sendReply") })
|
|
925
989
|
] })
|
|
926
990
|
]
|
|
@@ -946,6 +1010,18 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
946
1010
|
/* @__PURE__ */ jsxRuntime.jsx("button", { className: s__default.default.smallBtn, onClick: () => window.open(`/api/admin/impersonate?clientId=${client.id}`, "_blank"), children: t("client.clientPortal") })
|
|
947
1011
|
] })
|
|
948
1012
|
] }),
|
|
1013
|
+
clientSummary && clientSummary.summary && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${s__default.default.sideSection} ${s__default.default.aiCard}`, children: [
|
|
1014
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.aiCardTitle, children: [
|
|
1015
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.aiCardIcon, "aria-hidden": true, children: "\u2728" }),
|
|
1016
|
+
"Synth\xE8se client"
|
|
1017
|
+
] }),
|
|
1018
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: s__default.default.aiCardLead, children: clientSummary.summary }),
|
|
1019
|
+
clientSummary.recurringTopics && clientSummary.recurringTopics.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: s__default.default.aiCardChips, children: clientSummary.recurringTopics.slice(0, 5).map((tp, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.aiChip, children: tp.topic }, `tp-${i}`)) }),
|
|
1020
|
+
clientSummary.keyFacts && clientSummary.keyFacts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: s__default.default.aiCardFacts, children: clientSummary.keyFacts.slice(0, 4).map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: s__default.default.aiCardFact, children: [
|
|
1021
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.aiCardDot, "aria-hidden": true }),
|
|
1022
|
+
f
|
|
1023
|
+
] }, `kf-${i}`)) })
|
|
1024
|
+
] }),
|
|
949
1025
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.sideSection, children: [
|
|
950
1026
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: s__default.default.sideSectionTitle, children: t("detail.details") }),
|
|
951
1027
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.sideField, children: [
|
|
@@ -1203,16 +1279,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1203
1279
|
] })
|
|
1204
1280
|
] }, a.id))
|
|
1205
1281
|
] }),
|
|
1206
|
-
|
|
1207
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.sideSectionTitle, style: { display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
1208
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 13 }, children: "\u{1F9E0}" }),
|
|
1209
|
-
" R\xE9sum\xE9 client"
|
|
1210
|
-
] }),
|
|
1211
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "0 0 8px", fontSize: 11, lineHeight: 1.6, color: "#374151" }, children: clientSummary.summary }),
|
|
1212
|
-
clientSummary.recurringTopics && clientSummary.recurringTopics.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 4, marginBottom: 6 }, children: clientSummary.recurringTopics.slice(0, 3).map((tp, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: { padding: "2px 8px", borderRadius: 10, background: "rgba(37,99,235,0.08)", color: "#2563eb", fontSize: 10, fontWeight: 600 }, children: tp.topic }, i)) }),
|
|
1213
|
-
clientSummary.keyFacts && clientSummary.keyFacts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 4 }, children: clientSummary.keyFacts.slice(0, 3).map((f, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: { padding: "2px 8px", borderRadius: 10, background: "rgba(22,163,74,0.08)", color: "#16a34a", fontSize: 10, fontWeight: 600 }, children: f }, i)) })
|
|
1214
|
-
] }),
|
|
1215
|
-
summaryLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: s__default.default.sideSection, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: "#94a3b8", textAlign: "center", padding: 8 }, children: "\u{1F9E0} Chargement r\xE9sum\xE9..." }) })
|
|
1282
|
+
summaryLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: s__default.default.sideSection, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: "var(--theme-elevation-400)", textAlign: "center", padding: 8 }, children: "\u2728 Chargement de la synth\xE8se\u2026" }) })
|
|
1216
1283
|
] })
|
|
1217
1284
|
] }),
|
|
1218
1285
|
undoToast && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.undoToast, role: "alert", children: [
|
|
@@ -7,6 +7,7 @@ import { RichTextEditor } from '../../components/RichTextEditor/index.js';
|
|
|
7
7
|
import { hasCodeBlocks, CodeBlockRendererHtml, MessageWithCodeBlocks } from '../../components/TicketConversation/components/CodeBlock.js';
|
|
8
8
|
import { CodeBlockInserter } from '../../components/TicketConversation/components/CodeBlockInserter.js';
|
|
9
9
|
import { getFeatures } from '../shared/config.js';
|
|
10
|
+
import { computeSlaState, formatSlaRemaining } from '../shared/sla.js';
|
|
10
11
|
import { useTranslation } from '../../components/TicketConversation/hooks/useTranslation.js';
|
|
11
12
|
import s from '../../styles/TicketDetail.module.scss';
|
|
12
13
|
|
|
@@ -662,6 +663,46 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
662
663
|
] })
|
|
663
664
|
] })
|
|
664
665
|
] }),
|
|
666
|
+
(() => {
|
|
667
|
+
const slaInfo = computeSlaState({
|
|
668
|
+
slaFirstResponseDue: ticket.slaFirstResponseDue,
|
|
669
|
+
slaFirstResponseBreached: ticket.slaFirstResponseBreached,
|
|
670
|
+
slaResolutionDue: ticket.slaResolutionDue,
|
|
671
|
+
slaResolutionBreached: ticket.slaResolutionBreached,
|
|
672
|
+
firstResponseAt: ticket.firstResponseAt
|
|
673
|
+
});
|
|
674
|
+
if (slaInfo.state !== "breach") return null;
|
|
675
|
+
const duration = formatSlaRemaining(slaInfo.remainingMs).replace(/^−/, "");
|
|
676
|
+
const target = slaInfo.due ? new Date(slaInfo.due).toLocaleString("fr-FR", { day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit" }) : "";
|
|
677
|
+
return /* @__PURE__ */ jsxs("div", { className: s.slaBanner, role: "alert", children: [
|
|
678
|
+
/* @__PURE__ */ jsx("span", { className: s.slaBannerIcon, "aria-hidden": true, children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
679
|
+
/* @__PURE__ */ jsx("path", { d: "M12 9v4M12 17h.01" }),
|
|
680
|
+
/* @__PURE__ */ jsx("path", { d: "M10.3 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" })
|
|
681
|
+
] }) }),
|
|
682
|
+
/* @__PURE__ */ jsxs("div", { className: s.slaBannerBody, children: [
|
|
683
|
+
/* @__PURE__ */ jsx("strong", { children: t("inbox.slaBanner.breached") }),
|
|
684
|
+
/* @__PURE__ */ jsx("span", { className: s.slaBannerSep, children: "\u2014" }),
|
|
685
|
+
/* @__PURE__ */ jsx("span", { children: t("inbox.slaBanner.responseAwaitedFor", { duration }) }),
|
|
686
|
+
target && /* @__PURE__ */ jsxs("span", { className: s.slaBannerTarget, children: [
|
|
687
|
+
"\xB7 ",
|
|
688
|
+
t("inbox.slaBanner.target", { target })
|
|
689
|
+
] })
|
|
690
|
+
] }),
|
|
691
|
+
/* @__PURE__ */ jsxs(
|
|
692
|
+
"button",
|
|
693
|
+
{
|
|
694
|
+
type: "button",
|
|
695
|
+
className: s.slaBannerCta,
|
|
696
|
+
onClick: () => handleStatusChange("escalated"),
|
|
697
|
+
"aria-label": t("inbox.slaBanner.escalate"),
|
|
698
|
+
children: [
|
|
699
|
+
"\u2191 ",
|
|
700
|
+
t("inbox.slaBanner.escalate")
|
|
701
|
+
]
|
|
702
|
+
}
|
|
703
|
+
)
|
|
704
|
+
] });
|
|
705
|
+
})(),
|
|
665
706
|
otherViewers.length > 0 && /* @__PURE__ */ jsxs("div", { style: {
|
|
666
707
|
display: "flex",
|
|
667
708
|
alignItems: "center",
|
|
@@ -688,8 +729,17 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
688
729
|
const isPendingDelete = undoToast?.msgId === msg.id;
|
|
689
730
|
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
690
731
|
showDate && /* @__PURE__ */ jsx("div", { className: s.dateSeparator, children: /* @__PURE__ */ jsx("span", { className: s.dateSeparatorText, children: dateLabel(msg.createdAt) }) }),
|
|
691
|
-
/* @__PURE__ */ jsxs("div", { className: `${s.message} ${msg.isInternal ? s.messageInternal : ""}`, style: isPendingDelete ? { opacity: 0.3, pointerEvents: "none" } : void 0, children: [
|
|
692
|
-
/* @__PURE__ */ jsx(
|
|
732
|
+
/* @__PURE__ */ jsxs("div", { className: `${s.message} ${isAdmin ? s.messageAdmin : s.messageClient} ${msg.isInternal ? s.messageInternal : ""}`, style: isPendingDelete ? { opacity: 0.3, pointerEvents: "none" } : void 0, children: [
|
|
733
|
+
/* @__PURE__ */ jsx(
|
|
734
|
+
"div",
|
|
735
|
+
{
|
|
736
|
+
className: s.avatar,
|
|
737
|
+
style: {
|
|
738
|
+
backgroundColor: isAdmin ? "var(--theme-info-500, #2a6bd8)" : msg.authorType === "email" ? "var(--theme-warning-500, #c97a0a)" : "var(--theme-accent-500, #6b46e8)"
|
|
739
|
+
},
|
|
740
|
+
children: isAdmin ? "CW" : initials
|
|
741
|
+
}
|
|
742
|
+
),
|
|
693
743
|
/* @__PURE__ */ jsxs("div", { className: s.messageContent, children: [
|
|
694
744
|
/* @__PURE__ */ jsxs("div", { className: s.messageHeader, children: [
|
|
695
745
|
/* @__PURE__ */ jsx("span", { className: s.messageAuthor, children: isAdmin ? "Support" : msg.authorType === "email" ? "Email" : client?.firstName || "Client" }),
|
|
@@ -791,7 +841,17 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
791
841
|
children: [
|
|
792
842
|
/* @__PURE__ */ jsxs("div", { className: s.composerToolbar, children: [
|
|
793
843
|
features.ai && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
794
|
-
/* @__PURE__ */ jsx(
|
|
844
|
+
/* @__PURE__ */ jsx(
|
|
845
|
+
"button",
|
|
846
|
+
{
|
|
847
|
+
className: `${s.toolbarBtn} ${s.toolbarBtnAi}`,
|
|
848
|
+
"data-tooltip": t("detail.iaSuggestion"),
|
|
849
|
+
"aria-label": t("detail.iaSuggestion"),
|
|
850
|
+
onClick: handleAiSuggest,
|
|
851
|
+
disabled: aiReplying || messages.length === 0,
|
|
852
|
+
children: aiReplying ? "\u2026" : `\u2728 ${t("detail.iaSuggestion")}`
|
|
853
|
+
}
|
|
854
|
+
),
|
|
795
855
|
/* @__PURE__ */ jsx(RewriteDropdown, { disabled: aiRewriting || !replyBody.trim(), loading: aiRewriting, onSelect: (style) => handleAiRewrite(style), toolbarBtnClass: s.toolbarBtn })
|
|
796
856
|
] }),
|
|
797
857
|
/* @__PURE__ */ jsx(
|
|
@@ -914,6 +974,10 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
914
974
|
] })
|
|
915
975
|
] })
|
|
916
976
|
] }),
|
|
977
|
+
/* @__PURE__ */ jsxs("span", { className: s.sendShortcut, "aria-hidden": true, children: [
|
|
978
|
+
/* @__PURE__ */ jsx("kbd", { children: "\u2318" }),
|
|
979
|
+
/* @__PURE__ */ jsx("kbd", { children: "\u21B5" })
|
|
980
|
+
] }),
|
|
917
981
|
/* @__PURE__ */ jsx("button", { className: `${s.sendBtn} ${isInternal ? s.sendBtnInternal : ""}`, onClick: handleSend, disabled: sending || !replyBody.trim(), "data-action": "send-reply", children: sending ? t("detail.sending") : sendAsClient ? "Ajouter message client" : isInternal ? t("detail.sendNote") : t("detail.sendReply") })
|
|
918
982
|
] })
|
|
919
983
|
]
|
|
@@ -939,6 +1003,18 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
939
1003
|
/* @__PURE__ */ jsx("button", { className: s.smallBtn, onClick: () => window.open(`/api/admin/impersonate?clientId=${client.id}`, "_blank"), children: t("client.clientPortal") })
|
|
940
1004
|
] })
|
|
941
1005
|
] }),
|
|
1006
|
+
clientSummary && clientSummary.summary && /* @__PURE__ */ jsxs("div", { className: `${s.sideSection} ${s.aiCard}`, children: [
|
|
1007
|
+
/* @__PURE__ */ jsxs("div", { className: s.aiCardTitle, children: [
|
|
1008
|
+
/* @__PURE__ */ jsx("span", { className: s.aiCardIcon, "aria-hidden": true, children: "\u2728" }),
|
|
1009
|
+
"Synth\xE8se client"
|
|
1010
|
+
] }),
|
|
1011
|
+
/* @__PURE__ */ jsx("p", { className: s.aiCardLead, children: clientSummary.summary }),
|
|
1012
|
+
clientSummary.recurringTopics && clientSummary.recurringTopics.length > 0 && /* @__PURE__ */ jsx("div", { className: s.aiCardChips, children: clientSummary.recurringTopics.slice(0, 5).map((tp, i) => /* @__PURE__ */ jsx("span", { className: s.aiChip, children: tp.topic }, `tp-${i}`)) }),
|
|
1013
|
+
clientSummary.keyFacts && clientSummary.keyFacts.length > 0 && /* @__PURE__ */ jsx("ul", { className: s.aiCardFacts, children: clientSummary.keyFacts.slice(0, 4).map((f, i) => /* @__PURE__ */ jsxs("li", { className: s.aiCardFact, children: [
|
|
1014
|
+
/* @__PURE__ */ jsx("span", { className: s.aiCardDot, "aria-hidden": true }),
|
|
1015
|
+
f
|
|
1016
|
+
] }, `kf-${i}`)) })
|
|
1017
|
+
] }),
|
|
942
1018
|
/* @__PURE__ */ jsxs("div", { className: s.sideSection, children: [
|
|
943
1019
|
/* @__PURE__ */ jsx("div", { className: s.sideSectionTitle, children: t("detail.details") }),
|
|
944
1020
|
/* @__PURE__ */ jsxs("div", { className: s.sideField, children: [
|
|
@@ -1196,16 +1272,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1196
1272
|
] })
|
|
1197
1273
|
] }, a.id))
|
|
1198
1274
|
] }),
|
|
1199
|
-
|
|
1200
|
-
/* @__PURE__ */ jsxs("div", { className: s.sideSectionTitle, style: { display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
1201
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: 13 }, children: "\u{1F9E0}" }),
|
|
1202
|
-
" R\xE9sum\xE9 client"
|
|
1203
|
-
] }),
|
|
1204
|
-
/* @__PURE__ */ jsx("p", { style: { margin: "0 0 8px", fontSize: 11, lineHeight: 1.6, color: "#374151" }, children: clientSummary.summary }),
|
|
1205
|
-
clientSummary.recurringTopics && clientSummary.recurringTopics.length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 4, marginBottom: 6 }, children: clientSummary.recurringTopics.slice(0, 3).map((tp, i) => /* @__PURE__ */ jsx("span", { style: { padding: "2px 8px", borderRadius: 10, background: "rgba(37,99,235,0.08)", color: "#2563eb", fontSize: 10, fontWeight: 600 }, children: tp.topic }, i)) }),
|
|
1206
|
-
clientSummary.keyFacts && clientSummary.keyFacts.length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 4 }, children: clientSummary.keyFacts.slice(0, 3).map((f, i) => /* @__PURE__ */ jsx("span", { style: { padding: "2px 8px", borderRadius: 10, background: "rgba(22,163,74,0.08)", color: "#16a34a", fontSize: 10, fontWeight: 600 }, children: f }, i)) })
|
|
1207
|
-
] }),
|
|
1208
|
-
summaryLoading && /* @__PURE__ */ jsx("div", { className: s.sideSection, children: /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: "#94a3b8", textAlign: "center", padding: 8 }, children: "\u{1F9E0} Chargement r\xE9sum\xE9..." }) })
|
|
1275
|
+
summaryLoading && /* @__PURE__ */ jsx("div", { className: s.sideSection, children: /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: "var(--theme-elevation-400)", textAlign: "center", padding: 8 }, children: "\u2728 Chargement de la synth\xE8se\u2026" }) })
|
|
1209
1276
|
] })
|
|
1210
1277
|
] }),
|
|
1211
1278
|
undoToast && /* @__PURE__ */ jsxs("div", { className: s.undoToast, role: "alert", children: [
|
|
@@ -5,6 +5,7 @@ var react = require('react');
|
|
|
5
5
|
var navigation = require('next/navigation');
|
|
6
6
|
var Link = require('next/link');
|
|
7
7
|
var useTranslation = require('../../components/TicketConversation/hooks/useTranslation');
|
|
8
|
+
var shared = require('../shared');
|
|
8
9
|
var s = require('../../styles/TicketInbox.module.scss');
|
|
9
10
|
|
|
10
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -12,28 +13,18 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
12
13
|
var Link__default = /*#__PURE__*/_interopDefault(Link);
|
|
13
14
|
var s__default = /*#__PURE__*/_interopDefault(s);
|
|
14
15
|
|
|
15
|
-
const STATUS_DOTS = {
|
|
16
|
-
open: "#22c55e",
|
|
17
|
-
waiting_client: "#eab308",
|
|
18
|
-
resolved: "#94a3b8"
|
|
19
|
-
};
|
|
20
|
-
const STATUS_LABEL_KEYS = {
|
|
21
|
-
open: "inbox.tabs.open",
|
|
22
|
-
waiting_client: "inbox.tabs.waiting",
|
|
23
|
-
resolved: "inbox.tabs.resolved"
|
|
24
|
-
};
|
|
25
16
|
const PRIORITY_COLORS = {
|
|
26
|
-
urgent: "
|
|
27
|
-
high: "
|
|
28
|
-
normal: "
|
|
29
|
-
low: "
|
|
17
|
+
urgent: "var(--theme-error-500)",
|
|
18
|
+
high: "var(--theme-warning-500)",
|
|
19
|
+
normal: "var(--theme-info-500, #2a6bd8)",
|
|
20
|
+
low: "var(--theme-elevation-400)"
|
|
30
21
|
};
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
22
|
+
const STATUS_VARIANT = {
|
|
23
|
+
open: "open",
|
|
24
|
+
waiting_client: "pending",
|
|
25
|
+
pending: "pending",
|
|
26
|
+
resolved: "resolved",
|
|
27
|
+
closed: "closed"
|
|
37
28
|
};
|
|
38
29
|
function relativeTime(dateStr) {
|
|
39
30
|
const diff = Date.now() - new Date(dateStr).getTime();
|
|
@@ -53,12 +44,12 @@ const TicketInboxClient = () => {
|
|
|
53
44
|
const [loading, setLoading] = react.useState(true);
|
|
54
45
|
const [tab, setTab] = react.useState(() => {
|
|
55
46
|
const urlTab = searchParams.get("tab");
|
|
56
|
-
if (urlTab && ["all", "open", "waiting_client", "resolved"].includes(urlTab)) return urlTab;
|
|
47
|
+
if (urlTab && ["all", "open", "waiting_client", "resolved", "sla_breach"].includes(urlTab)) return urlTab;
|
|
57
48
|
return "all";
|
|
58
49
|
});
|
|
59
50
|
react.useEffect(() => {
|
|
60
51
|
const urlTab = searchParams.get("tab");
|
|
61
|
-
if (urlTab && ["all", "open", "waiting_client", "resolved"].includes(urlTab)) {
|
|
52
|
+
if (urlTab && ["all", "open", "waiting_client", "resolved", "sla_breach"].includes(urlTab)) {
|
|
62
53
|
setTab(urlTab);
|
|
63
54
|
} else if (!urlTab) {
|
|
64
55
|
setTab("all");
|
|
@@ -66,7 +57,7 @@ const TicketInboxClient = () => {
|
|
|
66
57
|
}, [searchParams]);
|
|
67
58
|
const [search, setSearch] = react.useState("");
|
|
68
59
|
const [sort, setSort] = react.useState("-updatedAt");
|
|
69
|
-
const [counts, setCounts] = react.useState({ all: 0, open: 0, waiting: 0, resolved: 0 });
|
|
60
|
+
const [counts, setCounts] = react.useState({ all: 0, open: 0, waiting: 0, resolved: 0, breach: 0 });
|
|
70
61
|
const [selectedIdx, setSelectedIdx] = react.useState(-1);
|
|
71
62
|
const [checkedIds, setCheckedIds] = react.useState(/* @__PURE__ */ new Set());
|
|
72
63
|
const [bulkAction, setBulkAction] = react.useState("");
|
|
@@ -99,8 +90,32 @@ const TicketInboxClient = () => {
|
|
|
99
90
|
setBulkProcessing(false);
|
|
100
91
|
};
|
|
101
92
|
const fetchTickets = react.useCallback(async () => {
|
|
102
|
-
const params = [
|
|
103
|
-
|
|
93
|
+
const params = [
|
|
94
|
+
`limit=30`,
|
|
95
|
+
`sort=${sort}`,
|
|
96
|
+
`depth=1`,
|
|
97
|
+
`select[id]=true`,
|
|
98
|
+
`select[ticketNumber]=true`,
|
|
99
|
+
`select[subject]=true`,
|
|
100
|
+
`select[status]=true`,
|
|
101
|
+
`select[priority]=true`,
|
|
102
|
+
`select[category]=true`,
|
|
103
|
+
`select[client]=true`,
|
|
104
|
+
`select[updatedAt]=true`,
|
|
105
|
+
`select[lastClientMessageAt]=true`,
|
|
106
|
+
`select[lastAdminReadAt]=true`,
|
|
107
|
+
`select[slaFirstResponseDue]=true`,
|
|
108
|
+
`select[slaFirstResponseBreached]=true`,
|
|
109
|
+
`select[slaResolutionDue]=true`,
|
|
110
|
+
`select[slaResolutionBreached]=true`,
|
|
111
|
+
`select[firstResponseAt]=true`
|
|
112
|
+
];
|
|
113
|
+
if (tab === "sla_breach") {
|
|
114
|
+
params.push(`where[or][0][slaFirstResponseBreached][equals]=true`);
|
|
115
|
+
params.push(`where[or][1][slaResolutionBreached][equals]=true`);
|
|
116
|
+
} else if (tab !== "all") {
|
|
117
|
+
params.push(`where[status][equals]=${tab}`);
|
|
118
|
+
}
|
|
104
119
|
if (search.trim()) {
|
|
105
120
|
params.push(`where[or][0][subject][contains]=${encodeURIComponent(search)}`);
|
|
106
121
|
params.push(`where[or][1][ticketNumber][contains]=${encodeURIComponent(search)}`);
|
|
@@ -126,14 +141,21 @@ const TicketInboxClient = () => {
|
|
|
126
141
|
react.useEffect(() => {
|
|
127
142
|
const fetchCounts = async () => {
|
|
128
143
|
try {
|
|
129
|
-
const [all, openRes, waiting, resolved] = await Promise.all([
|
|
144
|
+
const [all, openRes, waiting, resolved, breach] = await Promise.all([
|
|
130
145
|
fetch("/api/tickets?limit=0&depth=0", { credentials: "include" }),
|
|
131
146
|
fetch("/api/tickets?limit=0&depth=0&where[status][equals]=open", { credentials: "include" }),
|
|
132
147
|
fetch("/api/tickets?limit=0&depth=0&where[status][equals]=waiting_client", { credentials: "include" }),
|
|
133
|
-
fetch("/api/tickets?limit=0&depth=0&where[status][equals]=resolved", { credentials: "include" })
|
|
148
|
+
fetch("/api/tickets?limit=0&depth=0&where[status][equals]=resolved", { credentials: "include" }),
|
|
149
|
+
fetch("/api/tickets?limit=0&depth=0&where[or][0][slaFirstResponseBreached][equals]=true&where[or][1][slaResolutionBreached][equals]=true", { credentials: "include" })
|
|
134
150
|
]);
|
|
135
|
-
const [a, o, w, r] = await Promise.all([all.json(), openRes.json(), waiting.json(), resolved.json()]);
|
|
136
|
-
setCounts({
|
|
151
|
+
const [a, o, w, r, b] = await Promise.all([all.json(), openRes.json(), waiting.json(), resolved.json(), breach.json()]);
|
|
152
|
+
setCounts({
|
|
153
|
+
all: a.totalDocs || 0,
|
|
154
|
+
open: o.totalDocs || 0,
|
|
155
|
+
waiting: w.totalDocs || 0,
|
|
156
|
+
resolved: r.totalDocs || 0,
|
|
157
|
+
breach: b.totalDocs || 0
|
|
158
|
+
});
|
|
137
159
|
} catch {
|
|
138
160
|
}
|
|
139
161
|
};
|
|
@@ -165,11 +187,22 @@ const TicketInboxClient = () => {
|
|
|
165
187
|
{ key: "all", label: t("inbox.tabs.all"), count: counts.all },
|
|
166
188
|
{ key: "open", label: t("inbox.tabs.open"), count: counts.open },
|
|
167
189
|
{ key: "waiting_client", label: t("inbox.tabs.waiting"), count: counts.waiting },
|
|
190
|
+
{ key: "sla_breach", label: t("inbox.tabs.slaBreach"), count: counts.breach, alert: true },
|
|
168
191
|
{ key: "resolved", label: t("inbox.tabs.resolved"), count: counts.resolved }
|
|
169
192
|
];
|
|
170
193
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.page, children: [
|
|
171
194
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.header, children: [
|
|
172
|
-
/* @__PURE__ */ jsxRuntime.
|
|
195
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
196
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: s__default.default.title, children: t("inbox.title") }),
|
|
197
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: s__default.default.subtitle, children: [
|
|
198
|
+
tickets.length > 0 && `${tickets.length} sur ${counts.all} \xB7 `,
|
|
199
|
+
counts.breach > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: s__default.default.subtitleBreach, children: [
|
|
200
|
+
counts.breach,
|
|
201
|
+
" SLA d\xE9pass\xE9",
|
|
202
|
+
counts.breach > 1 ? "s" : ""
|
|
203
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Aucun SLA en alerte" })
|
|
204
|
+
] })
|
|
205
|
+
] }),
|
|
173
206
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.headerRight, children: [
|
|
174
207
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: s__default.default.searchWrap, children: [
|
|
175
208
|
/* @__PURE__ */ jsxRuntime.jsxs("svg", { className: s__default.default.searchIcon, width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", children: [
|
|
@@ -191,25 +224,26 @@ const TicketInboxClient = () => {
|
|
|
191
224
|
/* @__PURE__ */ jsxRuntime.jsx(Link__default.default, { href: "/admin/support/new-ticket", className: s__default.default.newTicketBtn, children: t("inbox.newTicketBtn") })
|
|
192
225
|
] })
|
|
193
226
|
] }),
|
|
194
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: s__default.default.tabs, children: tabs.map((tk) =>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
227
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: s__default.default.tabs, role: "tablist", children: tabs.map((tk) => {
|
|
228
|
+
const isAlert = tk.alert && tk.count > 0;
|
|
229
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
230
|
+
"button",
|
|
231
|
+
{
|
|
232
|
+
role: "tab",
|
|
233
|
+
"aria-selected": tab === tk.key,
|
|
234
|
+
className: `${s__default.default.tab} ${tab === tk.key ? s__default.default.tabActive : ""} ${isAlert ? s__default.default.tabAlert : ""}`,
|
|
235
|
+
onClick: () => {
|
|
236
|
+
setTab(tk.key);
|
|
237
|
+
setSelectedIdx(-1);
|
|
238
|
+
},
|
|
239
|
+
children: [
|
|
240
|
+
tk.label,
|
|
241
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${s__default.default.tabCount} ${isAlert ? s__default.default.tabCountAlert : ""}`, children: tk.count })
|
|
242
|
+
]
|
|
201
243
|
},
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
"(",
|
|
206
|
-
tk.count,
|
|
207
|
-
")"
|
|
208
|
-
] })
|
|
209
|
-
]
|
|
210
|
-
},
|
|
211
|
-
tk.key
|
|
212
|
-
)) }),
|
|
244
|
+
tk.key
|
|
245
|
+
);
|
|
246
|
+
}) }),
|
|
213
247
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: s__default.default.sortRow, children: checkedIds.size > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 8, alignItems: "center", flex: 1 }, children: [
|
|
214
248
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "var(--theme-text)" }, children: checkedIds.size > 1 ? t("inbox.selectedPlural", { count: String(checkedIds.size) }) : t("inbox.selected", { count: String(checkedIds.size) }) }),
|
|
215
249
|
/* @__PURE__ */ jsxRuntime.jsx("button", { className: s__default.default.sortSelect, onClick: () => handleBulkAction("close"), disabled: bulkProcessing, children: t("inbox.closeAction") }),
|
|
@@ -239,11 +273,19 @@ const TicketInboxClient = () => {
|
|
|
239
273
|
const displayClient = clientName ? `${clientName}${clientCompany ? `, ${clientCompany}` : ""}` : "\u2014";
|
|
240
274
|
const isUnread = tk.lastClientMessageAt && (!tk.lastAdminReadAt || new Date(tk.lastClientMessageAt) > new Date(tk.lastAdminReadAt));
|
|
241
275
|
const priorityColor = PRIORITY_COLORS[tk.priority] || "transparent";
|
|
276
|
+
const sla = shared.computeSlaState(tk);
|
|
277
|
+
const isBreach = sla.state === "breach";
|
|
278
|
+
const statusVariant = STATUS_VARIANT[tk.status] || "open";
|
|
242
279
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
243
280
|
"a",
|
|
244
281
|
{
|
|
245
282
|
href: `/admin/support/ticket?id=${tk.id}`,
|
|
246
|
-
className:
|
|
283
|
+
className: [
|
|
284
|
+
s__default.default.row,
|
|
285
|
+
idx === selectedIdx ? s__default.default.rowSelected : "",
|
|
286
|
+
isUnread ? s__default.default.rowUnread : "",
|
|
287
|
+
isBreach ? s__default.default.rowBreach : ""
|
|
288
|
+
].filter(Boolean).join(" "),
|
|
247
289
|
onClick: (e) => {
|
|
248
290
|
e.preventDefault();
|
|
249
291
|
window.location.href = `/admin/support/ticket?id=${tk.id}`;
|
|
@@ -256,20 +298,36 @@ const TicketInboxClient = () => {
|
|
|
256
298
|
checked: checkedIds.has(tk.id),
|
|
257
299
|
onClick: (e) => e.stopPropagation(),
|
|
258
300
|
onChange: () => toggleCheck(tk.id),
|
|
259
|
-
|
|
301
|
+
className: s__default.default.rowCheck,
|
|
302
|
+
"aria-label": `S\xE9lectionner ${tk.ticketNumber}`
|
|
303
|
+
}
|
|
304
|
+
),
|
|
305
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
306
|
+
"span",
|
|
307
|
+
{
|
|
308
|
+
className: s__default.default.priorityDot,
|
|
309
|
+
style: { background: priorityColor },
|
|
310
|
+
"aria-label": `Priorit\xE9 ${tk.priority}`,
|
|
311
|
+
title: `Priorit\xE9 ${tk.priority}`
|
|
260
312
|
}
|
|
261
313
|
),
|
|
262
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
263
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.statusText, children: t(STATUS_LABEL_KEYS[tk.status] || "ticket.status.open") }),
|
|
314
|
+
/* @__PURE__ */ jsxRuntime.jsx(shared.StatusPill, { status: isBreach ? "sla-breach" : statusVariant }),
|
|
264
315
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.ticketNum, children: tk.ticketNumber }),
|
|
265
316
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.subject, children: tk.subject }),
|
|
266
317
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.client, children: displayClient }),
|
|
267
|
-
|
|
268
|
-
"
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
318
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
319
|
+
"span",
|
|
320
|
+
{
|
|
321
|
+
className: [
|
|
322
|
+
s__default.default.slaCell,
|
|
323
|
+
sla.state === "breach" ? s__default.default.slaBreach : "",
|
|
324
|
+
sla.state === "warn" ? s__default.default.slaWarn : "",
|
|
325
|
+
sla.state === "ok" ? s__default.default.slaOk : ""
|
|
326
|
+
].filter(Boolean).join(" "),
|
|
327
|
+
title: sla.due ? new Date(sla.due).toLocaleString("fr-FR") : "",
|
|
328
|
+
children: shared.formatSlaRemaining(sla.remainingMs)
|
|
329
|
+
}
|
|
330
|
+
),
|
|
273
331
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.timeAgo, children: relativeTime(tk.updatedAt) }),
|
|
274
332
|
isUnread ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: s__default.default.unreadDot }) : /* @__PURE__ */ jsxRuntime.jsx("span", {})
|
|
275
333
|
]
|