@echothink-ui/inbox 0.1.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 (52) hide show
  1. package/README.md +5 -0
  2. package/dist/components/AgentDraftReviewPanel.d.ts +18 -0
  3. package/dist/components/ApprovalToSendPanel.d.ts +11 -0
  4. package/dist/components/AttachmentList.d.ts +8 -0
  5. package/dist/components/AttachmentPreview.d.ts +7 -0
  6. package/dist/components/EmailAutomationRulePanel.d.ts +8 -0
  7. package/dist/components/InboxShell.d.ts +10 -0
  8. package/dist/components/LabelManager.d.ts +9 -0
  9. package/dist/components/MailboxFolderList.d.ts +8 -0
  10. package/dist/components/MessageComposer.d.ts +13 -0
  11. package/dist/components/MessageFilterBar.d.ts +13 -0
  12. package/dist/components/MessageList.d.ts +8 -0
  13. package/dist/components/MessagePreview.d.ts +9 -0
  14. package/dist/components/MessageSearch.d.ts +11 -0
  15. package/dist/components/MessageThread.d.ts +22 -0
  16. package/dist/components/PriorityInboxView.d.ts +14 -0
  17. package/dist/components/RecipientPicker.d.ts +10 -0
  18. package/dist/components/ThreadSummaryPanel.d.ts +9 -0
  19. package/dist/index.cjs +1699 -0
  20. package/dist/index.cjs.map +1 -0
  21. package/dist/index.css +2155 -0
  22. package/dist/index.css.map +1 -0
  23. package/dist/index.d.ts +21 -0
  24. package/dist/index.js +1645 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/types.d.ts +75 -0
  27. package/dist/utils.d.ts +5 -0
  28. package/package.json +44 -0
  29. package/src/components/AgentDraftReviewPanel.tsx +128 -0
  30. package/src/components/ApprovalToSendPanel.tsx +118 -0
  31. package/src/components/AttachmentList.tsx +85 -0
  32. package/src/components/AttachmentPreview.tsx +207 -0
  33. package/src/components/EmailAutomationRulePanel.tsx +100 -0
  34. package/src/components/InboxShell.tsx +62 -0
  35. package/src/components/LabelManager.tsx +147 -0
  36. package/src/components/MailboxFolderList.tsx +66 -0
  37. package/src/components/MessageComposer.tsx +160 -0
  38. package/src/components/MessageFilterBar.test.tsx +34 -0
  39. package/src/components/MessageFilterBar.tsx +69 -0
  40. package/src/components/MessageList.tsx +101 -0
  41. package/src/components/MessagePreview.test.tsx +48 -0
  42. package/src/components/MessagePreview.tsx +84 -0
  43. package/src/components/MessageSearch.tsx +96 -0
  44. package/src/components/MessageThread.tsx +173 -0
  45. package/src/components/PriorityInboxView.tsx +74 -0
  46. package/src/components/RecipientPicker.tsx +181 -0
  47. package/src/components/ThreadSummaryPanel.tsx +107 -0
  48. package/src/index.test.tsx +276 -0
  49. package/src/index.tsx +60 -0
  50. package/src/styles.css +2523 -0
  51. package/src/types.ts +85 -0
  52. package/src/utils.ts +33 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,1699 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.tsx
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AgentDraftReviewPanel: () => AgentDraftReviewPanel,
34
+ ApprovalToSendPanel: () => ApprovalToSendPanel,
35
+ AttachmentList: () => AttachmentList,
36
+ AttachmentPreview: () => AttachmentPreview,
37
+ EmailAutomationRulePanel: () => EmailAutomationRulePanel,
38
+ InboxComponentNames: () => InboxComponentNames,
39
+ InboxShell: () => InboxShell,
40
+ LabelManager: () => LabelManager,
41
+ MailboxFolderList: () => MailboxFolderList,
42
+ MessageComposer: () => MessageComposer,
43
+ MessageFilterBar: () => MessageFilterBar,
44
+ MessageList: () => MessageList,
45
+ MessagePreview: () => MessagePreview,
46
+ MessageSearch: () => MessageSearch,
47
+ MessageThread: () => MessageThread,
48
+ PriorityInboxView: () => PriorityInboxView,
49
+ RecipientPicker: () => RecipientPicker,
50
+ ThreadSummaryPanel: () => ThreadSummaryPanel
51
+ });
52
+ module.exports = __toCommonJS(index_exports);
53
+
54
+ // src/components/InboxShell.tsx
55
+ var import_jsx_runtime = require("react/jsx-runtime");
56
+ function InboxShell({
57
+ folders,
58
+ list,
59
+ thread,
60
+ inspector,
61
+ toolbar,
62
+ className,
63
+ title,
64
+ description,
65
+ ...props
66
+ }) {
67
+ const hasInspector = Boolean(inspector);
68
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
69
+ "section",
70
+ {
71
+ ...props,
72
+ className: `eth-inbox-shell ${className ?? ""}`,
73
+ "data-eth-component": "InboxShell",
74
+ children: [
75
+ (title || description || toolbar) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", { className: "eth-inbox-shell__header", children: [
76
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
77
+ title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: title }) : null,
78
+ description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: description }) : null
79
+ ] }),
80
+ toolbar ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "eth-inbox-shell__toolbar", children: toolbar }) : null
81
+ ] }),
82
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
83
+ "div",
84
+ {
85
+ className: `eth-inbox-shell__layout ${hasInspector ? "eth-inbox-shell__layout--has-inspector" : ""}`,
86
+ children: [
87
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("aside", { className: "eth-inbox-shell__folders", "aria-label": "Mailbox folders", children: folders }),
88
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("aside", { className: "eth-inbox-shell__list", "aria-label": "Message list", children: list }),
89
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("main", { className: "eth-inbox-shell__thread", "aria-label": "Selected conversation", children: thread }),
90
+ inspector ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("aside", { className: "eth-inbox-shell__inspector", "aria-label": "Conversation inspector", children: inspector }) : null
91
+ ]
92
+ }
93
+ )
94
+ ]
95
+ }
96
+ );
97
+ }
98
+
99
+ // src/components/MailboxFolderList.tsx
100
+ var import_core = require("@echothink-ui/core");
101
+ var import_jsx_runtime2 = require("react/jsx-runtime");
102
+ function MailboxFolderList({
103
+ folders = [],
104
+ activeFolderId,
105
+ onSelect,
106
+ className,
107
+ "aria-label": ariaLabel = "Mailbox folders",
108
+ ...props
109
+ }) {
110
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
111
+ "nav",
112
+ {
113
+ ...props,
114
+ className: ["eth-inbox-folders", className].filter(Boolean).join(" "),
115
+ "data-eth-component": "MailboxFolderList",
116
+ "aria-label": ariaLabel,
117
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { className: "eth-inbox-folders__list", children: folders.map((folder) => {
118
+ const isActive = activeFolderId === folder.id;
119
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
120
+ "button",
121
+ {
122
+ type: "button",
123
+ className: [
124
+ "eth-inbox-folders__item",
125
+ isActive ? "eth-inbox-folders__item--active" : "",
126
+ folder.smart ? "eth-inbox-folders__item--smart" : ""
127
+ ].filter(Boolean).join(" "),
128
+ "aria-current": isActive ? "page" : void 0,
129
+ onClick: () => onSelect?.(folder.id),
130
+ title: folder.label,
131
+ children: [
132
+ folder.icon ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "eth-inbox-folders__icon", "aria-hidden": "true", children: folder.icon }) : null,
133
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "eth-inbox-folders__label", children: folder.label }),
134
+ typeof folder.count === "number" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core.Badge, { className: "eth-inbox-folders__count", "aria-label": `${folder.count} items`, children: folder.count }) : null
135
+ ]
136
+ }
137
+ ) }, folder.id);
138
+ }) })
139
+ }
140
+ );
141
+ }
142
+
143
+ // src/components/MessageList.tsx
144
+ var import_core2 = require("@echothink-ui/core");
145
+
146
+ // src/utils.ts
147
+ function formatDateTime(value) {
148
+ const date = new Date(value);
149
+ if (Number.isNaN(date.getTime())) return value;
150
+ return new Intl.DateTimeFormat(void 0, {
151
+ month: "short",
152
+ day: "numeric",
153
+ hour: "numeric",
154
+ minute: "2-digit"
155
+ }).format(date);
156
+ }
157
+ function formatBytes(size) {
158
+ if (size < 1024) return `${size} B`;
159
+ if (size < 1024 * 1024) return `${Math.round(size / 1024)} KB`;
160
+ return `${(size / (1024 * 1024)).toFixed(1)} MB`;
161
+ }
162
+ function listToInput(value) {
163
+ return value?.join(", ") ?? "";
164
+ }
165
+ function inputToList(value) {
166
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
167
+ }
168
+ function prioritySeverity(priority) {
169
+ if (priority === "high") return "danger";
170
+ if (priority === "low") return "neutral";
171
+ return "info";
172
+ }
173
+
174
+ // src/components/MessageList.tsx
175
+ var import_jsx_runtime3 = require("react/jsx-runtime");
176
+ function MessageList({
177
+ threads = [],
178
+ selectedThreadId,
179
+ onSelect,
180
+ className,
181
+ ...props
182
+ }) {
183
+ const hasThreads = threads.length > 0;
184
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
185
+ "div",
186
+ {
187
+ ...props,
188
+ className: `eth-inbox-message-list ${className ?? ""}`,
189
+ role: "listbox",
190
+ "aria-label": "Message threads",
191
+ "data-eth-component": "MessageList",
192
+ children: hasThreads ? threads.map((thread, index) => {
193
+ const receivedAtLabel = formatDateTime(thread.receivedAt);
194
+ const selected = selectedThreadId === thread.id;
195
+ const hasMeta = Boolean(thread.priority || thread.labels?.length || thread.status);
196
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
197
+ "button",
198
+ {
199
+ type: "button",
200
+ role: "option",
201
+ "aria-label": [
202
+ thread.unread ? "Unread" : "Read",
203
+ `From ${thread.from}`,
204
+ thread.subject,
205
+ `Received ${receivedAtLabel}`,
206
+ thread.priority ? `${thread.priority} priority` : null,
207
+ thread.status ? (0, import_core2.statusLabel)(thread.status) : null
208
+ ].filter(Boolean).join(", "),
209
+ "aria-posinset": index + 1,
210
+ "aria-selected": selected,
211
+ "aria-setsize": threads.length,
212
+ className: `eth-inbox-message-list__row ${thread.unread ? "eth-inbox-message-list__row--unread" : ""}`,
213
+ onClick: () => onSelect?.(thread.id),
214
+ children: [
215
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "eth-inbox-message-list__selection", "aria-hidden": "true" }),
216
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "eth-inbox-message-list__content", children: [
217
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "eth-inbox-message-list__header", children: [
218
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "eth-inbox-message-list__from-group", children: [
219
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "eth-inbox-message-list__unread", "aria-hidden": "true" }),
220
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "eth-inbox-message-list__from", children: thread.from })
221
+ ] }),
222
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("time", { className: "eth-inbox-message-list__date", dateTime: thread.receivedAt, children: receivedAtLabel })
223
+ ] }),
224
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { className: "eth-inbox-message-list__subject", children: thread.subject }),
225
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "eth-inbox-message-list__preview", children: thread.preview }),
226
+ hasMeta ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "eth-inbox-message-list__meta", children: [
227
+ thread.priority ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core2.Badge, { severity: prioritySeverity(thread.priority), children: thread.priority }) : null,
228
+ thread.labels?.map((label) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core2.Tag, { children: label }, label)),
229
+ thread.status ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core2.StatusDot, { status: thread.status, label: (0, import_core2.statusLabel)(thread.status) }) : null
230
+ ] }) : null
231
+ ] })
232
+ ]
233
+ },
234
+ thread.id
235
+ );
236
+ }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
237
+ "div",
238
+ {
239
+ className: "eth-inbox-message-list__empty",
240
+ role: "status",
241
+ "aria-label": "No message threads",
242
+ children: "No message threads"
243
+ }
244
+ )
245
+ }
246
+ );
247
+ }
248
+
249
+ // src/components/MessageThread.tsx
250
+ var React2 = __toESM(require("react"), 1);
251
+ var import_core4 = require("@echothink-ui/core");
252
+
253
+ // src/components/MessagePreview.tsx
254
+ var React = __toESM(require("react"), 1);
255
+
256
+ // src/components/AttachmentList.tsx
257
+ var import_core3 = require("@echothink-ui/core");
258
+ var import_icons = require("@echothink-ui/icons");
259
+ var import_jsx_runtime4 = require("react/jsx-runtime");
260
+ function AttachmentList({
261
+ attachments = [],
262
+ onPreview,
263
+ onDownload,
264
+ className,
265
+ role,
266
+ "aria-label": ariaLabel,
267
+ ...props
268
+ }) {
269
+ if (!attachments.length) return null;
270
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
271
+ "div",
272
+ {
273
+ ...props,
274
+ className: ["eth-inbox-attachments", className].filter(Boolean).join(" "),
275
+ "data-eth-component": "AttachmentList",
276
+ role: role ?? "list",
277
+ "aria-label": ariaLabel ?? "Message attachments",
278
+ children: attachments.map((attachment) => {
279
+ const typeLabel = attachmentTypeLabel(attachment);
280
+ const hasActions = Boolean(onPreview || onDownload);
281
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "eth-inbox-attachments__tile", role: "listitem", children: [
282
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "eth-inbox-attachments__icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons.DocumentIcon, { size: 18 }) }),
283
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "eth-inbox-attachments__content", children: [
284
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { title: attachment.name, children: attachment.name }),
285
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "eth-inbox-attachments__meta", children: [
286
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "eth-inbox-attachments__type", children: typeLabel }),
287
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: attachment.mimeType }),
288
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: formatBytes(attachment.size) })
289
+ ] })
290
+ ] }),
291
+ hasActions ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
292
+ "div",
293
+ {
294
+ className: "eth-inbox-attachments__actions",
295
+ "aria-label": `Actions for ${attachment.name}`,
296
+ children: [
297
+ onPreview ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
298
+ import_core3.IconButton,
299
+ {
300
+ intent: "ghost",
301
+ density: "compact",
302
+ label: `Preview ${attachment.name}`,
303
+ icon: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons.ViewIcon, { size: 16 }),
304
+ onClick: () => onPreview(attachment)
305
+ }
306
+ ) : null,
307
+ onDownload ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
308
+ import_core3.IconButton,
309
+ {
310
+ intent: "ghost",
311
+ density: "compact",
312
+ label: `Download ${attachment.name}`,
313
+ icon: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons.DownloadIcon, { size: 16 }),
314
+ onClick: () => onDownload(attachment)
315
+ }
316
+ ) : null
317
+ ]
318
+ }
319
+ ) : null
320
+ ] }, attachment.id);
321
+ })
322
+ }
323
+ );
324
+ }
325
+ function attachmentTypeLabel(attachment) {
326
+ const extension = attachment.name.split(".").pop();
327
+ if (extension && extension !== attachment.name) return extension.slice(0, 4).toUpperCase();
328
+ const subtype = attachment.mimeType.split("/").pop();
329
+ return subtype ? subtype.slice(0, 4).toUpperCase() : "FILE";
330
+ }
331
+
332
+ // src/components/MessagePreview.tsx
333
+ var import_jsx_runtime5 = require("react/jsx-runtime");
334
+ function MessagePreview({
335
+ message,
336
+ showSubject = true,
337
+ onPreviewAttachment,
338
+ onDownloadAttachment,
339
+ className,
340
+ "aria-label": ariaLabel,
341
+ "aria-labelledby": ariaLabelledBy,
342
+ ...props
343
+ }) {
344
+ const subjectId = React.useId();
345
+ const attachmentsHeadingId = React.useId();
346
+ const visibleSubject = showSubject ? message.subject : void 0;
347
+ const labelledBy = ariaLabel ? ariaLabelledBy : ariaLabelledBy ?? (visibleSubject ? subjectId : void 0);
348
+ const computedAriaLabel = ariaLabel ?? (labelledBy ? void 0 : "Message preview");
349
+ const hasAttachments = Boolean(message.attachments?.length);
350
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
351
+ "article",
352
+ {
353
+ ...props,
354
+ className: ["eth-inbox-message-preview", className].filter(Boolean).join(" "),
355
+ "data-eth-component": "MessagePreview",
356
+ "aria-label": computedAriaLabel,
357
+ "aria-labelledby": labelledBy,
358
+ children: [
359
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("header", { className: "eth-inbox-message-preview__header", children: [
360
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "eth-inbox-message-preview__heading", children: [
361
+ visibleSubject ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { id: subjectId, children: visibleSubject }) : null,
362
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("dl", { className: "eth-inbox-message-preview__recipients", "aria-label": "Message routing", children: [
363
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
364
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: "From" }),
365
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: message.from })
366
+ ] }),
367
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
368
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: "To" }),
369
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: formatRecipients(message.to) })
370
+ ] }),
371
+ message.cc?.length ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
372
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: "Cc" }),
373
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: formatRecipients(message.cc) })
374
+ ] }) : null
375
+ ] })
376
+ ] }),
377
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("time", { dateTime: message.date, children: formatDateTime(message.date) })
378
+ ] }),
379
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "eth-inbox-message-preview__body", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: message.body }) }),
380
+ hasAttachments ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
381
+ "section",
382
+ {
383
+ className: "eth-inbox-message-preview__attachments",
384
+ "aria-labelledby": attachmentsHeadingId,
385
+ children: [
386
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h4", { id: attachmentsHeadingId, children: "Attachments" }),
387
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
388
+ AttachmentList,
389
+ {
390
+ attachments: message.attachments,
391
+ onPreview: onPreviewAttachment,
392
+ onDownload: onDownloadAttachment
393
+ }
394
+ )
395
+ ]
396
+ }
397
+ ) : null
398
+ ]
399
+ }
400
+ );
401
+ }
402
+ function formatRecipients(recipients) {
403
+ return recipients.length ? recipients.join(", ") : "No recipients";
404
+ }
405
+
406
+ // src/components/MessageThread.tsx
407
+ var import_jsx_runtime6 = require("react/jsx-runtime");
408
+ function MessageThread({
409
+ thread,
410
+ summaryRef,
411
+ status,
412
+ statusLabel: statusLabel2,
413
+ actions = [],
414
+ onPreviewAttachment,
415
+ onDownloadAttachment,
416
+ className,
417
+ ...props
418
+ }) {
419
+ const messages = React2.useMemo(
420
+ () => [...thread?.messages ?? []].sort(
421
+ (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
422
+ ),
423
+ [thread?.messages]
424
+ );
425
+ const older = messages.slice(0, Math.max(0, messages.length - 3));
426
+ const recent = messages.slice(Math.max(0, messages.length - 3));
427
+ const participantCount = countParticipants(messages);
428
+ const attachmentCount = messages.reduce(
429
+ (count, message) => count + (message.attachments?.length ?? 0),
430
+ 0
431
+ );
432
+ const latestMessage = messages.at(-1);
433
+ const messageLabel = formatCount(messages.length, "message");
434
+ const participantLabel = formatCount(participantCount, "participant");
435
+ const attachmentLabel = formatCount(attachmentCount, "attachment");
436
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
437
+ "article",
438
+ {
439
+ ...props,
440
+ className: `eth-inbox-thread ${className ?? ""}`,
441
+ "data-eth-component": "MessageThread",
442
+ children: [
443
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("header", { className: "eth-inbox-thread__header", children: [
444
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "eth-inbox-thread__heading", children: [
445
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "eth-inbox-thread__eyebrow", children: "Conversation thread" }),
446
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { children: thread?.subject ?? "Thread" }),
447
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("ul", { className: "eth-inbox-thread__meta", "aria-label": "Thread metadata", children: [
448
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core4.Badge, { severity: "neutral", children: messageLabel }) }),
449
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core4.Badge, { severity: "neutral", children: participantLabel }) }),
450
+ attachmentCount ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core4.Badge, { severity: "info", children: attachmentLabel }) }) : null,
451
+ status ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core4.StatusDot, { status, label: statusLabel2 ?? statusToLabel(status) }) }) : null,
452
+ latestMessage ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { className: "eth-inbox-thread__updated", children: [
453
+ "Last activity",
454
+ " ",
455
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("time", { dateTime: latestMessage.date, children: formatDateTime(latestMessage.date) })
456
+ ] }) : null
457
+ ] })
458
+ ] }),
459
+ actions.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "eth-inbox-thread__actions", role: "group", "aria-label": "Thread actions", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
460
+ import_core4.Button,
461
+ {
462
+ intent: action.intent ?? "secondary",
463
+ density: action.density ?? "compact",
464
+ disabled: action.disabled,
465
+ icon: action.icon,
466
+ onClick: action.onSelect,
467
+ children: action.label
468
+ },
469
+ action.id
470
+ )) }) : null
471
+ ] }),
472
+ summaryRef ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("aside", { className: "eth-inbox-thread__summary", "aria-label": "Thread summary", children: [
473
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "eth-inbox-thread__summary-label", children: "Thread summary" }),
474
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "eth-inbox-thread__summary-body", children: summaryRef })
475
+ ] }) : null,
476
+ !messages.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "eth-inbox-thread__empty", role: "status", children: [
477
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "No messages in this thread" }),
478
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Replies, summaries, and attachment activity will appear here." })
479
+ ] }) : null,
480
+ older.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("details", { className: "eth-inbox-thread__older", children: [
481
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("summary", { children: formatCount(older.length, "older message") }),
482
+ older.map((message) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
483
+ MessagePreview,
484
+ {
485
+ message,
486
+ showSubject: false,
487
+ onPreviewAttachment,
488
+ onDownloadAttachment
489
+ },
490
+ message.id
491
+ ))
492
+ ] }) : null,
493
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "eth-inbox-thread__messages", children: recent.map((message) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
494
+ MessagePreview,
495
+ {
496
+ message,
497
+ showSubject: false,
498
+ onPreviewAttachment,
499
+ onDownloadAttachment
500
+ },
501
+ message.id
502
+ )) })
503
+ ]
504
+ }
505
+ );
506
+ }
507
+ function countParticipants(messages) {
508
+ const participants = /* @__PURE__ */ new Set();
509
+ messages.forEach((message) => {
510
+ participants.add(message.from);
511
+ message.to.forEach((recipient) => participants.add(recipient));
512
+ message.cc?.forEach((recipient) => participants.add(recipient));
513
+ message.bcc?.forEach((recipient) => participants.add(recipient));
514
+ });
515
+ return participants.size;
516
+ }
517
+ function formatCount(value, singular) {
518
+ return `${value} ${value === 1 ? singular : `${singular}s`}`;
519
+ }
520
+ function statusToLabel(status) {
521
+ return status.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
522
+ }
523
+
524
+ // src/components/MessageComposer.tsx
525
+ var React3 = __toESM(require("react"), 1);
526
+ var import_core5 = require("@echothink-ui/core");
527
+ var import_icons2 = require("@echothink-ui/icons");
528
+ var import_jsx_runtime7 = require("react/jsx-runtime");
529
+ function MessageComposer({
530
+ draft = {},
531
+ onChange,
532
+ onSend,
533
+ onDiscard,
534
+ onAttach,
535
+ recipients,
536
+ attachments,
537
+ statusText,
538
+ className,
539
+ ...props
540
+ }) {
541
+ const [localDraft, setLocalDraft] = React3.useState(draft);
542
+ React3.useEffect(() => setLocalDraft(draft), [draft]);
543
+ const update = (next) => {
544
+ setLocalDraft(next);
545
+ onChange?.(next);
546
+ };
547
+ const draftAttachments = localDraft.attachments ?? [];
548
+ const hasAttachmentsRegion = Boolean(attachments || draftAttachments.length || onAttach);
549
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
550
+ "form",
551
+ {
552
+ ...props,
553
+ className: ["eth-inbox-composer", className].filter(Boolean).join(" "),
554
+ "data-eth-component": "MessageComposer",
555
+ onSubmit: (event) => {
556
+ event.preventDefault();
557
+ onSend?.(localDraft);
558
+ },
559
+ children: [
560
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "eth-inbox-composer__fields", children: [
561
+ recipients ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "eth-inbox-composer__address-fields", role: "group", "aria-label": "Recipients", children: [
562
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
563
+ import_core5.FormField,
564
+ {
565
+ className: "eth-inbox-composer__field eth-inbox-composer__field--address",
566
+ label: "To",
567
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
568
+ import_core5.TextInput,
569
+ {
570
+ density: "compact",
571
+ placeholder: "name@company.com",
572
+ value: listToInput(localDraft.to),
573
+ onChange: (event) => update({ ...localDraft, to: inputToList(event.currentTarget.value) })
574
+ }
575
+ )
576
+ }
577
+ ),
578
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
579
+ import_core5.FormField,
580
+ {
581
+ className: "eth-inbox-composer__field eth-inbox-composer__field--address",
582
+ label: "CC",
583
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
584
+ import_core5.TextInput,
585
+ {
586
+ density: "compact",
587
+ placeholder: "Optional",
588
+ value: listToInput(localDraft.cc),
589
+ onChange: (event) => update({ ...localDraft, cc: inputToList(event.currentTarget.value) })
590
+ }
591
+ )
592
+ }
593
+ ),
594
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
595
+ import_core5.FormField,
596
+ {
597
+ className: "eth-inbox-composer__field eth-inbox-composer__field--address",
598
+ label: "BCC",
599
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
600
+ import_core5.TextInput,
601
+ {
602
+ density: "compact",
603
+ placeholder: "Optional",
604
+ value: listToInput(localDraft.bcc),
605
+ onChange: (event) => update({ ...localDraft, bcc: inputToList(event.currentTarget.value) })
606
+ }
607
+ )
608
+ }
609
+ )
610
+ ] }),
611
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
612
+ import_core5.FormField,
613
+ {
614
+ className: "eth-inbox-composer__field eth-inbox-composer__field--subject",
615
+ label: "Subject",
616
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
617
+ import_core5.TextInput,
618
+ {
619
+ density: "compact",
620
+ value: localDraft.subject ?? "",
621
+ onChange: (event) => update({ ...localDraft, subject: event.currentTarget.value })
622
+ }
623
+ )
624
+ }
625
+ ),
626
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
627
+ import_core5.FormField,
628
+ {
629
+ className: "eth-inbox-composer__field eth-inbox-composer__field--body",
630
+ label: "Body",
631
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
632
+ import_core5.Textarea,
633
+ {
634
+ value: localDraft.body ?? "",
635
+ rows: 10,
636
+ onChange: (event) => update({ ...localDraft, body: event.currentTarget.value })
637
+ }
638
+ )
639
+ }
640
+ )
641
+ ] }),
642
+ hasAttachmentsRegion ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: "eth-inbox-composer__attachments", "aria-label": "Draft attachments", children: [
643
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "eth-inbox-composer__attachments-header", children: [
644
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Attachments" }),
645
+ onAttach ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
646
+ import_core5.Button,
647
+ {
648
+ type: "button",
649
+ intent: "tertiary",
650
+ density: "compact",
651
+ icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons2.DocumentIcon, { size: 16 }),
652
+ onClick: onAttach,
653
+ children: "Attach file"
654
+ }
655
+ ) : null
656
+ ] }),
657
+ attachments ?? (draftAttachments.length ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AttachmentList, { attachments: draftAttachments }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "eth-inbox-composer__empty-attachments", children: "No attachments added" }))
658
+ ] }) : null,
659
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "eth-inbox-composer__footer", children: [
660
+ statusText ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "eth-inbox-composer__status", children: statusText }) : null,
661
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "eth-inbox-composer__actions", children: [
662
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core5.Button, { type: "submit", icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons2.MessageIcon, { size: 16 }), children: "Send" }),
663
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core5.Button, { type: "button", intent: "tertiary", onClick: onDiscard, children: "Discard" })
664
+ ] })
665
+ ] })
666
+ ]
667
+ }
668
+ );
669
+ }
670
+
671
+ // src/components/AttachmentPreview.tsx
672
+ var import_jsx_runtime8 = require("react/jsx-runtime");
673
+ function AttachmentPreview({
674
+ attachment,
675
+ children,
676
+ className,
677
+ ...props
678
+ }) {
679
+ const kind = getPreviewKind(attachment);
680
+ const previewSource = attachment?.previewUrl ?? attachment?.src;
681
+ const hasCustomPreview = children !== void 0 && children !== null;
682
+ const label = attachment ? `Attachment preview for ${attachment.name}` : "Attachment preview";
683
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
684
+ "section",
685
+ {
686
+ ...props,
687
+ "aria-label": props["aria-label"] ?? label,
688
+ className: `eth-inbox-attachment-preview ${className ?? ""}`,
689
+ "data-eth-component": "AttachmentPreview",
690
+ children: [
691
+ attachment ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("header", { className: "eth-inbox-attachment-preview__header", children: [
692
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "eth-inbox-attachment-preview__file", children: [
693
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
694
+ "span",
695
+ {
696
+ className: "eth-inbox-attachment-preview__glyph",
697
+ "data-kind": kind,
698
+ "aria-hidden": "true",
699
+ children: kindToken(kind)
700
+ }
701
+ ),
702
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "eth-inbox-attachment-preview__summary", children: [
703
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { title: attachment.name, children: attachment.name }),
704
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
705
+ attachment.mimeType,
706
+ " - ",
707
+ formatBytes(attachment.size)
708
+ ] })
709
+ ] })
710
+ ] }),
711
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "eth-inbox-attachment-preview__state", children: previewStateLabel(kind) })
712
+ ] }) : null,
713
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
714
+ "div",
715
+ {
716
+ className: `eth-inbox-attachment-preview__body eth-inbox-attachment-preview__body--${kind}`,
717
+ children: hasCustomPreview ? children : renderDefaultPreview(attachment, kind, previewSource)
718
+ }
719
+ )
720
+ ]
721
+ }
722
+ );
723
+ }
724
+ function getPreviewKind(attachment) {
725
+ if (!attachment) return "empty";
726
+ const mimeType = attachment.mimeType.toLowerCase();
727
+ const name = attachment.name.toLowerCase();
728
+ if (mimeType === "application/pdf" || name.endsWith(".pdf")) return "pdf";
729
+ if (mimeType.startsWith("image/")) return "image";
730
+ if (mimeType.includes("spreadsheet") || mimeType.includes("csv") || name.endsWith(".csv") || name.endsWith(".xls") || name.endsWith(".xlsx")) {
731
+ return "spreadsheet";
732
+ }
733
+ if (mimeType.startsWith("text/") || ["application/json", "application/xml", "application/yaml"].includes(mimeType) || name.endsWith(".md")) {
734
+ return "text";
735
+ }
736
+ if (mimeType.includes("zip") || mimeType.includes("compressed") || name.endsWith(".zip") || name.endsWith(".gz")) {
737
+ return "archive";
738
+ }
739
+ return "file";
740
+ }
741
+ function kindToken(kind) {
742
+ if (kind === "pdf") return "PDF";
743
+ if (kind === "image") return "IMG";
744
+ if (kind === "text") return "TXT";
745
+ if (kind === "spreadsheet") return "CSV";
746
+ if (kind === "archive") return "ZIP";
747
+ return "FILE";
748
+ }
749
+ function previewStateLabel(kind) {
750
+ if (kind === "archive" || kind === "file") return "Preview unavailable";
751
+ return "Inline preview";
752
+ }
753
+ function renderDefaultPreview(attachment, kind, previewSource) {
754
+ if (!attachment) {
755
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "eth-inbox-attachment-preview__empty", children: [
756
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: "No attachment selected" }),
757
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "PDF, image, text, and spreadsheet files can be previewed inline." })
758
+ ] });
759
+ }
760
+ if (kind === "image") {
761
+ return previewSource ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
762
+ "img",
763
+ {
764
+ className: "eth-inbox-attachment-preview__image",
765
+ src: previewSource,
766
+ alt: `${attachment.name} preview`
767
+ }
768
+ ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
769
+ "div",
770
+ {
771
+ className: "eth-inbox-attachment-preview__image-frame",
772
+ role: "img",
773
+ "aria-label": `${attachment.name} image preview`,
774
+ children: [
775
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {}),
776
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {})
777
+ ]
778
+ }
779
+ );
780
+ }
781
+ if (kind === "text") {
782
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
783
+ "div",
784
+ {
785
+ className: "eth-inbox-attachment-preview__text",
786
+ role: "img",
787
+ "aria-label": `${attachment.name} text preview`,
788
+ children: Array.from({ length: 9 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {}, index))
789
+ }
790
+ );
791
+ }
792
+ if (kind === "spreadsheet") {
793
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
794
+ "div",
795
+ {
796
+ className: "eth-inbox-attachment-preview__sheet",
797
+ role: "img",
798
+ "aria-label": `${attachment.name} spreadsheet preview`,
799
+ children: Array.from({ length: 20 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {}, index))
800
+ }
801
+ );
802
+ }
803
+ if (kind === "pdf") {
804
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
805
+ "div",
806
+ {
807
+ className: "eth-inbox-attachment-preview__document",
808
+ role: "img",
809
+ "aria-label": `${attachment.name} PDF preview`,
810
+ children: [
811
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "eth-inbox-attachment-preview__document-bar", children: [
812
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: attachment.mimeType }),
813
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Page 1" })
814
+ ] }),
815
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "eth-inbox-attachment-preview__page", children: [
816
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: attachment.name.replace(/\.[^.]+$/, "") || attachment.name }),
817
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {}),
818
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {}),
819
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {}),
820
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {}),
821
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {})
822
+ ] })
823
+ ]
824
+ }
825
+ );
826
+ }
827
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "eth-inbox-attachment-preview__empty", children: [
828
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: "Preview unavailable" }),
829
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
830
+ attachment.mimeType,
831
+ " files are kept as attachments for download or external review."
832
+ ] })
833
+ ] });
834
+ }
835
+
836
+ // src/components/RecipientPicker.tsx
837
+ var React4 = __toESM(require("react"), 1);
838
+ var import_core6 = require("@echothink-ui/core");
839
+ var import_jsx_runtime9 = require("react/jsx-runtime");
840
+ function RecipientPicker({
841
+ value = [],
842
+ onChange,
843
+ onSearch,
844
+ suggestions = [],
845
+ defaultSuggestionsOpen = false,
846
+ className,
847
+ ...props
848
+ }) {
849
+ const listboxId = React4.useId().replace(/:/g, "");
850
+ const [query, setQuery] = React4.useState("");
851
+ const [manualValue, setManualValue] = React4.useState("");
852
+ const [suggestionsOpen, setSuggestionsOpen] = React4.useState(defaultSuggestionsOpen);
853
+ const normalizedQuery = query.trim().toLocaleLowerCase();
854
+ const visibleSuggestions = normalizedQuery ? suggestions.filter(
855
+ (suggestion) => [suggestion.label, suggestion.email].some(
856
+ (field) => field.toLocaleLowerCase().includes(normalizedQuery)
857
+ )
858
+ ) : suggestions;
859
+ const showSuggestions = suggestionsOpen && (visibleSuggestions.length > 0 || Boolean(query));
860
+ const add = (email) => {
861
+ const normalizedEmail = email.trim();
862
+ if (!normalizedEmail || value.includes(normalizedEmail)) return false;
863
+ onChange?.([...value, normalizedEmail]);
864
+ setManualValue("");
865
+ setQuery("");
866
+ return true;
867
+ };
868
+ const updateQuery = (nextQuery) => {
869
+ setQuery(nextQuery);
870
+ onSearch?.(nextQuery);
871
+ setSuggestionsOpen(Boolean(nextQuery || suggestions.length));
872
+ };
873
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
874
+ "div",
875
+ {
876
+ ...props,
877
+ className: `eth-inbox-recipient-picker ${className ?? ""}`,
878
+ "data-eth-component": "RecipientPicker",
879
+ onBlur: (event) => {
880
+ props.onBlur?.(event);
881
+ if (!event.currentTarget.contains(event.relatedTarget)) {
882
+ setSuggestionsOpen(false);
883
+ }
884
+ },
885
+ onKeyDown: (event) => {
886
+ props.onKeyDown?.(event);
887
+ if (!event.defaultPrevented && event.key === "Escape") {
888
+ setSuggestionsOpen(false);
889
+ }
890
+ },
891
+ children: [
892
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "eth-inbox-recipient-picker__selected", "aria-label": "Selected recipients", children: [
893
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "eth-inbox-recipient-picker__label", children: "To" }),
894
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "eth-inbox-recipient-picker__chips", children: value.length ? value.map((email) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
895
+ import_core6.Tag,
896
+ {
897
+ removable: true,
898
+ onRemove: () => onChange?.(value.filter((item) => item !== email)),
899
+ children: email
900
+ },
901
+ email
902
+ )) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "eth-inbox-recipient-picker__placeholder", children: "No recipients selected" }) })
903
+ ] }),
904
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
905
+ import_core6.SearchInput,
906
+ {
907
+ "aria-controls": showSuggestions ? listboxId : void 0,
908
+ "aria-expanded": showSuggestions,
909
+ "aria-haspopup": "listbox",
910
+ className: "eth-inbox-recipient-picker__search",
911
+ labelText: "Search recipients",
912
+ value: query,
913
+ placeholder: "Search recipients",
914
+ onFocus: () => setSuggestionsOpen(Boolean(suggestions.length)),
915
+ onChange: (event) => updateQuery(event.currentTarget.value),
916
+ onClear: () => {
917
+ updateQuery("");
918
+ setSuggestionsOpen(false);
919
+ }
920
+ }
921
+ ),
922
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "eth-inbox-recipient-picker__manual", children: [
923
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
924
+ import_core6.TextInput,
925
+ {
926
+ className: "eth-inbox-recipient-picker__manual-input",
927
+ density: "compact",
928
+ hideLabel: true,
929
+ labelText: "Recipient email",
930
+ type: "email",
931
+ value: manualValue,
932
+ placeholder: "name@company.com",
933
+ onChange: (event) => setManualValue(event.currentTarget.value),
934
+ onKeyDown: (event) => {
935
+ if (event.key === "Enter") {
936
+ event.preventDefault();
937
+ add(manualValue);
938
+ }
939
+ }
940
+ }
941
+ ),
942
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
943
+ import_core6.Button,
944
+ {
945
+ density: "compact",
946
+ disabled: !manualValue.trim(),
947
+ intent: "primary",
948
+ onClick: () => add(manualValue),
949
+ children: "Add recipient"
950
+ }
951
+ )
952
+ ] }),
953
+ showSuggestions ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
954
+ "div",
955
+ {
956
+ className: "eth-inbox-recipient-picker__suggestions",
957
+ id: listboxId,
958
+ role: "listbox",
959
+ "aria-label": "Recipient suggestions",
960
+ "aria-multiselectable": true,
961
+ children: [
962
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "eth-inbox-recipient-picker__suggestions-header", children: [
963
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Suggested recipients" }),
964
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("strong", { children: [
965
+ visibleSuggestions.length,
966
+ " result",
967
+ visibleSuggestions.length === 1 ? "" : "s"
968
+ ] })
969
+ ] }),
970
+ visibleSuggestions.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: "eth-inbox-recipient-picker__suggestions-list", children: visibleSuggestions.map((suggestion) => {
971
+ const isSelected = value.includes(suggestion.email);
972
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
973
+ "button",
974
+ {
975
+ type: "button",
976
+ role: "option",
977
+ "aria-selected": isSelected,
978
+ "aria-disabled": isSelected ? true : void 0,
979
+ onClick: () => add(suggestion.email),
980
+ children: [
981
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "eth-inbox-recipient-picker__suggestion-copy", children: [
982
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: suggestion.label }),
983
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: suggestion.email })
984
+ ] }),
985
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "eth-inbox-recipient-picker__suggestion-status", children: isSelected ? "Selected" : "Add" })
986
+ ]
987
+ }
988
+ ) }, suggestion.id);
989
+ }) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "eth-inbox-recipient-picker__empty", children: "No matching recipients" })
990
+ ]
991
+ }
992
+ ) : null
993
+ ]
994
+ }
995
+ );
996
+ }
997
+
998
+ // src/components/LabelManager.tsx
999
+ var React5 = __toESM(require("react"), 1);
1000
+ var import_core7 = require("@echothink-ui/core");
1001
+ var import_icons3 = require("@echothink-ui/icons");
1002
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1003
+ function LabelManager({
1004
+ labels = [],
1005
+ onCreate,
1006
+ onRename,
1007
+ onDelete,
1008
+ className,
1009
+ ...props
1010
+ }) {
1011
+ const [newLabel, setNewLabel] = React5.useState("");
1012
+ const [edits, setEdits] = React5.useState({});
1013
+ const trackedLabels = labels.filter((label) => typeof label.count === "number");
1014
+ const trackedMessageCount = trackedLabels.reduce((total, label) => total + (label.count ?? 0), 0);
1015
+ const labelSummary = `${labels.length.toLocaleString()} ${labels.length === 1 ? "label" : "labels"}`;
1016
+ const subtitle = labels.length ? trackedLabels.length ? `${labelSummary} \xB7 ${trackedMessageCount.toLocaleString()} tracked messages` : `${labelSummary} configured for mailbox categories and automation tags.` : "Create categories and automation tags for mailbox workflows.";
1017
+ const submitNewLabel = (event) => {
1018
+ event.preventDefault();
1019
+ const nextLabel = newLabel.trim();
1020
+ if (!nextLabel || !onCreate) return;
1021
+ onCreate(nextLabel);
1022
+ setNewLabel("");
1023
+ };
1024
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1025
+ import_core7.Panel,
1026
+ {
1027
+ ...props,
1028
+ className: `eth-inbox-label-manager ${className ?? ""}`,
1029
+ title: "Labels",
1030
+ subtitle,
1031
+ "data-eth-component": "LabelManager",
1032
+ children: [
1033
+ labels.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "eth-inbox-label-manager__list", role: "table", "aria-label": "Managed labels", children: [
1034
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "eth-inbox-label-manager__table-head", role: "row", children: [
1035
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "columnheader", children: "Label" }),
1036
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "columnheader", children: "Messages" }),
1037
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "columnheader", children: "Actions" })
1038
+ ] }),
1039
+ labels.map((label) => {
1040
+ const draft = edits[label.id] ?? label.label;
1041
+ const trimmedDraft = draft.trim();
1042
+ const countLabel = typeof label.count === "number" ? `${label.count.toLocaleString()} ${label.count === 1 ? "message" : "messages"}` : "Message count not tracked";
1043
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "eth-inbox-label-manager__row", role: "row", children: [
1044
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "eth-inbox-label-manager__name-cell", role: "cell", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1045
+ import_core7.TextInput,
1046
+ {
1047
+ "aria-label": `Label name for ${label.label}`,
1048
+ density: "compact",
1049
+ placeholder: "Label name",
1050
+ value: draft,
1051
+ onChange: (event) => setEdits((current) => ({
1052
+ ...current,
1053
+ [label.id]: event.currentTarget.value
1054
+ }))
1055
+ }
1056
+ ) }),
1057
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1058
+ "div",
1059
+ {
1060
+ className: "eth-inbox-label-manager__count-cell",
1061
+ role: "cell",
1062
+ "aria-label": countLabel,
1063
+ children: typeof label.count === "number" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1064
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: label.count.toLocaleString() }),
1065
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: label.count === 1 ? "message" : "messages" })
1066
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "eth-inbox-label-manager__count-muted", children: "Not tracked" })
1067
+ }
1068
+ ),
1069
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "eth-inbox-label-manager__actions", role: "cell", children: [
1070
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1071
+ import_core7.Button,
1072
+ {
1073
+ density: "compact",
1074
+ disabled: !onRename || !trimmedDraft,
1075
+ icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons3.EditIcon, { size: 16 }),
1076
+ intent: "secondary",
1077
+ onClick: () => {
1078
+ if (trimmedDraft) onRename?.(label.id, trimmedDraft);
1079
+ },
1080
+ children: "Rename"
1081
+ }
1082
+ ),
1083
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1084
+ import_core7.Button,
1085
+ {
1086
+ density: "compact",
1087
+ disabled: !onDelete,
1088
+ intent: "danger",
1089
+ onClick: () => onDelete?.(label.id),
1090
+ children: "Delete"
1091
+ }
1092
+ )
1093
+ ] })
1094
+ ] }, label.id);
1095
+ })
1096
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "eth-inbox-label-manager__empty", children: "No labels configured. Create a label to route mailbox views and automation rules." }),
1097
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { className: "eth-inbox-label-manager__create", onSubmit: submitNewLabel, children: [
1098
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1099
+ import_core7.FormField,
1100
+ {
1101
+ label: "New label",
1102
+ helperText: "Use concise names for categories, filters, and automation rules.",
1103
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1104
+ import_core7.TextInput,
1105
+ {
1106
+ density: "compact",
1107
+ placeholder: "e.g. renewal-risk",
1108
+ value: newLabel,
1109
+ onChange: (event) => setNewLabel(event.currentTarget.value)
1110
+ }
1111
+ )
1112
+ }
1113
+ ),
1114
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1115
+ import_core7.Button,
1116
+ {
1117
+ disabled: !onCreate || !newLabel.trim(),
1118
+ icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons3.PlusIcon, { size: 16 }),
1119
+ type: "submit",
1120
+ children: "Create"
1121
+ }
1122
+ )
1123
+ ] })
1124
+ ]
1125
+ }
1126
+ );
1127
+ }
1128
+
1129
+ // src/components/MessageSearch.tsx
1130
+ var import_core8 = require("@echothink-ui/core");
1131
+ var import_icons4 = require("@echothink-ui/icons");
1132
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1133
+ function MessageSearch({
1134
+ value = "",
1135
+ onChange,
1136
+ placeholder = "Search messages",
1137
+ resultCount,
1138
+ activeResultIndex = 0,
1139
+ onPreviousResult,
1140
+ onNextResult,
1141
+ className,
1142
+ role,
1143
+ "aria-label": ariaLabel,
1144
+ ...props
1145
+ }) {
1146
+ const hasResultCount = typeof resultCount === "number";
1147
+ const normalizedResultCount = hasResultCount && Number.isFinite(resultCount) ? Math.max(0, Math.trunc(resultCount)) : 0;
1148
+ const normalizedResultIndex = Number.isFinite(activeResultIndex) ? Math.trunc(activeResultIndex) : 0;
1149
+ const hasResults = normalizedResultCount > 0;
1150
+ const currentResult = hasResults ? Math.min(Math.max(normalizedResultIndex, 0), normalizedResultCount - 1) + 1 : 0;
1151
+ const canGoPrevious = hasResults && currentResult > 1 && Boolean(onPreviousResult);
1152
+ const canGoNext = hasResults && currentResult < normalizedResultCount && Boolean(onNextResult);
1153
+ const resultNoun = normalizedResultCount === 1 ? "result" : "results";
1154
+ const resultLabel = hasResults ? `${currentResult} of ${normalizedResultCount} ${resultNoun}` : "No results";
1155
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1156
+ "div",
1157
+ {
1158
+ ...props,
1159
+ className: ["eth-inbox-search", className].filter(Boolean).join(" "),
1160
+ "data-eth-component": "MessageSearch",
1161
+ role: role ?? "search",
1162
+ "aria-label": ariaLabel ?? "Message search",
1163
+ children: [
1164
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "eth-inbox-search__input", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1165
+ import_core8.SearchInput,
1166
+ {
1167
+ value,
1168
+ placeholder,
1169
+ labelText: placeholder,
1170
+ onChange: (event) => onChange?.(event.currentTarget.value),
1171
+ onClear: () => onChange?.(""),
1172
+ className: "eth-inbox-search__control"
1173
+ }
1174
+ ) }),
1175
+ hasResultCount ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "eth-inbox-search__results", children: [
1176
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "eth-inbox-search__count", "aria-live": "polite", children: resultLabel }),
1177
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1178
+ "div",
1179
+ {
1180
+ className: "eth-inbox-search__nav",
1181
+ role: "group",
1182
+ "aria-label": "Search result navigation",
1183
+ children: [
1184
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1185
+ import_core8.IconButton,
1186
+ {
1187
+ className: "eth-inbox-search__nav-button eth-inbox-search__nav-button--previous",
1188
+ density: "compact",
1189
+ intent: "ghost",
1190
+ label: "Previous result",
1191
+ icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_icons4.ChevronRightIcon, { size: 16 }),
1192
+ disabled: !canGoPrevious,
1193
+ onClick: onPreviousResult
1194
+ }
1195
+ ),
1196
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1197
+ import_core8.IconButton,
1198
+ {
1199
+ className: "eth-inbox-search__nav-button",
1200
+ density: "compact",
1201
+ intent: "ghost",
1202
+ label: "Next result",
1203
+ icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_icons4.ChevronRightIcon, { size: 16 }),
1204
+ disabled: !canGoNext,
1205
+ onClick: onNextResult
1206
+ }
1207
+ )
1208
+ ]
1209
+ }
1210
+ )
1211
+ ] }) : null
1212
+ ]
1213
+ }
1214
+ );
1215
+ }
1216
+
1217
+ // src/components/MessageFilterBar.tsx
1218
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1219
+ var filterKindLabels = {
1220
+ priority: "Priority",
1221
+ sender: "Sender",
1222
+ date: "Date",
1223
+ label: "Label",
1224
+ unread: "Read",
1225
+ status: "Status"
1226
+ };
1227
+ function MessageFilterBar({
1228
+ filters = [],
1229
+ onToggle,
1230
+ className,
1231
+ "aria-label": ariaLabel = "Message filters",
1232
+ ...props
1233
+ }) {
1234
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1235
+ "div",
1236
+ {
1237
+ ...props,
1238
+ className: `eth-inbox-filter-bar ${className ?? ""}`,
1239
+ "data-eth-component": "MessageFilterBar",
1240
+ role: "toolbar",
1241
+ "aria-label": ariaLabel,
1242
+ children: filters.map((filter) => {
1243
+ const kindLabel = filter.kind ? filterKindLabels[filter.kind] : void 0;
1244
+ const accessibleLabel = kindLabel ? `${kindLabel}: ${filter.label}` : filter.label;
1245
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1246
+ "button",
1247
+ {
1248
+ type: "button",
1249
+ className: `eth-inbox-filter-bar__chip ${filter.active ? "eth-inbox-filter-bar__chip--active" : ""} ${filter.disabled ? "eth-inbox-filter-bar__chip--disabled" : ""}`,
1250
+ "aria-label": accessibleLabel,
1251
+ "aria-pressed": Boolean(filter.active),
1252
+ "data-filter-kind": filter.kind,
1253
+ disabled: filter.disabled,
1254
+ onClick: () => onToggle?.(filter.id, !Boolean(filter.active)),
1255
+ children: [
1256
+ kindLabel ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "eth-inbox-filter-bar__kind", "aria-hidden": "true", children: kindLabel }) : null,
1257
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "eth-inbox-filter-bar__label", children: filter.label })
1258
+ ]
1259
+ },
1260
+ filter.id
1261
+ );
1262
+ })
1263
+ }
1264
+ );
1265
+ }
1266
+
1267
+ // src/components/PriorityInboxView.tsx
1268
+ var React6 = __toESM(require("react"), 1);
1269
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1270
+ function PriorityInboxView({
1271
+ groups = [],
1272
+ selectedThreadId,
1273
+ onSelect,
1274
+ className,
1275
+ ...props
1276
+ }) {
1277
+ const hasGroups = groups.length > 0;
1278
+ const idBase = React6.useId();
1279
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1280
+ "div",
1281
+ {
1282
+ ...props,
1283
+ className: `eth-inbox-priority ${className ?? ""}`,
1284
+ "data-eth-component": "PriorityInboxView",
1285
+ children: hasGroups ? groups.map((group, index) => {
1286
+ const headingId = `${idBase}-group-${index}-heading`;
1287
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1288
+ "section",
1289
+ {
1290
+ className: "eth-inbox-priority__group",
1291
+ "aria-labelledby": headingId,
1292
+ children: [
1293
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("header", { className: "eth-inbox-priority__group-header", children: [
1294
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "eth-inbox-priority__heading", children: [
1295
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { id: headingId, children: group.title }),
1296
+ group.description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "eth-inbox-priority__description", children: group.description }) : null
1297
+ ] }),
1298
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "eth-inbox-priority__count", children: formatThreadCount(group.threads.length) })
1299
+ ] }),
1300
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1301
+ MessageList,
1302
+ {
1303
+ threads: group.threads,
1304
+ selectedThreadId,
1305
+ onSelect
1306
+ }
1307
+ )
1308
+ ]
1309
+ },
1310
+ group.id
1311
+ );
1312
+ }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "eth-inbox-priority__empty", role: "status", "aria-label": "No priority threads", children: "No priority threads" })
1313
+ }
1314
+ );
1315
+ }
1316
+ function formatThreadCount(count) {
1317
+ return `${count} ${count === 1 ? "thread" : "threads"}`;
1318
+ }
1319
+
1320
+ // src/components/EmailAutomationRulePanel.tsx
1321
+ var import_core9 = require("@echothink-ui/core");
1322
+ var import_icons5 = require("@echothink-ui/icons");
1323
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1324
+ function EmailAutomationRulePanel({
1325
+ rules = [],
1326
+ onToggle,
1327
+ onEdit,
1328
+ className,
1329
+ ...props
1330
+ }) {
1331
+ const enabledCount = rules.reduce((count, rule) => count + (rule.enabled ? 1 : 0), 0);
1332
+ const ruleCountLabel = `${rules.length} automation ${rules.length === 1 ? "rule" : "rules"}`;
1333
+ const subtitle = rules.length ? `${enabledCount} of ${ruleCountLabel} enabled` : "Create routing, drafting, and mailbox automation rules.";
1334
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1335
+ import_core9.Panel,
1336
+ {
1337
+ ...props,
1338
+ className: `eth-inbox-rules ${className ?? ""}`,
1339
+ title: "Automation rules",
1340
+ subtitle,
1341
+ "data-eth-component": "EmailAutomationRulePanel",
1342
+ children: rules.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "eth-inbox-rules__list", role: "list", children: rules.map((rule) => {
1343
+ const headingId = `eth-inbox-rule-${rule.id.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
1344
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1345
+ "article",
1346
+ {
1347
+ "aria-labelledby": headingId,
1348
+ className: `eth-inbox-rules__item ${rule.enabled ? "eth-inbox-rules__item--enabled" : "eth-inbox-rules__item--paused"}`,
1349
+ role: "listitem",
1350
+ children: [
1351
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "eth-inbox-rules__content", children: [
1352
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("header", { className: "eth-inbox-rules__item-header", children: [
1353
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h4", { id: headingId, children: rule.name }),
1354
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_core9.Badge, { severity: rule.enabled ? "success" : "neutral", children: rule.enabled ? "Enabled" : "Paused" })
1355
+ ] }),
1356
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("dl", { className: "eth-inbox-rules__definition", children: [
1357
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
1358
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: "Trigger" }),
1359
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: rule.conditions })
1360
+ ] }),
1361
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
1362
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: "Action" }),
1363
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: rule.actions })
1364
+ ] })
1365
+ ] })
1366
+ ] }),
1367
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "eth-inbox-rules__controls", children: [
1368
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1369
+ import_core9.Toggle,
1370
+ {
1371
+ checked: rule.enabled,
1372
+ className: "eth-inbox-rules__toggle",
1373
+ disabled: !onToggle,
1374
+ hideLabel: true,
1375
+ label: `Automation status for ${rule.name}`,
1376
+ offLabel: "Paused",
1377
+ onChange: (event) => onToggle?.(rule.id, event.currentTarget.checked),
1378
+ onLabel: "Enabled"
1379
+ }
1380
+ ),
1381
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1382
+ import_core9.Button,
1383
+ {
1384
+ "aria-label": `Edit ${rule.name}`,
1385
+ density: "compact",
1386
+ disabled: !onEdit,
1387
+ icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_icons5.EditIcon, { size: 16 }),
1388
+ intent: "secondary",
1389
+ onClick: () => onEdit?.(rule.id),
1390
+ children: "Edit"
1391
+ }
1392
+ )
1393
+ ] })
1394
+ ]
1395
+ },
1396
+ rule.id
1397
+ );
1398
+ }) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "eth-inbox-rules__empty", children: "No automation rules configured." })
1399
+ }
1400
+ );
1401
+ }
1402
+
1403
+ // src/components/AgentDraftReviewPanel.tsx
1404
+ var import_core10 = require("@echothink-ui/core");
1405
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1406
+ function formatDraftTimestamp(value) {
1407
+ if (!value) return null;
1408
+ const date = new Date(value);
1409
+ if (Number.isNaN(date.getTime())) return value;
1410
+ return new Intl.DateTimeFormat("en-US", {
1411
+ month: "short",
1412
+ day: "numeric",
1413
+ hour: "numeric",
1414
+ minute: "2-digit"
1415
+ }).format(date);
1416
+ }
1417
+ function AgentDraftReviewPanel({
1418
+ draft,
1419
+ onApprove,
1420
+ onEdit,
1421
+ onReject,
1422
+ className,
1423
+ ...props
1424
+ }) {
1425
+ const formattedDate = formatDraftTimestamp(draft?.date);
1426
+ const hasDraft = Boolean(draft);
1427
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1428
+ import_core10.Panel,
1429
+ {
1430
+ ...props,
1431
+ className: `eth-inbox-agent-draft ${className ?? ""}`,
1432
+ title: "Agent draft review",
1433
+ subtitle: "Validate the generated response, source evidence, and approval direction before sending.",
1434
+ "data-eth-component": "AgentDraftReviewPanel",
1435
+ children: [
1436
+ draft ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "eth-inbox-agent-draft__content", children: [
1437
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "eth-inbox-agent-draft__status", children: [
1438
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core10.Badge, { severity: "info", children: draft.statusLabel ?? "Ready for review" }),
1439
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Generated from inbound thread and policy context" }),
1440
+ formattedDate ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("time", { dateTime: draft.date, children: [
1441
+ "Updated ",
1442
+ formattedDate
1443
+ ] }) : null
1444
+ ] }),
1445
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("dl", { className: "eth-inbox-agent-draft__meta", children: [
1446
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
1447
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dt", { children: "Subject" }),
1448
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dd", { children: draft.subject ?? "No subject" })
1449
+ ] }),
1450
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
1451
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dt", { children: "Requested by" }),
1452
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dd", { children: draft.from || "Unknown sender" })
1453
+ ] }),
1454
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
1455
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dt", { children: "Recipients" }),
1456
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dd", { children: draft.to?.length ? draft.to.join(", ") : "No recipients" })
1457
+ ] })
1458
+ ] }),
1459
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("section", { className: "eth-inbox-agent-draft__section", "aria-label": "Proposed response", children: [
1460
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "eth-inbox-agent-draft__section-header", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Proposed response" }) }),
1461
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "eth-inbox-agent-draft__body", children: draft.body })
1462
+ ] }),
1463
+ draft.rationale ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("section", { className: "eth-inbox-agent-draft__rationale", "aria-label": "Agent rationale", children: [
1464
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Agent rationale" }),
1465
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "eth-inbox-agent-draft__rationale-body", children: draft.rationale })
1466
+ ] }) : null,
1467
+ draft.evidence?.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("section", { className: "eth-inbox-agent-draft__evidence", "aria-label": "Source evidence", children: [
1468
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Source evidence" }),
1469
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "eth-inbox-agent-draft__evidence-list", children: draft.evidence.map(
1470
+ (item) => item.href ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href: item.href, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core10.Tag, { children: item.label }) }, item.id) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core10.Tag, { children: item.label }, item.id)
1471
+ ) })
1472
+ ] }) : null
1473
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "eth-inbox-agent-draft__empty", role: "status", children: [
1474
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "No draft selected" }),
1475
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: "Select an agent-generated response to review its evidence and approval options." })
1476
+ ] }),
1477
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "eth-inbox-agent-draft__actions", children: [
1478
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core10.Button, { type: "button", disabled: !hasDraft, onClick: onApprove, children: "Approve draft" }),
1479
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core10.Button, { type: "button", intent: "secondary", disabled: !hasDraft, onClick: onEdit, children: "Edit draft" }),
1480
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core10.Button, { type: "button", intent: "danger", disabled: !hasDraft, onClick: onReject, children: "Reject draft" })
1481
+ ] })
1482
+ ]
1483
+ }
1484
+ );
1485
+ }
1486
+
1487
+ // src/components/ApprovalToSendPanel.tsx
1488
+ var React7 = __toESM(require("react"), 1);
1489
+ var import_core11 = require("@echothink-ui/core");
1490
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1491
+ function ApprovalToSendPanel({
1492
+ draft,
1493
+ recipients = [],
1494
+ riskLevel = "low",
1495
+ policyRef,
1496
+ onApprove,
1497
+ onReject,
1498
+ className,
1499
+ ...props
1500
+ }) {
1501
+ const [reason, setReason] = React7.useState("");
1502
+ const toRecipients = recipients.length ? recipients : draft?.to ?? [];
1503
+ const ccRecipients = draft?.cc ?? [];
1504
+ const bccRecipients = draft?.bcc ?? [];
1505
+ const subject = draft?.subject?.trim() || "No subject";
1506
+ const body = draft?.body?.trim() || "No message body provided.";
1507
+ const riskSeverity = riskLevel === "critical" || riskLevel === "high" ? "danger" : riskLevel === "medium" ? "warning" : "info";
1508
+ const riskLabel = `${riskLevel.charAt(0).toUpperCase()}${riskLevel.slice(1)} risk`;
1509
+ const recipientCount = recipients.length || toRecipients.length + ccRecipients.length + bccRecipients.length;
1510
+ const recipientKind = recipients.length ? "external recipient" : "recipient";
1511
+ const recipientSummary = recipientCount === 1 ? `1 ${recipientKind}` : `${recipientCount || "No"} ${recipientKind}s`;
1512
+ const formatRecipients2 = (values) => values.length ? values.join(", ") : "Not specified";
1513
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1514
+ import_core11.Panel,
1515
+ {
1516
+ ...props,
1517
+ className: `eth-inbox-send-approval eth-inbox-send-approval--${riskLevel} ${className ?? ""}`,
1518
+ title: "Approval required",
1519
+ subtitle: "Review this outbound message before it is sent.",
1520
+ "data-eth-component": "ApprovalToSendPanel",
1521
+ children: [
1522
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "eth-inbox-send-approval__status", children: [
1523
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "eth-inbox-send-approval__summary", children: [
1524
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_core11.Badge, { severity: riskSeverity, children: riskLabel }),
1525
+ policyRef ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "eth-inbox-send-approval__policy", children: policyRef }) : null
1526
+ ] }),
1527
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "eth-inbox-send-approval__state", children: "Awaiting approval" })
1528
+ ] }),
1529
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1530
+ "section",
1531
+ {
1532
+ className: "eth-inbox-send-approval__message",
1533
+ "aria-label": "Outbound message for approval",
1534
+ children: [
1535
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("header", { className: "eth-inbox-send-approval__message-header", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
1536
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h4", { children: "Outbound message" }),
1537
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: recipientSummary })
1538
+ ] }) }),
1539
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("dl", { className: "eth-inbox-send-approval__meta", children: [
1540
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
1541
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dt", { children: "To" }),
1542
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dd", { children: formatRecipients2(toRecipients) })
1543
+ ] }),
1544
+ ccRecipients.length ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
1545
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dt", { children: "Cc" }),
1546
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dd", { children: formatRecipients2(ccRecipients) })
1547
+ ] }) : null,
1548
+ bccRecipients.length ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
1549
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dt", { children: "Bcc" }),
1550
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dd", { children: formatRecipients2(bccRecipients) })
1551
+ ] }) : null,
1552
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
1553
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dt", { children: "Subject" }),
1554
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dd", { children: subject })
1555
+ ] })
1556
+ ] }),
1557
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "eth-inbox-send-approval__message-body", children: [
1558
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Message body" }),
1559
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: body })
1560
+ ] })
1561
+ ]
1562
+ }
1563
+ ),
1564
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "eth-inbox-send-approval__decision", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1565
+ import_core11.Textarea,
1566
+ {
1567
+ value: reason,
1568
+ labelText: "Decision note",
1569
+ helperText: "Optional for approval. Include the policy reason when rejecting.",
1570
+ placeholder: "Add an approval or rejection reason",
1571
+ onChange: (event) => setReason(event.currentTarget.value)
1572
+ }
1573
+ ) }),
1574
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "eth-inbox-send-approval__actions", children: [
1575
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_core11.Button, { intent: "danger", onClick: () => onReject?.(reason || void 0), children: "Reject" }),
1576
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_core11.Button, { onClick: () => onApprove?.(reason || void 0), children: "Approve send" })
1577
+ ] })
1578
+ ]
1579
+ }
1580
+ );
1581
+ }
1582
+
1583
+ // src/components/ThreadSummaryPanel.tsx
1584
+ var import_core12 = require("@echothink-ui/core");
1585
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1586
+ function ThreadSummaryPanel({
1587
+ summary,
1588
+ className,
1589
+ ...props
1590
+ }) {
1591
+ const citations = summary?.citations ?? [];
1592
+ const citationCount = citations.length;
1593
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1594
+ import_core12.Panel,
1595
+ {
1596
+ ...props,
1597
+ className: `eth-inbox-thread-summary ${className ?? ""}`,
1598
+ title: "Thread summary",
1599
+ subtitle: "Agent-generated recap with source references.",
1600
+ "data-eth-component": "ThreadSummaryPanel",
1601
+ children: summary ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "eth-inbox-thread-summary__content", children: [
1602
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1603
+ "div",
1604
+ {
1605
+ className: "eth-inbox-thread-summary__metadata",
1606
+ role: "group",
1607
+ "aria-label": "Summary metadata",
1608
+ children: [
1609
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_core12.Badge, { severity: "info", children: "Agent generated" }),
1610
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: formatCitationCount(citationCount) })
1611
+ ]
1612
+ }
1613
+ ),
1614
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { className: "eth-inbox-thread-summary__summary", "aria-label": "Generated summary", children: [
1615
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "eth-inbox-thread-summary__section-label", children: "Summary" }),
1616
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "eth-inbox-thread-summary__summary-body", children: summary.text })
1617
+ ] }),
1618
+ citations.length ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { className: "eth-inbox-thread-summary__sources", "aria-label": "Source citations", children: [
1619
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "eth-inbox-thread-summary__section-label", children: "Source citations" }),
1620
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("ul", { className: "eth-inbox-thread-summary__source-list", children: citations.map((citation) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("li", { className: "eth-inbox-thread-summary__source-item", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CitationTag, { citation }) }, citation.id)) })
1621
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "eth-inbox-thread-summary__no-sources", role: "status", children: "No citations attached." })
1622
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "eth-inbox-thread-summary__empty", role: "status", children: [
1623
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("strong", { children: "No generated summary" }),
1624
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Summaries and source citations appear here after the agent reviews the conversation." })
1625
+ ] })
1626
+ }
1627
+ );
1628
+ }
1629
+ function CitationTag({ citation }) {
1630
+ const referenceLabel = citation.messageRef ? `${citation.label}, message ${citation.messageRef}` : citation.label;
1631
+ const tag = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1632
+ import_core12.Tag,
1633
+ {
1634
+ className: "eth-inbox-thread-summary__source-token",
1635
+ "aria-label": referenceLabel,
1636
+ title: referenceLabel,
1637
+ "data-message-ref": citation.messageRef,
1638
+ children: citation.label
1639
+ }
1640
+ );
1641
+ if (!citation.href) {
1642
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "eth-inbox-thread-summary__source-reference", children: tag });
1643
+ }
1644
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1645
+ "a",
1646
+ {
1647
+ className: "eth-inbox-thread-summary__source-link",
1648
+ href: citation.href,
1649
+ "aria-label": referenceLabel,
1650
+ children: tag
1651
+ }
1652
+ );
1653
+ }
1654
+ function formatCitationCount(count) {
1655
+ return `${count} ${count === 1 ? "citation" : "citations"}`;
1656
+ }
1657
+
1658
+ // src/index.tsx
1659
+ var InboxComponentNames = [
1660
+ "InboxShell",
1661
+ "MailboxFolderList",
1662
+ "MessageList",
1663
+ "MessageThread",
1664
+ "MessageComposer",
1665
+ "MessagePreview",
1666
+ "AttachmentList",
1667
+ "AttachmentPreview",
1668
+ "RecipientPicker",
1669
+ "LabelManager",
1670
+ "MessageSearch",
1671
+ "MessageFilterBar",
1672
+ "PriorityInboxView",
1673
+ "EmailAutomationRulePanel",
1674
+ "AgentDraftReviewPanel",
1675
+ "ApprovalToSendPanel",
1676
+ "ThreadSummaryPanel"
1677
+ ];
1678
+ // Annotate the CommonJS export names for ESM import in node:
1679
+ 0 && (module.exports = {
1680
+ AgentDraftReviewPanel,
1681
+ ApprovalToSendPanel,
1682
+ AttachmentList,
1683
+ AttachmentPreview,
1684
+ EmailAutomationRulePanel,
1685
+ InboxComponentNames,
1686
+ InboxShell,
1687
+ LabelManager,
1688
+ MailboxFolderList,
1689
+ MessageComposer,
1690
+ MessageFilterBar,
1691
+ MessageList,
1692
+ MessagePreview,
1693
+ MessageSearch,
1694
+ MessageThread,
1695
+ PriorityInboxView,
1696
+ RecipientPicker,
1697
+ ThreadSummaryPanel
1698
+ });
1699
+ //# sourceMappingURL=index.cjs.map