@consilioweb/payload-support 5.0.0 → 6.0.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/README.md +249 -22
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/components/TicketConversation/RewriteDropdown.js +1 -1
- package/dist/components/TicketConversation/components/AISummaryPanel.js +3 -0
- package/dist/components/TicketConversation/components/ActionPanels.js +13 -8
- package/dist/components/TicketConversation/components/ClientHistory.js +1 -0
- package/dist/components/TicketConversation/components/CodeBlock.js +1 -0
- package/dist/components/TicketConversation/components/CodeBlockInserter.js +1 -1
- package/dist/components/TicketConversation/components/QuickActions.js +10 -8
- package/dist/components/TicketConversation/components/TicketHeader.js +2 -0
- package/dist/components/TicketConversation/components/TimeTrackingPanel.js +15 -9
- package/dist/components/TicketConversation/index.d.ts +10 -0
- package/dist/components/TicketConversation/index.js +25 -7
- package/dist/index.cjs +306 -60
- package/dist/index.d.cts +107 -38
- package/dist/index.d.ts +107 -38
- package/dist/index.js +300 -59
- package/dist/styles/BillingView.module.scss +11 -11
- package/dist/styles/ChatView.module.scss +7 -7
- package/dist/styles/CommandPalette.module.scss +1 -1
- package/dist/styles/CrmView.module.scss +9 -9
- package/dist/styles/EmailTracking.module.scss +6 -6
- package/dist/styles/ImportConversation.module.scss +5 -5
- package/dist/styles/Logs.module.scss +5 -5
- package/dist/styles/NewTicket.module.scss +2 -2
- package/dist/styles/PendingEmails.module.scss +13 -13
- package/dist/styles/SupportDashboard.module.scss +24 -8
- package/dist/styles/TicketDetail.module.scss +20 -20
- package/dist/styles/TicketInbox.module.scss +6 -6
- package/dist/styles/TicketingSettings.module.scss +10 -10
- package/dist/styles/TimeDashboard.module.scss +6 -6
- package/dist/styles/_tokens.scss +3 -1
- package/dist/views/BillingView/client.js +15 -8
- package/dist/views/ChatView/client.js +2 -0
- package/dist/views/CrmView/client.js +2 -0
- package/dist/views/EmailTrackingView/client.js +23 -11
- package/dist/views/ImportConversationView/client.js +1 -0
- package/dist/views/LogsView/client.js +1 -1
- package/dist/views/NewTicketView/client.js +20 -13
- package/dist/views/PendingEmailsView/client.js +9 -3
- package/dist/views/SupportDashboardView/client.js +17 -19
- package/dist/views/TicketDetailView/client.js +23 -11
- package/dist/views/TicketInboxView/client.js +52 -26
- package/dist/views/TicketingSettingsView/TicketingSettings.module.scss +7 -7
- package/dist/views/TicketingSettingsView/client.js +44 -26
- package/dist/views/TimeDashboardView/client.js +10 -7
- package/dist/views/shared/ErrorBoundary.d.ts +36 -1
- package/dist/views/shared/ErrorBoundary.js +59 -28
- package/dist/views/shared/adminTokens.d.ts +15 -5
- package/dist/views/shared/adminTokens.js +23 -7
- package/dist/views/shared/icons.d.ts +49 -0
- package/dist/views/shared/icons.js +92 -0
- package/dist/views/shared/locales/en.json +15 -1
- package/dist/views/shared/locales/fr.json +15 -1
- package/package.json +6 -2
- package/scripts/uninstall-data.mjs +178 -0
- package/scripts/uninstall.mjs +184 -0
- package/src/collections/Tickets.ts +7 -0
- package/src/collections/TimeEntries.ts +11 -3
- package/src/components/RichTextEditor/index.tsx +1 -1
- package/src/components/TicketConversation/RewriteDropdown.tsx +1 -1
- package/src/components/TicketConversation/components/AISummaryPanel.tsx +3 -0
- package/src/components/TicketConversation/components/ActionPanels.tsx +13 -8
- package/src/components/TicketConversation/components/ClientHistory.tsx +1 -0
- package/src/components/TicketConversation/components/CodeBlock.tsx +1 -0
- package/src/components/TicketConversation/components/CodeBlockInserter.tsx +1 -1
- package/src/components/TicketConversation/components/QuickActions.tsx +10 -8
- package/src/components/TicketConversation/components/TicketHeader.tsx +2 -0
- package/src/components/TicketConversation/components/TimeTrackingPanel.tsx +17 -9
- package/src/components/TicketConversation/index.tsx +41 -7
- package/src/endpoints/delete-account.ts +191 -47
- package/src/endpoints/export-data.ts +104 -4
- package/src/endpoints/purge-logs.ts +6 -15
- package/src/index.ts +2 -0
- package/src/plugin.ts +51 -1
- package/src/portal/LiveChat.tsx +1 -1
- package/src/portal/auth/profile/page.tsx +3 -2
- package/src/portal/icons.tsx +91 -0
- package/src/styles/BillingView.module.scss +11 -11
- package/src/styles/ChatView.module.scss +7 -7
- package/src/styles/CommandPalette.module.scss +1 -1
- package/src/styles/CrmView.module.scss +9 -9
- package/src/styles/EmailTracking.module.scss +6 -6
- package/src/styles/ImportConversation.module.scss +5 -5
- package/src/styles/Logs.module.scss +5 -5
- package/src/styles/NewTicket.module.scss +2 -2
- package/src/styles/PendingEmails.module.scss +13 -13
- package/src/styles/SupportDashboard.module.scss +24 -8
- package/src/styles/TicketDetail.module.scss +20 -20
- package/src/styles/TicketInbox.module.scss +6 -6
- package/src/styles/TicketingSettings.module.scss +10 -10
- package/src/styles/TimeDashboard.module.scss +6 -6
- package/src/styles/_tokens.scss +3 -1
- package/src/types.ts +20 -0
- package/src/utils/retention.ts +111 -0
- package/src/utils/slugs.ts +15 -0
- package/src/views/BillingView/client.tsx +17 -8
- package/src/views/ChatView/client.tsx +2 -0
- package/src/views/CrmView/client.tsx +2 -0
- package/src/views/EmailTrackingView/client.tsx +18 -7
- package/src/views/ImportConversationView/client.tsx +1 -0
- package/src/views/LogsView/client.tsx +1 -1
- package/src/views/NewTicketView/client.tsx +22 -13
- package/src/views/PendingEmailsView/client.tsx +9 -3
- package/src/views/SupportDashboardView/client.tsx +11 -5
- package/src/views/TicketDetailView/client.tsx +25 -11
- package/src/views/TicketInboxView/client.tsx +47 -7
- package/src/views/TicketingSettingsView/TicketingSettings.module.scss +7 -7
- package/src/views/TicketingSettingsView/client.tsx +201 -144
- package/src/views/TimeDashboardView/client.tsx +10 -7
- package/src/views/shared/ErrorBoundary.tsx +95 -31
- package/src/views/shared/adminTokens.ts +28 -11
- package/src/views/shared/icons.tsx +146 -0
- package/src/views/shared/locales/en.json +15 -1
- package/src/views/shared/locales/fr.json +15 -1
- package/src/types/lucide-react.d.ts +0 -42
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import React from 'react';
|
|
3
4
|
import { s, C } from '../constants.js';
|
|
4
5
|
|
|
5
6
|
function TimeTrackingPanel({
|
|
@@ -22,6 +23,8 @@ function TimeTrackingPanel({
|
|
|
22
23
|
addingTime,
|
|
23
24
|
timeSuccess
|
|
24
25
|
}) {
|
|
26
|
+
const minutesId = React.useId();
|
|
27
|
+
const workDescriptionId = React.useId();
|
|
25
28
|
const totalH = Math.floor(totalMinutes / 60);
|
|
26
29
|
const totalM = totalMinutes % 60;
|
|
27
30
|
return /* @__PURE__ */ jsxs("div", { style: s.section, children: [
|
|
@@ -61,6 +64,7 @@ function TimeTrackingPanel({
|
|
|
61
64
|
!timerRunning && timerSeconds > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [-5, -1, 1, 5, 15, 30].map((m) => /* @__PURE__ */ jsx(
|
|
62
65
|
"button",
|
|
63
66
|
{
|
|
67
|
+
type: "button",
|
|
64
68
|
onClick: () => setTimerSeconds((p) => Math.max(0, p + m * 60)),
|
|
65
69
|
style: { width: Math.abs(m) >= 15 ? "32px" : "28px", height: "28px", borderRadius: "6px", border: "1px solid #e2e8f0", background: "white", cursor: "pointer", fontSize: Math.abs(m) >= 15 ? "12px" : "14px", fontWeight: 700, color: "#64748b" },
|
|
66
70
|
title: `${m > 0 ? "+" : ""}${m} min`,
|
|
@@ -68,14 +72,15 @@ function TimeTrackingPanel({
|
|
|
68
72
|
},
|
|
69
73
|
m
|
|
70
74
|
)) }),
|
|
71
|
-
!timerRunning && timerSeconds === 0 && /* @__PURE__ */ jsx("button", { onClick: () => handleTimerStart(true), style: { ...s.btn("#dc2626", false), fontSize: "12px", padding: "6px 16px", display: "flex", alignItems: "center", gap: "6px" }, children: "\u25B6 D\xE9marrer" }),
|
|
72
|
-
timerRunning && /* @__PURE__ */ jsx("button", { onClick: handleTimerStop, style: { ...s.btn("#374151", false), fontSize: "12px", padding: "6px 16px", display: "flex", alignItems: "center", gap: "6px" }, children: "\u23F8 Pause" }),
|
|
75
|
+
!timerRunning && timerSeconds === 0 && /* @__PURE__ */ jsx("button", { type: "button", onClick: () => handleTimerStart(true), style: { ...s.btn("#dc2626", false), fontSize: "12px", padding: "6px 16px", display: "flex", alignItems: "center", gap: "6px" }, children: "\u25B6 D\xE9marrer" }),
|
|
76
|
+
timerRunning && /* @__PURE__ */ jsx("button", { type: "button", onClick: handleTimerStop, style: { ...s.btn("#374151", false), fontSize: "12px", padding: "6px 16px", display: "flex", alignItems: "center", gap: "6px" }, children: "\u23F8 Pause" }),
|
|
73
77
|
!timerRunning && timerSeconds > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
74
|
-
/* @__PURE__ */ jsx("button", { onClick: () => handleTimerStart(false), style: { ...s.btn("#dc2626", false), fontSize: "12px", padding: "6px 14px" }, children: "\u25B6 Reprendre" }),
|
|
78
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => handleTimerStart(false), style: { ...s.btn("#dc2626", false), fontSize: "12px", padding: "6px 14px" }, children: "\u25B6 Reprendre" }),
|
|
75
79
|
/* @__PURE__ */ jsx(
|
|
76
80
|
"input",
|
|
77
81
|
{
|
|
78
82
|
type: "text",
|
|
83
|
+
"aria-label": "Description du temps en cours",
|
|
79
84
|
value: timerDescription,
|
|
80
85
|
onChange: (e) => setTimerDescription(e.target.value),
|
|
81
86
|
placeholder: "Description...",
|
|
@@ -85,6 +90,7 @@ function TimeTrackingPanel({
|
|
|
85
90
|
/* @__PURE__ */ jsxs(
|
|
86
91
|
"button",
|
|
87
92
|
{
|
|
93
|
+
type: "button",
|
|
88
94
|
onClick: handleTimerSave,
|
|
89
95
|
disabled: addingTime || timerSeconds < 60,
|
|
90
96
|
style: { ...s.btn("#16a34a", addingTime || timerSeconds < 60), fontSize: "12px", padding: "6px 14px" },
|
|
@@ -96,20 +102,20 @@ function TimeTrackingPanel({
|
|
|
96
102
|
]
|
|
97
103
|
}
|
|
98
104
|
),
|
|
99
|
-
/* @__PURE__ */ jsx("button", { onClick: handleTimerDiscard, style: { background: "none", border: "none", cursor: "pointer", fontSize: "14px", color: "#94a3b8", padding: "4px" }, title: "Annuler", children: "\u2715" })
|
|
105
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: handleTimerDiscard, style: { background: "none", border: "none", cursor: "pointer", fontSize: "14px", color: "#94a3b8", padding: "4px" }, title: "Annuler", children: "\u2715" })
|
|
100
106
|
] }),
|
|
101
107
|
timerRunning && /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: "#dc2626", fontWeight: 600 }, children: "\u25CF Enregistrement en cours \u2014 session maintenue active" })
|
|
102
108
|
] }),
|
|
103
109
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end", flexWrap: "wrap", marginBottom: "14px" }, children: [
|
|
104
110
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
105
|
-
/* @__PURE__ */ jsx("label", { style: { display: "block", fontSize: "11px", color: C.textSecondary, marginBottom: "3px", fontWeight: 600 }, children: "Min" }),
|
|
106
|
-
/* @__PURE__ */ jsx("input", { type: "number", min: "1", value: duration, onChange: (e) => setDuration(e.target.value), placeholder: "30", style: { ...s.input, width: "80px" } })
|
|
111
|
+
/* @__PURE__ */ jsx("label", { htmlFor: minutesId, style: { display: "block", fontSize: "11px", color: C.textSecondary, marginBottom: "3px", fontWeight: 600 }, children: "Min" }),
|
|
112
|
+
/* @__PURE__ */ jsx("input", { id: minutesId, type: "number", min: "1", value: duration, onChange: (e) => setDuration(e.target.value), placeholder: "30", style: { ...s.input, width: "80px" } })
|
|
107
113
|
] }),
|
|
108
114
|
/* @__PURE__ */ jsxs("div", { style: { flex: 1 }, children: [
|
|
109
|
-
/* @__PURE__ */ jsx("label", { style: { display: "block", fontSize: "11px", color: C.textSecondary, marginBottom: "3px", fontWeight: 600 }, children: "Description" }),
|
|
110
|
-
/* @__PURE__ */ jsx("input", { type: "text", value: timeDescription, onChange: (e) => setTimeDescription(e.target.value), placeholder: "Travail effectu\xE9...", style: { ...s.input, width: "100%" } })
|
|
115
|
+
/* @__PURE__ */ jsx("label", { htmlFor: workDescriptionId, style: { display: "block", fontSize: "11px", color: C.textSecondary, marginBottom: "3px", fontWeight: 600 }, children: "Description" }),
|
|
116
|
+
/* @__PURE__ */ jsx("input", { id: workDescriptionId, type: "text", value: timeDescription, onChange: (e) => setTimeDescription(e.target.value), placeholder: "Travail effectu\xE9...", style: { ...s.input, width: "100%" } })
|
|
111
117
|
] }),
|
|
112
|
-
/* @__PURE__ */ jsx("button", { onClick: handleAddTime, disabled: addingTime || !duration, style: s.btn(C.amber, addingTime || !duration), children: addingTime ? "..." : "+ Temps" }),
|
|
118
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: handleAddTime, disabled: addingTime || !duration, style: s.btn(C.amber, addingTime || !duration), children: addingTime ? "..." : "+ Temps" }),
|
|
113
119
|
timeSuccess && /* @__PURE__ */ jsx("span", { style: { fontSize: "12px", color: "#16a34a", fontWeight: 600 }, children: timeSuccess })
|
|
114
120
|
] }),
|
|
115
121
|
timeEntries.length > 0 && /* @__PURE__ */ jsx("div", { style: { fontSize: "12px" }, children: /* @__PURE__ */ jsxs("table", { style: { width: "100%", borderCollapse: "collapse" }, children: [
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import '../../styles/theme.css';
|
|
3
|
+
/**
|
|
4
|
+
* Payload mounts this component straight from the import map as the `ui` field
|
|
5
|
+
* of the Tickets edit view, so the plugin never gets to render an ancestor for
|
|
6
|
+
* it: the boundary has to live inside the module itself. Without it a single
|
|
7
|
+
* render error in any of the twelve sub-components blanks the whole ticket
|
|
8
|
+
* screen.
|
|
9
|
+
*
|
|
10
|
+
* The document id is used as a reset key so that navigating from a ticket that
|
|
11
|
+
* broke to another one clears the error on its own.
|
|
12
|
+
*/
|
|
3
13
|
declare const TicketConversation: React.FC;
|
|
4
14
|
export default TicketConversation;
|
|
@@ -22,9 +22,10 @@ import { useDocumentIdFromUrl } from './hooks/useDocumentIdFromUrl.js';
|
|
|
22
22
|
import { useFeatures } from './hooks/useFeatures.js';
|
|
23
23
|
import { SkeletonText } from './SkeletonText.js';
|
|
24
24
|
import { RewriteDropdown } from './RewriteDropdown.js';
|
|
25
|
+
import { AdminErrorBoundary } from '../../views/shared/ErrorBoundary.js';
|
|
25
26
|
import '../../styles/theme.css';
|
|
26
27
|
|
|
27
|
-
const
|
|
28
|
+
const TicketConversationInner = () => {
|
|
28
29
|
const { id } = useDocumentIdFromUrl();
|
|
29
30
|
const { features } = useFeatures();
|
|
30
31
|
const [messages, setMessages] = useState([]);
|
|
@@ -368,6 +369,7 @@ const TicketConversation = () => {
|
|
|
368
369
|
"input",
|
|
369
370
|
{
|
|
370
371
|
type: "text",
|
|
372
|
+
"aria-label": "Rechercher dans la conversation",
|
|
371
373
|
value: searchQuery,
|
|
372
374
|
onChange: (e) => setSearchQuery(e.target.value),
|
|
373
375
|
placeholder: "Rechercher...",
|
|
@@ -386,6 +388,7 @@ const TicketConversation = () => {
|
|
|
386
388
|
showCollapse && hiddenCount > 0 && /* @__PURE__ */ jsxs(
|
|
387
389
|
"button",
|
|
388
390
|
{
|
|
391
|
+
type: "button",
|
|
389
392
|
onClick: () => setMessagesCollapsed(false),
|
|
390
393
|
style: {
|
|
391
394
|
background: "none",
|
|
@@ -411,6 +414,7 @@ const TicketConversation = () => {
|
|
|
411
414
|
!messagesCollapsed && filtered.length > 1 && !isSearching && /* @__PURE__ */ jsx(
|
|
412
415
|
"button",
|
|
413
416
|
{
|
|
417
|
+
type: "button",
|
|
414
418
|
onClick: () => setMessagesCollapsed(true),
|
|
415
419
|
style: {
|
|
416
420
|
background: "none",
|
|
@@ -468,6 +472,7 @@ const TicketConversation = () => {
|
|
|
468
472
|
msg.authorType === "email" ? /* @__PURE__ */ jsx("span", { style: s.badge(C.emailBg, C.orange), children: "Email" }) : /* @__PURE__ */ jsxs(
|
|
469
473
|
"select",
|
|
470
474
|
{
|
|
475
|
+
"aria-label": "Auteur du message",
|
|
471
476
|
value: msg.authorType,
|
|
472
477
|
onChange: (e) => handleToggleAuthor(msg.id, e.target.value === "admin" ? "client" : "admin"),
|
|
473
478
|
disabled: togglingAuthor === msg.id,
|
|
@@ -515,6 +520,7 @@ const TicketConversation = () => {
|
|
|
515
520
|
!msg.isInternal && !msg.deletedAt && /* @__PURE__ */ jsxs(
|
|
516
521
|
"button",
|
|
517
522
|
{
|
|
523
|
+
type: "button",
|
|
518
524
|
onClick: () => handleSplitMessage(msg.id, ticketSubject),
|
|
519
525
|
style: { background: "none", border: "none", cursor: "pointer", fontSize: "10px", color: "#6b7280", padding: 0 },
|
|
520
526
|
title: "Extraire en nouveau ticket",
|
|
@@ -554,6 +560,7 @@ const TicketConversation = () => {
|
|
|
554
560
|
/* @__PURE__ */ jsx(
|
|
555
561
|
"textarea",
|
|
556
562
|
{
|
|
563
|
+
"aria-label": "Editer le message",
|
|
557
564
|
value: editBody,
|
|
558
565
|
onChange: (e) => {
|
|
559
566
|
setEditBody(e.target.value);
|
|
@@ -564,8 +571,8 @@ const TicketConversation = () => {
|
|
|
564
571
|
}
|
|
565
572
|
),
|
|
566
573
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", marginTop: "8px" }, children: [
|
|
567
|
-
/* @__PURE__ */ jsx("button", { onClick: () => handleEditSave(msg.id), disabled: savingEdit || !editBody.trim() && !editHtml, style: { ...s.btn(C.blue, savingEdit), fontSize: "11px", padding: "5px 12px" }, children: savingEdit ? "..." : "Enregistrer" }),
|
|
568
|
-
/* @__PURE__ */ jsx("button", { onClick: handleEditCancel, style: { ...s.ghostBtn("#6b7280"), fontSize: "11px", padding: "5px 12px" }, children: "Annuler" })
|
|
574
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => handleEditSave(msg.id), disabled: savingEdit || !editBody.trim() && !editHtml, style: { ...s.btn(C.blue, savingEdit), fontSize: "11px", padding: "5px 12px" }, children: savingEdit ? "..." : "Enregistrer" }),
|
|
575
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: handleEditCancel, style: { ...s.ghostBtn("#6b7280"), fontSize: "11px", padding: "5px 12px" }, children: "Annuler" })
|
|
569
576
|
] })
|
|
570
577
|
] }) : msg.deletedAt ? /* @__PURE__ */ jsx("div", { style: { fontSize: "13px", color: "#94a3b8", fontStyle: "italic" }, children: "Ce message a \xE9t\xE9 supprim\xE9." }) : msg.bodyHtml ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
571
578
|
/* @__PURE__ */ jsx(
|
|
@@ -753,6 +760,7 @@ const TicketConversation = () => {
|
|
|
753
760
|
features.ai && /* @__PURE__ */ jsx(
|
|
754
761
|
"button",
|
|
755
762
|
{
|
|
763
|
+
type: "button",
|
|
756
764
|
onClick: handleAiSuggestReply,
|
|
757
765
|
disabled: aiReplying || messages.length === 0,
|
|
758
766
|
style: { ...s.outlineBtn("#17807c", aiReplying || messages.length === 0), fontSize: "11px", padding: "3px 10px", borderRadius: "14px" },
|
|
@@ -780,7 +788,7 @@ const TicketConversation = () => {
|
|
|
780
788
|
}
|
|
781
789
|
),
|
|
782
790
|
features.canned && cannedResponses.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
783
|
-
/* @__PURE__ */ jsxs("select", { onChange: handleCannedSelect, style: { ...s.input, fontSize: "11px", padding: "3px 8px", fontWeight: 600 }, children: [
|
|
791
|
+
/* @__PURE__ */ jsxs("select", { "aria-label": "Reponse rapide", onChange: handleCannedSelect, style: { ...s.input, fontSize: "11px", padding: "3px 8px", fontWeight: 600 }, children: [
|
|
784
792
|
/* @__PURE__ */ jsx("option", { value: "", children: "R\xE9ponse rapide..." }),
|
|
785
793
|
cannedResponses.map((cr) => /* @__PURE__ */ jsx("option", { value: String(cr.id), children: cr.title }, cr.id))
|
|
786
794
|
] }),
|
|
@@ -797,6 +805,7 @@ const TicketConversation = () => {
|
|
|
797
805
|
/* @__PURE__ */ jsx("div", { style: { border: `1px solid ${C.border}`, borderRadius: "8px", overflow: "hidden" }, children: /* @__PURE__ */ jsx(
|
|
798
806
|
"textarea",
|
|
799
807
|
{
|
|
808
|
+
"aria-label": "Reponse au client",
|
|
800
809
|
value: replyBody,
|
|
801
810
|
onChange: (e) => {
|
|
802
811
|
const text = e.target.value;
|
|
@@ -810,7 +819,6 @@ const TicketConversation = () => {
|
|
|
810
819
|
minHeight: "120px",
|
|
811
820
|
padding: "12px",
|
|
812
821
|
border: "none",
|
|
813
|
-
outline: "none",
|
|
814
822
|
fontSize: "14px",
|
|
815
823
|
lineHeight: 1.5,
|
|
816
824
|
resize: "vertical",
|
|
@@ -828,6 +836,7 @@ const TicketConversation = () => {
|
|
|
828
836
|
ref: fileInputRef,
|
|
829
837
|
type: "file",
|
|
830
838
|
multiple: true,
|
|
839
|
+
"aria-label": "Joindre des fichiers",
|
|
831
840
|
onChange: handleReplyFileChange,
|
|
832
841
|
style: { display: "none" },
|
|
833
842
|
accept: "image/*,.pdf,.doc,.docx,.txt,.zip"
|
|
@@ -850,6 +859,7 @@ const TicketConversation = () => {
|
|
|
850
859
|
"button",
|
|
851
860
|
{
|
|
852
861
|
type: "button",
|
|
862
|
+
"aria-label": `Retirer la piece jointe ${file.name}`,
|
|
853
863
|
onClick: () => setReplyFiles((prev) => prev.filter((_, idx) => idx !== i)),
|
|
854
864
|
style: { border: "none", background: "none", color: "#ef4444", fontWeight: 700, cursor: "pointer", fontSize: "14px", lineHeight: 1 },
|
|
855
865
|
children: "\xD7"
|
|
@@ -861,6 +871,7 @@ const TicketConversation = () => {
|
|
|
861
871
|
/* @__PURE__ */ jsxs(
|
|
862
872
|
"select",
|
|
863
873
|
{
|
|
874
|
+
"aria-label": "Envoyer en tant que",
|
|
864
875
|
value: sendAsClient ? "client" : "admin",
|
|
865
876
|
onChange: (e) => setSendAsClient(e.target.value === "client"),
|
|
866
877
|
style: { ...s.input, fontSize: "12px", padding: "6px 8px", fontWeight: 600 },
|
|
@@ -881,10 +892,11 @@ const TicketConversation = () => {
|
|
|
881
892
|
/* @__PURE__ */ jsx("input", { type: "checkbox", checked: notifyClient, onChange: (e) => setNotifyClient(e.target.checked), style: { width: "14px", height: "14px", accentColor: "#16a34a" } }),
|
|
882
893
|
"Envoyer au client"
|
|
883
894
|
] }),
|
|
884
|
-
/* @__PURE__ */ jsx("button", { "data-action": "send-reply", onClick: handleSendReply, disabled: sending || !replyBody.trim() && !replyHtml, style: { ...s.btn(isInternal ? C.amber : notifyClient ? "#16a34a" : C.blue, sending || !replyBody.trim() && !replyHtml), fontSize: "13px", padding: "8px 20px", marginLeft: "auto" }, children: sending ? "Envoi..." : isInternal ? "Ajouter note" : notifyClient ? "Envoyer + Notifier" : "Sauvegarder" }),
|
|
895
|
+
/* @__PURE__ */ jsx("button", { type: "button", "data-action": "send-reply", onClick: handleSendReply, disabled: sending || !replyBody.trim() && !replyHtml, style: { ...s.btn(isInternal ? C.amber : notifyClient ? "#16a34a" : C.blue, sending || !replyBody.trim() && !replyHtml), fontSize: "13px", padding: "8px 20px", marginLeft: "auto" }, children: sending ? "Envoi..." : isInternal ? "Ajouter note" : notifyClient ? "Envoyer + Notifier" : "Sauvegarder" }),
|
|
885
896
|
!isInternal && /* @__PURE__ */ jsx(
|
|
886
897
|
"button",
|
|
887
898
|
{
|
|
899
|
+
type: "button",
|
|
888
900
|
onClick: () => setShowSchedule(!showSchedule),
|
|
889
901
|
disabled: !replyBody.trim() && !replyHtml,
|
|
890
902
|
style: { ...s.outlineBtn("#17807c", !replyBody.trim() && !replyHtml), fontSize: "12px", padding: "8px 12px" },
|
|
@@ -899,6 +911,7 @@ const TicketConversation = () => {
|
|
|
899
911
|
"input",
|
|
900
912
|
{
|
|
901
913
|
type: "datetime-local",
|
|
914
|
+
"aria-label": "Date et heure d'envoi programme",
|
|
902
915
|
value: scheduleDate,
|
|
903
916
|
onChange: (e) => setScheduleDate(e.target.value),
|
|
904
917
|
min: (/* @__PURE__ */ new Date()).toISOString().slice(0, 16),
|
|
@@ -908,13 +921,14 @@ const TicketConversation = () => {
|
|
|
908
921
|
/* @__PURE__ */ jsx(
|
|
909
922
|
"button",
|
|
910
923
|
{
|
|
924
|
+
type: "button",
|
|
911
925
|
onClick: handleScheduleReply,
|
|
912
926
|
disabled: sending || !scheduleDate || !replyBody.trim() && !replyHtml,
|
|
913
927
|
style: { ...s.btn("#17807c", sending || !scheduleDate || !replyBody.trim() && !replyHtml), fontSize: "12px", padding: "6px 14px" },
|
|
914
928
|
children: sending ? "..." : "\u23F0 Programmer"
|
|
915
929
|
}
|
|
916
930
|
),
|
|
917
|
-
/* @__PURE__ */ jsx("button", { onClick: () => setShowSchedule(false), style: { background: "none", border: "none", cursor: "pointer", color: "#94a3b8", fontSize: "14px" }, children: "\u2715" })
|
|
931
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Annuler la programmation", onClick: () => setShowSchedule(false), style: { background: "none", border: "none", cursor: "pointer", color: "#94a3b8", fontSize: "14px" }, children: "\u2715" })
|
|
918
932
|
] }),
|
|
919
933
|
/* @__PURE__ */ jsxs("div", { style: { fontSize: "11px", color: C.textMuted, marginTop: "4px", textAlign: "right" }, children: [
|
|
920
934
|
"\u2318",
|
|
@@ -1104,6 +1118,10 @@ const TicketConversation = () => {
|
|
|
1104
1118
|
] })
|
|
1105
1119
|
] });
|
|
1106
1120
|
};
|
|
1121
|
+
const TicketConversation = () => {
|
|
1122
|
+
const { id } = useDocumentIdFromUrl();
|
|
1123
|
+
return /* @__PURE__ */ jsx(AdminErrorBoundary, { viewName: "TicketConversation", resetKeys: [id], children: /* @__PURE__ */ jsx(TicketConversationInner, {}) });
|
|
1124
|
+
};
|
|
1107
1125
|
var TicketConversation_default = TicketConversation;
|
|
1108
1126
|
|
|
1109
1127
|
export { TicketConversation_default as default };
|