@consilioweb/payload-support 2.0.1 → 3.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.
Files changed (215) hide show
  1. package/README.md +636 -402
  2. package/dist/components/RichTextEditor/index.d.ts +19 -0
  3. package/dist/components/TicketConversation/RewriteDropdown.d.ts +6 -0
  4. package/dist/components/TicketConversation/SkeletonText.d.ts +4 -0
  5. package/dist/components/TicketConversation/components/AISummaryPanel.d.ts +14 -0
  6. package/dist/components/TicketConversation/components/ActionPanels.d.ts +47 -0
  7. package/dist/components/TicketConversation/components/ActivityLog.d.ts +5 -0
  8. package/dist/components/TicketConversation/components/ClientBar.d.ts +5 -0
  9. package/dist/components/TicketConversation/components/ClientHistory.d.ts +24 -0
  10. package/dist/components/TicketConversation/components/CodeBlock.d.ts +26 -0
  11. package/dist/components/TicketConversation/components/CodeBlockInserter.d.ts +12 -0
  12. package/dist/components/TicketConversation/components/QuickActions.d.ts +32 -0
  13. package/dist/components/TicketConversation/components/TicketHeader.d.ts +19 -0
  14. package/dist/components/TicketConversation/components/TimeTrackingPanel.d.ts +24 -0
  15. package/dist/components/TicketConversation/config.d.ts +10 -0
  16. package/dist/components/TicketConversation/config.js +1 -40
  17. package/dist/components/TicketConversation/constants.d.ts +56 -0
  18. package/dist/components/TicketConversation/context.d.ts +53 -0
  19. package/dist/components/TicketConversation/hooks/useAI.d.ts +21 -0
  20. package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.d.ts +3 -0
  21. package/dist/components/TicketConversation/hooks/useFeatures.d.ts +23 -0
  22. package/dist/components/TicketConversation/hooks/useFeatures.js +61 -0
  23. package/dist/components/TicketConversation/hooks/useMessageActions.d.ts +20 -0
  24. package/dist/components/TicketConversation/hooks/useReply.d.ts +27 -0
  25. package/dist/components/TicketConversation/hooks/useTicketActions.d.ts +58 -0
  26. package/dist/components/TicketConversation/hooks/useTimeTracking.d.ts +18 -0
  27. package/dist/components/TicketConversation/hooks/useTranslation.d.ts +33 -0
  28. package/dist/components/TicketConversation/index.d.ts +4 -0
  29. package/dist/components/TicketConversation/index.js +2 -2
  30. package/dist/components/TicketConversation/types.d.ts +56 -0
  31. package/dist/components/TicketConversation/utils.d.ts +2 -0
  32. package/dist/index.cjs +392 -320
  33. package/dist/index.d.cts +100 -3
  34. package/dist/index.d.ts +100 -3
  35. package/dist/index.js +388 -321
  36. package/dist/utils/features.d.ts +123 -0
  37. package/dist/utils/features.js +147 -0
  38. package/dist/views/BillingView/client.d.ts +2 -0
  39. package/dist/views/BillingView/index.d.ts +4 -0
  40. package/dist/views/ChatView/client.d.ts +2 -0
  41. package/dist/views/ChatView/client.js +9 -9
  42. package/dist/views/ChatView/index.d.ts +4 -0
  43. package/dist/views/CrmView/client.d.ts +2 -0
  44. package/dist/views/CrmView/client.js +6 -9
  45. package/dist/views/CrmView/index.d.ts +4 -0
  46. package/dist/views/EmailTrackingView/client.d.ts +2 -0
  47. package/dist/views/EmailTrackingView/index.d.ts +4 -0
  48. package/dist/views/ImportConversationView/client.d.ts +2 -0
  49. package/dist/views/ImportConversationView/index.d.ts +4 -0
  50. package/dist/views/LogsView/client.d.ts +2 -0
  51. package/dist/views/LogsView/index.d.ts +4 -0
  52. package/dist/views/NewTicketView/client.d.ts +2 -0
  53. package/dist/views/NewTicketView/index.d.ts +4 -0
  54. package/dist/views/PendingEmailsView/client.d.ts +2 -0
  55. package/dist/views/PendingEmailsView/index.d.ts +4 -0
  56. package/dist/views/SupportDashboardView/client.d.ts +2 -0
  57. package/dist/views/SupportDashboardView/index.d.ts +4 -0
  58. package/dist/views/TicketDetailView/NextActionItem.d.ts +6 -0
  59. package/dist/views/TicketDetailView/RewriteDropdown.d.ts +7 -0
  60. package/dist/views/TicketDetailView/client.d.ts +2 -0
  61. package/dist/views/TicketDetailView/client.js +2 -2
  62. package/dist/views/TicketDetailView/constants.d.ts +13 -0
  63. package/dist/views/TicketDetailView/helpers.d.ts +2 -0
  64. package/dist/views/TicketDetailView/index.d.ts +4 -0
  65. package/dist/views/TicketDetailView/types.d.ts +40 -0
  66. package/dist/views/TicketInboxView/client.d.ts +2 -0
  67. package/dist/views/TicketInboxView/client.js +5 -5
  68. package/dist/views/TicketInboxView/index.d.ts +4 -0
  69. package/dist/views/TicketingSettingsView/client.d.ts +2 -0
  70. package/dist/views/TicketingSettingsView/client.js +5 -4
  71. package/dist/views/TicketingSettingsView/index.d.ts +4 -0
  72. package/dist/views/TimeDashboardView/client.d.ts +2 -0
  73. package/dist/views/TimeDashboardView/index.d.ts +4 -0
  74. package/dist/views/shared/AdminViewHeader.d.ts +13 -0
  75. package/dist/views/shared/ErrorBoundary.d.ts +17 -0
  76. package/dist/views/shared/Skeleton.d.ts +21 -0
  77. package/dist/views/shared/StatusPill.d.ts +8 -0
  78. package/dist/views/shared/adminTokens.d.ts +19 -0
  79. package/dist/views/shared/config.d.ts +8 -0
  80. package/dist/views/shared/config.js +1 -40
  81. package/dist/views/shared/dateLocale.d.ts +5 -0
  82. package/dist/views/shared/index.d.ts +12 -0
  83. package/dist/views/shared/index.js +2 -1
  84. package/dist/views/shared/sla.d.ts +14 -0
  85. package/dist/views.d.ts +13 -13
  86. package/package.json +16 -31
  87. package/src/collections/SupportClients.ts +29 -0
  88. package/src/collections/TicketCollaborators.ts +6 -1
  89. package/src/collections/TicketMessages.ts +46 -24
  90. package/src/collections/Tickets.ts +117 -79
  91. package/src/collections/TimeEntries.ts +57 -32
  92. package/src/components/TicketConversation/config.ts +16 -80
  93. package/src/components/TicketConversation/hooks/useFeatures.ts +109 -0
  94. package/src/components/TicketConversation/index.tsx +2 -2
  95. package/src/endpoints/ai.ts +2 -1
  96. package/src/endpoints/client-intelligence.ts +2 -1
  97. package/src/endpoints/process-scheduled.ts +13 -8
  98. package/src/endpoints/round-robin-config.ts +30 -20
  99. package/src/endpoints/settings.ts +28 -77
  100. package/src/index.ts +6 -2
  101. package/src/portal/LiveChat.tsx +33 -22
  102. package/src/portal/auth/tickets/detail/TicketPolling.tsx +5 -1
  103. package/src/types/lucide-react.d.ts +10 -2
  104. package/src/utils/aiAgent.ts +2 -1
  105. package/src/utils/aiProvider.ts +21 -0
  106. package/src/utils/features.ts +297 -0
  107. package/src/utils/fireWebhooks.ts +6 -0
  108. package/src/utils/generateTicketSynthesis.ts +2 -1
  109. package/src/utils/index.ts +4 -2
  110. package/src/utils/readSettings.ts +82 -9
  111. package/src/utils/webhookDispatcher.ts +19 -7
  112. package/src/views/ChatView/client.tsx +13 -9
  113. package/src/views/CrmView/client.tsx +10 -11
  114. package/src/views/TicketDetailView/client.tsx +2 -2
  115. package/src/views/TicketInboxView/client.tsx +10 -5
  116. package/src/views/TicketingSettingsView/client.tsx +8 -6
  117. package/src/views/shared/config.ts +14 -80
  118. package/src/views/shared/index.ts +3 -1
  119. package/dist/components/RichTextEditor/index.cjs +0 -279
  120. package/dist/components/TicketConversation/RewriteDropdown.cjs +0 -98
  121. package/dist/components/TicketConversation/SkeletonText.cjs +0 -21
  122. package/dist/components/TicketConversation/components/AISummaryPanel.cjs +0 -85
  123. package/dist/components/TicketConversation/components/ActionPanels.cjs +0 -193
  124. package/dist/components/TicketConversation/components/ActivityLog.cjs +0 -24
  125. package/dist/components/TicketConversation/components/ClientBar.cjs +0 -43
  126. package/dist/components/TicketConversation/components/ClientHistory.cjs +0 -138
  127. package/dist/components/TicketConversation/components/CodeBlock.cjs +0 -171
  128. package/dist/components/TicketConversation/components/CodeBlockInserter.cjs +0 -156
  129. package/dist/components/TicketConversation/components/QuickActions.cjs +0 -87
  130. package/dist/components/TicketConversation/components/TicketHeader.cjs +0 -93
  131. package/dist/components/TicketConversation/components/TimeTrackingPanel.cjs +0 -134
  132. package/dist/components/TicketConversation/config.cjs +0 -44
  133. package/dist/components/TicketConversation/constants.cjs +0 -127
  134. package/dist/components/TicketConversation/context.cjs +0 -13
  135. package/dist/components/TicketConversation/hooks/useAI.cjs +0 -196
  136. package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.cjs +0 -20
  137. package/dist/components/TicketConversation/hooks/useMessageActions.cjs +0 -136
  138. package/dist/components/TicketConversation/hooks/useReply.cjs +0 -188
  139. package/dist/components/TicketConversation/hooks/useTicketActions.cjs +0 -290
  140. package/dist/components/TicketConversation/hooks/useTimeTracking.cjs +0 -123
  141. package/dist/components/TicketConversation/hooks/useTranslation.cjs +0 -101
  142. package/dist/components/TicketConversation/index.cjs +0 -1114
  143. package/dist/components/TicketConversation/types.cjs +0 -2
  144. package/dist/components/TicketConversation/utils.cjs +0 -27
  145. package/dist/views/BillingView/client.cjs +0 -469
  146. package/dist/views/BillingView/index.cjs +0 -34
  147. package/dist/views/ChatView/client.cjs +0 -301
  148. package/dist/views/ChatView/index.cjs +0 -34
  149. package/dist/views/CrmView/client.cjs +0 -458
  150. package/dist/views/CrmView/index.cjs +0 -34
  151. package/dist/views/EmailTrackingView/client.cjs +0 -171
  152. package/dist/views/EmailTrackingView/index.cjs +0 -34
  153. package/dist/views/ImportConversationView/client.cjs +0 -238
  154. package/dist/views/ImportConversationView/index.cjs +0 -34
  155. package/dist/views/LogsView/client.cjs +0 -148
  156. package/dist/views/LogsView/index.cjs +0 -32
  157. package/dist/views/NewTicketView/client.cjs +0 -213
  158. package/dist/views/NewTicketView/index.cjs +0 -32
  159. package/dist/views/PendingEmailsView/client.cjs +0 -471
  160. package/dist/views/PendingEmailsView/index.cjs +0 -34
  161. package/dist/views/SupportDashboardView/client.cjs +0 -437
  162. package/dist/views/SupportDashboardView/index.cjs +0 -34
  163. package/dist/views/TicketDetailView/NextActionItem.cjs +0 -40
  164. package/dist/views/TicketDetailView/RewriteDropdown.cjs +0 -80
  165. package/dist/views/TicketDetailView/client.cjs +0 -1412
  166. package/dist/views/TicketDetailView/constants.cjs +0 -20
  167. package/dist/views/TicketDetailView/helpers.cjs +0 -23
  168. package/dist/views/TicketDetailView/index.cjs +0 -34
  169. package/dist/views/TicketDetailView/types.cjs +0 -2
  170. package/dist/views/TicketInboxView/client.cjs +0 -359
  171. package/dist/views/TicketInboxView/index.cjs +0 -32
  172. package/dist/views/TicketingSettingsView/client.cjs +0 -740
  173. package/dist/views/TicketingSettingsView/index.cjs +0 -34
  174. package/dist/views/TimeDashboardView/client.cjs +0 -180
  175. package/dist/views/TimeDashboardView/index.cjs +0 -34
  176. package/dist/views/shared/AdminViewHeader.cjs +0 -68
  177. package/dist/views/shared/ErrorBoundary.cjs +0 -55
  178. package/dist/views/shared/Skeleton.cjs +0 -77
  179. package/dist/views/shared/StatusPill.cjs +0 -47
  180. package/dist/views/shared/adminTokens.cjs +0 -34
  181. package/dist/views/shared/config.cjs +0 -44
  182. package/dist/views/shared/dateLocale.cjs +0 -5
  183. package/dist/views/shared/index.cjs +0 -72
  184. package/dist/views/shared/sla.cjs +0 -37
  185. package/dist/views.cjs +0 -86
  186. package/dist/views.d.cts +0 -13
  187. package/src/__tests__/aiSummaryRendering.test.ts +0 -21
  188. package/src/__tests__/authResponses.test.ts +0 -69
  189. package/src/__tests__/capabilities.test.ts +0 -71
  190. package/src/__tests__/generateTrackingToken.test.ts +0 -67
  191. package/src/__tests__/integration/ai-agent.test.ts +0 -46
  192. package/src/__tests__/integration/auth.test.ts +0 -43
  193. package/src/__tests__/integration/automation-rules.test.ts +0 -68
  194. package/src/__tests__/integration/buildTestPayload.ts +0 -52
  195. package/src/__tests__/integration/channels.test.ts +0 -52
  196. package/src/__tests__/integration/core-behaviors.test.ts +0 -81
  197. package/src/__tests__/integration/dashboard-volume.test.ts +0 -31
  198. package/src/__tests__/integration/digest.test.ts +0 -48
  199. package/src/__tests__/integration/invoice-pdf.test.ts +0 -30
  200. package/src/__tests__/integration/isolation.test.ts +0 -81
  201. package/src/__tests__/integration/mentions-invoice.test.ts +0 -50
  202. package/src/__tests__/integration/nps.test.ts +0 -37
  203. package/src/__tests__/integration/per-team-sla.test.ts +0 -44
  204. package/src/__tests__/integration/push.test.ts +0 -75
  205. package/src/__tests__/integration/sanitization.test.ts +0 -35
  206. package/src/__tests__/integration/sla-pause.test.ts +0 -39
  207. package/src/__tests__/integration/smoke.test.ts +0 -26
  208. package/src/__tests__/integration/snooze.test.ts +0 -68
  209. package/src/__tests__/integration/teams.test.ts +0 -38
  210. package/src/__tests__/rateLimiter.test.ts +0 -83
  211. package/src/__tests__/sanitizeHtml.test.ts +0 -165
  212. package/src/__tests__/sla.test.ts +0 -258
  213. package/src/__tests__/trackOpenEndpoint.test.ts +0 -54
  214. package/src/__tests__/translations.test.ts +0 -67
  215. package/src/__tests__/webhookSecurity.test.ts +0 -58
@@ -1,290 +0,0 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
-
5
- function useTicketActions(id, fetchAll) {
6
- const [statusUpdating, setStatusUpdating] = react.useState(false);
7
- const [showMerge, setShowMerge] = react.useState(false);
8
- const [mergeTarget, setMergeTarget] = react.useState("");
9
- const [mergeTargetInfo, setMergeTargetInfo] = react.useState(null);
10
- const [merging, setMerging] = react.useState(false);
11
- const [mergeError, setMergeError] = react.useState("");
12
- const [showExtMsg, setShowExtMsg] = react.useState(false);
13
- const [extMsgBody, setExtMsgBody] = react.useState("");
14
- const [extMsgAuthor, setExtMsgAuthor] = react.useState("client");
15
- const [extMsgDate, setExtMsgDate] = react.useState("");
16
- const [extMsgFiles, setExtMsgFiles] = react.useState([]);
17
- const [sendingExtMsg, setSendingExtMsg] = react.useState(false);
18
- const extFileInputRef = react.useRef(null);
19
- const [showSnooze, setShowSnooze] = react.useState(false);
20
- const [snoozeUntil, setSnoozeUntil] = react.useState(null);
21
- const [snoozeSaving, setSnoozeSaving] = react.useState(false);
22
- const [showReminder, setShowReminder] = react.useState(false);
23
- const [reminderHours, setReminderHours] = react.useState(24);
24
- const [reminderSending, setReminderSending] = react.useState(false);
25
- const [reminderError, setReminderError] = react.useState("");
26
- const [reminderSuccess, setReminderSuccess] = react.useState(false);
27
- const [cancelingClose, setCancelingClose] = react.useState(false);
28
- const [showNextTicket, setShowNextTicket] = react.useState(false);
29
- const [nextTicketId, setNextTicketId] = react.useState(null);
30
- const [nextTicketInfo, setNextTicketInfo] = react.useState("");
31
- const handleStatusChange = async (newStatus) => {
32
- if (!id) return;
33
- setStatusUpdating(true);
34
- try {
35
- await fetch(`/api/tickets/${id}`, {
36
- method: "PATCH",
37
- headers: { "Content-Type": "application/json" },
38
- credentials: "include",
39
- body: JSON.stringify({ status: newStatus })
40
- });
41
- window.location.reload();
42
- } catch {
43
- } finally {
44
- setStatusUpdating(false);
45
- }
46
- };
47
- const handleMergeLookup = async () => {
48
- if (!mergeTarget.trim()) return;
49
- setMergeTargetInfo(null);
50
- setMergeError("");
51
- try {
52
- const searchVal = mergeTarget.trim().toUpperCase();
53
- const res = await fetch(`/api/tickets?where[ticketNumber][equals]=${encodeURIComponent(searchVal)}&limit=1&depth=0`, { credentials: "include" });
54
- if (res.ok) {
55
- const d = await res.json();
56
- if (d.docs?.length > 0) {
57
- const t = d.docs[0];
58
- if (String(t.id) === String(id)) {
59
- setMergeError("Impossible de fusionner un ticket avec lui-m\xEAme");
60
- } else {
61
- setMergeTargetInfo({ id: t.id, ticketNumber: t.ticketNumber, subject: t.subject });
62
- }
63
- } else {
64
- setMergeError("Ticket introuvable");
65
- }
66
- }
67
- } catch {
68
- setMergeError("Erreur de recherche");
69
- }
70
- };
71
- const handleMerge = async () => {
72
- if (!mergeTargetInfo || !id) return;
73
- setMerging(true);
74
- setMergeError("");
75
- try {
76
- const res = await fetch("/api/support/merge-tickets", {
77
- method: "POST",
78
- headers: { "Content-Type": "application/json" },
79
- credentials: "include",
80
- body: JSON.stringify({ sourceTicketId: id, targetTicketId: mergeTargetInfo.id })
81
- });
82
- if (res.ok) {
83
- window.location.href = `/admin/collections/tickets/${mergeTargetInfo.id}`;
84
- } else {
85
- const d = await res.json().catch(() => ({}));
86
- setMergeError(d.error || "Erreur de fusion");
87
- }
88
- } catch {
89
- setMergeError("Erreur r\xE9seau");
90
- } finally {
91
- setMerging(false);
92
- }
93
- };
94
- const handleExtFileChange = (e) => {
95
- if (e.target.files) {
96
- const maxSize = 1 * 1024 * 1024;
97
- const newFiles = Array.from(e.target.files);
98
- const tooLarge = newFiles.filter((f) => f.size > maxSize);
99
- if (tooLarge.length > 0) {
100
- alert(`Fichier(s) trop volumineux (max 1 Mo) : ${tooLarge.map((f) => f.name).join(", ")}`);
101
- }
102
- setExtMsgFiles((prev) => [...prev, ...newFiles.filter((f) => f.size <= maxSize)]);
103
- }
104
- if (extFileInputRef.current) extFileInputRef.current.value = "";
105
- };
106
- const handleSendExtMsg = async () => {
107
- if (!extMsgBody.trim() || !id) return;
108
- setSendingExtMsg(true);
109
- try {
110
- const uploadedIds = [];
111
- for (const file of extMsgFiles) {
112
- if (file.size > 1 * 1024 * 1024) continue;
113
- const formData = new FormData();
114
- formData.append("file", file);
115
- formData.append("_payload", JSON.stringify({ alt: file.name }));
116
- const uploadRes = await fetch("/api/media", { method: "POST", credentials: "include", body: formData });
117
- if (uploadRes.ok) {
118
- const d = await uploadRes.json();
119
- if (d.doc?.id) uploadedIds.push(d.doc.id);
120
- }
121
- }
122
- const messageData = {
123
- ticket: id,
124
- body: extMsgBody.trim(),
125
- authorType: extMsgAuthor,
126
- isInternal: false,
127
- skipNotification: true
128
- };
129
- if (extMsgDate) {
130
- messageData.createdAt = new Date(extMsgDate).toISOString();
131
- }
132
- if (uploadedIds.length > 0) {
133
- messageData.attachments = uploadedIds.map((mid) => ({ file: mid }));
134
- }
135
- const res = await fetch("/api/ticket-messages", {
136
- method: "POST",
137
- headers: { "Content-Type": "application/json" },
138
- credentials: "include",
139
- body: JSON.stringify(messageData)
140
- });
141
- if (res.ok) {
142
- setExtMsgBody("");
143
- setExtMsgDate("");
144
- setExtMsgFiles([]);
145
- setShowExtMsg(false);
146
- fetchAll();
147
- }
148
- } catch {
149
- } finally {
150
- setSendingExtMsg(false);
151
- }
152
- };
153
- const handleSnooze = async (days, customDate) => {
154
- if (!id) return;
155
- setSnoozeSaving(true);
156
- try {
157
- let newSnooze = null;
158
- if (days !== null) {
159
- const d = /* @__PURE__ */ new Date();
160
- d.setDate(d.getDate() + days);
161
- newSnooze = d.toISOString();
162
- } else if (customDate) {
163
- newSnooze = new Date(customDate).toISOString();
164
- }
165
- await fetch(`/api/tickets/${id}`, {
166
- method: "PATCH",
167
- headers: { "Content-Type": "application/json" },
168
- credentials: "include",
169
- body: JSON.stringify({ snoozeUntil: newSnooze })
170
- });
171
- setSnoozeUntil(newSnooze);
172
- setShowSnooze(false);
173
- fetchAll();
174
- } catch {
175
- } finally {
176
- setSnoozeSaving(false);
177
- }
178
- };
179
- const handleSendReminder = async () => {
180
- if (!id) return;
181
- setReminderSending(true);
182
- setReminderError("");
183
- try {
184
- const res = await fetch("/api/support/send-reminder", {
185
- method: "POST",
186
- headers: { "Content-Type": "application/json" },
187
- credentials: "include",
188
- body: JSON.stringify({ ticketId: id, hours: reminderHours })
189
- });
190
- const d = await res.json().catch(() => ({}));
191
- if (res.ok) {
192
- setShowReminder(false);
193
- setReminderSuccess(true);
194
- setTimeout(() => setReminderSuccess(false), 5e3);
195
- fetchAll();
196
- } else {
197
- setReminderError(d.error || "Erreur lors de la relance");
198
- }
199
- } catch {
200
- setReminderError("Erreur r\xE9seau");
201
- } finally {
202
- setReminderSending(false);
203
- }
204
- };
205
- const handleCancelScheduledClose = async () => {
206
- if (!id) return;
207
- setCancelingClose(true);
208
- try {
209
- await fetch(`/api/tickets/${id}`, {
210
- method: "PATCH",
211
- headers: { "Content-Type": "application/json" },
212
- credentials: "include",
213
- body: JSON.stringify({ autoCloseScheduledAt: null, autoCloseRemindedAt: null })
214
- });
215
- fetchAll();
216
- } catch {
217
- } finally {
218
- setCancelingClose(false);
219
- }
220
- };
221
- const handleNextTicket = async () => {
222
- try {
223
- const res = await fetch("/api/tickets?where[status][equals]=open&sort=updatedAt&limit=1&depth=0", { credentials: "include" });
224
- if (res.ok) {
225
- const d = await res.json();
226
- if (d.docs?.length > 0 && String(d.docs[0].id) !== String(id)) {
227
- setNextTicketId(d.docs[0].id);
228
- setNextTicketInfo(`${d.docs[0].ticketNumber} \u2014 ${d.docs[0].subject}`);
229
- } else {
230
- setNextTicketId(null);
231
- setNextTicketInfo("Aucun autre ticket ouvert");
232
- }
233
- setShowNextTicket(true);
234
- }
235
- } catch {
236
- }
237
- };
238
- return {
239
- statusUpdating,
240
- handleStatusChange,
241
- showMerge,
242
- setShowMerge,
243
- mergeTarget,
244
- setMergeTarget,
245
- mergeTargetInfo,
246
- setMergeTargetInfo,
247
- mergeError,
248
- setMergeError,
249
- merging,
250
- handleMergeLookup,
251
- handleMerge,
252
- showExtMsg,
253
- setShowExtMsg,
254
- extMsgBody,
255
- setExtMsgBody,
256
- extMsgAuthor,
257
- setExtMsgAuthor,
258
- extMsgDate,
259
- setExtMsgDate,
260
- extMsgFiles,
261
- setExtMsgFiles,
262
- sendingExtMsg,
263
- handleExtFileChange,
264
- handleSendExtMsg,
265
- showSnooze,
266
- setShowSnooze,
267
- snoozeUntil,
268
- setSnoozeUntil,
269
- snoozeSaving,
270
- handleSnooze,
271
- showReminder,
272
- setShowReminder,
273
- reminderHours,
274
- setReminderHours,
275
- reminderSending,
276
- reminderError,
277
- setReminderError,
278
- reminderSuccess,
279
- handleSendReminder,
280
- cancelingClose,
281
- handleCancelScheduledClose,
282
- showNextTicket,
283
- setShowNextTicket,
284
- nextTicketId,
285
- nextTicketInfo,
286
- handleNextTicket
287
- };
288
- }
289
-
290
- exports.useTicketActions = useTicketActions;
@@ -1,123 +0,0 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
-
5
- function useTimeTracking(id, fetchAll) {
6
- const [duration, setDuration] = react.useState("");
7
- const [timeDescription, setTimeDescription] = react.useState("");
8
- const [addingTime, setAddingTime] = react.useState(false);
9
- const [timeSuccess, setTimeSuccess] = react.useState("");
10
- const [timerRunning, setTimerRunning] = react.useState(false);
11
- const [timerSeconds, setTimerSeconds] = react.useState(0);
12
- const [timerDescription, setTimerDescription] = react.useState("");
13
- const timerIntervalRef = react.useRef(null);
14
- const timerKeepAliveRef = react.useRef(null);
15
- const handleAddTime = async () => {
16
- if (!duration || !id) return;
17
- setAddingTime(true);
18
- setTimeSuccess("");
19
- try {
20
- const res = await fetch("/api/time-entries", {
21
- method: "POST",
22
- headers: { "Content-Type": "application/json" },
23
- credentials: "include",
24
- body: JSON.stringify({
25
- ticket: id,
26
- duration: parseInt(duration, 10),
27
- date: (/* @__PURE__ */ new Date()).toISOString(),
28
- description: timeDescription.trim() || void 0
29
- })
30
- });
31
- if (res.ok) {
32
- setDuration("");
33
- setTimeDescription("");
34
- setTimeSuccess(`${duration} min ajout\xE9es`);
35
- setTimeout(() => setTimeSuccess(""), 3e3);
36
- fetchAll();
37
- }
38
- } catch {
39
- } finally {
40
- setAddingTime(false);
41
- }
42
- };
43
- const handleTimerStart = (reset = false) => {
44
- setTimerRunning(true);
45
- if (reset) setTimerSeconds(0);
46
- timerIntervalRef.current = setInterval(() => {
47
- setTimerSeconds((prev) => prev + 1);
48
- }, 1e3);
49
- timerKeepAliveRef.current = setInterval(() => {
50
- fetch("/api/users/me", { credentials: "include" }).catch(() => {
51
- });
52
- }, 5 * 60 * 1e3);
53
- };
54
- const handleTimerStop = () => {
55
- setTimerRunning(false);
56
- if (timerIntervalRef.current) {
57
- clearInterval(timerIntervalRef.current);
58
- timerIntervalRef.current = null;
59
- }
60
- if (timerKeepAliveRef.current) {
61
- clearInterval(timerKeepAliveRef.current);
62
- timerKeepAliveRef.current = null;
63
- }
64
- };
65
- const handleTimerSave = async () => {
66
- if (!id || timerSeconds < 60) return;
67
- const minutes = Math.round(timerSeconds / 60);
68
- setAddingTime(true);
69
- try {
70
- const res = await fetch("/api/time-entries", {
71
- method: "POST",
72
- headers: { "Content-Type": "application/json" },
73
- credentials: "include",
74
- body: JSON.stringify({
75
- ticket: id,
76
- duration: minutes,
77
- date: (/* @__PURE__ */ new Date()).toISOString(),
78
- description: timerDescription.trim() || "Timer"
79
- })
80
- });
81
- if (res.ok) {
82
- setTimeSuccess(`${minutes} min ajout\xE9es (timer)`);
83
- setTimeout(() => setTimeSuccess(""), 3e3);
84
- setTimerSeconds(0);
85
- setTimerDescription("");
86
- fetchAll();
87
- }
88
- } catch {
89
- } finally {
90
- setAddingTime(false);
91
- }
92
- };
93
- const handleTimerDiscard = () => {
94
- setTimerSeconds(0);
95
- setTimerDescription("");
96
- };
97
- react.useEffect(() => {
98
- return () => {
99
- if (timerIntervalRef.current) clearInterval(timerIntervalRef.current);
100
- if (timerKeepAliveRef.current) clearInterval(timerKeepAliveRef.current);
101
- };
102
- }, []);
103
- return {
104
- duration,
105
- setDuration,
106
- timeDescription,
107
- setTimeDescription,
108
- addingTime,
109
- timeSuccess,
110
- timerRunning,
111
- timerSeconds,
112
- setTimerSeconds,
113
- timerDescription,
114
- setTimerDescription,
115
- handleAddTime,
116
- handleTimerStart,
117
- handleTimerStop,
118
- handleTimerSave,
119
- handleTimerDiscard
120
- };
121
- }
122
-
123
- exports.useTimeTracking = useTimeTracking;
@@ -1,101 +0,0 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
- var frTranslations = require('../locales/fr.json');
5
- var enTranslations = require('../locales/en.json');
6
- var frViewTranslations = require('../../../views/shared/locales/fr.json');
7
- var enViewTranslations = require('../../../views/shared/locales/en.json');
8
-
9
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
-
11
- var frTranslations__default = /*#__PURE__*/_interopDefault(frTranslations);
12
- var enTranslations__default = /*#__PURE__*/_interopDefault(enTranslations);
13
- var frViewTranslations__default = /*#__PURE__*/_interopDefault(frViewTranslations);
14
- var enViewTranslations__default = /*#__PURE__*/_interopDefault(enViewTranslations);
15
-
16
- const LOCALE_STORAGE_KEY = "support_locale";
17
- const DEFAULT_LOCALE = "fr";
18
- function mergeTranslations(base, supplement) {
19
- const merged = { ...base };
20
- for (const [key, value] of Object.entries(supplement)) {
21
- const current = merged[key];
22
- if (current != null && value != null && typeof current === "object" && typeof value === "object" && !Array.isArray(current) && !Array.isArray(value)) {
23
- merged[key] = mergeTranslations(
24
- current,
25
- value
26
- );
27
- continue;
28
- }
29
- if (current === void 0 || typeof current !== "object" && typeof value === "object") {
30
- merged[key] = value;
31
- }
32
- }
33
- return merged;
34
- }
35
- const translations = {
36
- fr: mergeTranslations(frTranslations__default.default, frViewTranslations__default.default),
37
- en: mergeTranslations(enTranslations__default.default, enViewTranslations__default.default)
38
- };
39
- function getNestedValue(obj, path) {
40
- const keys = path.split(".");
41
- let current = obj;
42
- for (const key of keys) {
43
- if (current == null || typeof current !== "object") {
44
- return path;
45
- }
46
- current = current[key];
47
- }
48
- if (typeof current === "string") {
49
- return current;
50
- }
51
- return path;
52
- }
53
- function interpolate(template, vars) {
54
- if (!vars) return template;
55
- return template.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g, (_, key) => {
56
- return String(vars[key] ?? `{{${key}}}`);
57
- });
58
- }
59
- function useTranslation() {
60
- const [locale, setLocaleState] = react.useState(() => {
61
- if (typeof window === "undefined") return DEFAULT_LOCALE;
62
- try {
63
- const stored = localStorage.getItem(LOCALE_STORAGE_KEY);
64
- if (stored === "fr" || stored === "en") return stored;
65
- } catch {
66
- }
67
- return DEFAULT_LOCALE;
68
- });
69
- react.useEffect(() => {
70
- fetch("/api/support/user-prefs", { credentials: "include" }).then((r) => r.ok ? r.json() : null).then((data) => {
71
- if (data?.locale && (data.locale === "fr" || data.locale === "en")) {
72
- setLocaleState(data.locale);
73
- }
74
- }).catch(() => {
75
- });
76
- }, []);
77
- react.useEffect(() => {
78
- try {
79
- localStorage.setItem(LOCALE_STORAGE_KEY, locale);
80
- } catch {
81
- }
82
- }, [locale]);
83
- const setLocale = react.useCallback((newLocale) => {
84
- setLocaleState(newLocale);
85
- }, []);
86
- const t = react.useCallback(
87
- (key, vars) => {
88
- const dict = translations[locale] || translations[DEFAULT_LOCALE];
89
- const value = getNestedValue(dict, key);
90
- return interpolate(value, vars);
91
- },
92
- [locale]
93
- );
94
- return { t, locale, setLocale };
95
- }
96
-
97
- exports.DEFAULT_LOCALE = DEFAULT_LOCALE;
98
- exports.LOCALE_STORAGE_KEY = LOCALE_STORAGE_KEY;
99
- exports.getNestedValue = getNestedValue;
100
- exports.translations = translations;
101
- exports.useTranslation = useTranslation;