@adatechnology/notification-ui 0.1.0-rc.5 → 0.1.0-rc.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2,6 +2,10 @@ import {
2
2
  DEFAULT_LOCALE,
3
3
  NOTIFICATION_QUERY_KEYS,
4
4
  NotificationProvider,
5
+ SORT_DIRECTIONS,
6
+ TEMPLATE_COLUMNS,
7
+ TEMPLATE_SORT_FIELDS,
8
+ TEMPLATE_VIEWS,
5
9
  flattenNotificationPages,
6
10
  formatNotificationTime,
7
11
  formatNotificationTimestamp,
@@ -21,7 +25,7 @@ import {
21
25
  useUnreadCount,
22
26
  useUpdatePreferences,
23
27
  useUpsertTemplate
24
- } from "./chunk-QBQ62VZ3.js";
28
+ } from "./chunk-7XDQ76IV.js";
25
29
 
26
30
  // src/components/NotificationBell.tsx
27
31
  import { Bell } from "lucide-react";
@@ -298,8 +302,632 @@ function NotificationsWorkspace({
298
302
  }
299
303
 
300
304
  // src/components/NotificationSettingsWorkspace.tsx
305
+ import { Plus, Trash2 as Trash22, X } from "lucide-react";
306
+ import { useState as useState4 } from "react";
307
+
308
+ // src/components/HtmlCodeField.tsx
309
+ import { useRef } from "react";
310
+
311
+ // src/htmlHighlight.util.ts
312
+ var HTML_TOKEN = {
313
+ TAG: "tag",
314
+ NAME: "name",
315
+ ATTRIBUTE: "attribute",
316
+ VALUE: "value",
317
+ COMMENT: "comment",
318
+ DOCTYPE: "doctype",
319
+ VARIABLE: "variable",
320
+ TEXT: "text"
321
+ };
322
+ var SCANNER = /(<!--[\s\S]*?-->)|(<!doctype[^>]*>)|(<\/?)([a-zA-Z][\w:-]*)((?:[^>"']|"[^"]*"|'[^']*')*?)(\/?>)|(\{\{\s*[\w.]+\s*\}\})/gi;
323
+ function tokenizeHtml(source) {
324
+ const tokens = [];
325
+ let cursor = 0;
326
+ for (const match of source.matchAll(SCANNER)) {
327
+ const start = match.index;
328
+ if (start > cursor) push(tokens, HTML_TOKEN.TEXT, source.slice(cursor, start));
329
+ const [whole, comment, doctype, open, name, attributes, close, variable] = match;
330
+ if (comment) push(tokens, HTML_TOKEN.COMMENT, comment);
331
+ else if (doctype) push(tokens, HTML_TOKEN.DOCTYPE, doctype);
332
+ else if (variable) push(tokens, HTML_TOKEN.VARIABLE, variable);
333
+ else if (name) {
334
+ push(tokens, HTML_TOKEN.TAG, open ?? "<");
335
+ push(tokens, HTML_TOKEN.NAME, name);
336
+ tokens.push(...tokenizeAttributes(attributes ?? ""));
337
+ push(tokens, HTML_TOKEN.TAG, close ?? ">");
338
+ }
339
+ cursor = start + whole.length;
340
+ }
341
+ if (cursor < source.length) push(tokens, HTML_TOKEN.TEXT, source.slice(cursor));
342
+ return tokens;
343
+ }
344
+ var ATTRIBUTE_SCANNER = /([\w:@.-]+)(\s*=\s*)("[^"]*"|'[^']*'|[^\s>]+)?/g;
345
+ function tokenizeAttributes(source) {
346
+ const tokens = [];
347
+ let cursor = 0;
348
+ for (const match of source.matchAll(ATTRIBUTE_SCANNER)) {
349
+ const start = match.index;
350
+ if (start > cursor) push(tokens, HTML_TOKEN.TEXT, source.slice(cursor, start));
351
+ const [whole, attribute, equals, value] = match;
352
+ push(tokens, HTML_TOKEN.ATTRIBUTE, attribute ?? "");
353
+ push(tokens, HTML_TOKEN.TEXT, equals ?? "");
354
+ push(tokens, HTML_TOKEN.VALUE, value ?? "");
355
+ cursor = start + whole.length;
356
+ }
357
+ if (cursor < source.length) push(tokens, HTML_TOKEN.TEXT, source.slice(cursor));
358
+ return tokens;
359
+ }
360
+ function push(tokens, kind, text) {
361
+ if (text) tokens.push({ kind, text });
362
+ }
363
+
364
+ // src/components/HtmlCodeField.tsx
365
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
366
+ function HtmlCodeField({ value, rows = 12, onChange, onSelect, onFocus, problems }) {
367
+ const highlightRef = useRef(null);
368
+ function handleScroll(event) {
369
+ const pre = highlightRef.current;
370
+ if (!pre) return;
371
+ pre.scrollTop = event.currentTarget.scrollTop;
372
+ pre.scrollLeft = event.currentTarget.scrollLeft;
373
+ }
374
+ const lineCount = value.split("\n").length;
375
+ return /* @__PURE__ */ jsxs6("div", { className: "adn-code", children: [
376
+ /* @__PURE__ */ jsxs6("div", { className: "adn-code__editor", children: [
377
+ /* @__PURE__ */ jsx6("div", { className: "adn-code__gutter", "aria-hidden": "true", children: Array.from({ length: lineCount }, (_, index) => /* @__PURE__ */ jsx6("span", { children: index + 1 }, index)) }),
378
+ /* @__PURE__ */ jsxs6("div", { className: "adn-code__surface", children: [
379
+ /* @__PURE__ */ jsxs6("pre", { ref: highlightRef, className: "adn-code__highlight", "aria-hidden": "true", children: [
380
+ tokenizeHtml(value).map((token, index) => /* @__PURE__ */ jsx6("span", { className: `adn-code__token adn-code__token--${token.kind}`, children: token.text }, index)),
381
+ "\n"
382
+ ] }),
383
+ /* @__PURE__ */ jsx6(
384
+ "textarea",
385
+ {
386
+ className: "adn-code__input",
387
+ spellCheck: false,
388
+ rows,
389
+ value,
390
+ onChange: (event) => onChange(event.target.value),
391
+ onScroll: handleScroll,
392
+ onSelect: (event) => onSelect?.(event.currentTarget.selectionStart),
393
+ onFocus
394
+ }
395
+ )
396
+ ] })
397
+ ] }),
398
+ problems && problems.length > 0 && /* @__PURE__ */ jsx6("ul", { className: "adn-settings__email-report", children: problems.map((problem) => /* @__PURE__ */ jsx6(
399
+ "li",
400
+ {
401
+ className: `adn-settings__email-problem adn-settings__email-problem--${problem.severity}`,
402
+ children: problem.message
403
+ },
404
+ problem.code
405
+ )) })
406
+ ] });
407
+ }
408
+
409
+ // src/components/MessageBodyField.tsx
410
+ import { useLayoutEffect, useRef as useRef2, useState as useState3 } from "react";
411
+
412
+ // src/messageFormat.util.ts
413
+ function applyMark({ text, delimiter, selectionStart, selectionEnd }) {
414
+ const start = clamp(selectionStart, text.length);
415
+ const end = clamp(Math.max(selectionEnd, selectionStart), text.length);
416
+ const selected = text.slice(start, end);
417
+ const size = delimiter.length;
418
+ const wrappedInside = selected.startsWith(delimiter) && selected.endsWith(delimiter) && selected.length > size * 2;
419
+ if (wrappedInside) {
420
+ const bare = selected.slice(size, -size);
421
+ return {
422
+ text: `${text.slice(0, start)}${bare}${text.slice(end)}`,
423
+ selectionStart: start,
424
+ selectionEnd: start + bare.length
425
+ };
426
+ }
427
+ const wrappedOutside = text.slice(start - size, start) === delimiter && text.slice(end, end + size) === delimiter;
428
+ if (wrappedOutside) {
429
+ return {
430
+ text: `${text.slice(0, start - size)}${selected}${text.slice(end + size)}`,
431
+ selectionStart: start - size,
432
+ selectionEnd: start - size + selected.length
433
+ };
434
+ }
435
+ return {
436
+ text: `${text.slice(0, start)}${delimiter}${selected}${delimiter}${text.slice(end)}`,
437
+ selectionStart: start + size,
438
+ selectionEnd: start + size + selected.length
439
+ };
440
+ }
441
+ function insertAt({
442
+ text,
443
+ insertion,
444
+ selectionStart,
445
+ selectionEnd
446
+ }) {
447
+ const start = clamp(selectionStart, text.length);
448
+ const end = clamp(Math.max(selectionEnd, selectionStart), text.length);
449
+ const next = start + insertion.length;
450
+ return {
451
+ text: `${text.slice(0, start)}${insertion}${text.slice(end)}`,
452
+ selectionStart: next,
453
+ selectionEnd: next
454
+ };
455
+ }
456
+ function clamp(value, max) {
457
+ return Math.min(Math.max(value, 0), max);
458
+ }
459
+
460
+ // src/components/MessageToolbar.tsx
461
+ import { Bold, Code, Italic, Smile, Strikethrough } from "lucide-react";
301
462
  import { useState as useState2 } from "react";
302
- import { Fragment, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
463
+
464
+ // src/messageFormat.constant.ts
465
+ var MESSAGE_FORMAT = {
466
+ BOLD: "bold",
467
+ ITALIC: "italic",
468
+ STRIKETHROUGH: "strikethrough",
469
+ MONOSPACE: "monospace"
470
+ };
471
+ var MESSAGE_FORMAT_MARKS = [
472
+ { format: MESSAGE_FORMAT.BOLD, delimiter: "*" },
473
+ { format: MESSAGE_FORMAT.ITALIC, delimiter: "_" },
474
+ { format: MESSAGE_FORMAT.STRIKETHROUGH, delimiter: "~" },
475
+ { format: MESSAGE_FORMAT.MONOSPACE, delimiter: "```" }
476
+ ];
477
+ var MESSAGE_EMOJI = [
478
+ "\u2705",
479
+ "\u274C",
480
+ "\u26A0\uFE0F",
481
+ "\u2139\uFE0F",
482
+ "\u{1F4C5}",
483
+ "\u23F0",
484
+ "\u23F3",
485
+ "\u{1F514}",
486
+ "\u{1F4AC}",
487
+ "\u{1F4DE}",
488
+ "\u{1F4E7}",
489
+ "\u{1F64B}",
490
+ "\u{1F4B0}",
491
+ "\u{1F4B3}",
492
+ "\u{1F9FE}",
493
+ "\u{1F4CA}",
494
+ "\u{1F4E6}",
495
+ "\u{1F69A}",
496
+ "\u{1F4CD}",
497
+ "\u{1F517}",
498
+ "\u{1F642}",
499
+ "\u{1F389}",
500
+ "\u{1F64F}",
501
+ "\u{1F44B}"
502
+ ];
503
+
504
+ // src/components/MessageToolbar.tsx
505
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
506
+ var FORMAT_ICON = {
507
+ [MESSAGE_FORMAT.BOLD]: /* @__PURE__ */ jsx7(Bold, { "aria-hidden": "true", className: "adn-settings__button-icon" }),
508
+ [MESSAGE_FORMAT.ITALIC]: /* @__PURE__ */ jsx7(Italic, { "aria-hidden": "true", className: "adn-settings__button-icon" }),
509
+ [MESSAGE_FORMAT.STRIKETHROUGH]: /* @__PURE__ */ jsx7(Strikethrough, { "aria-hidden": "true", className: "adn-settings__button-icon" }),
510
+ [MESSAGE_FORMAT.MONOSPACE]: /* @__PURE__ */ jsx7(Code, { "aria-hidden": "true", className: "adn-settings__button-icon" })
511
+ };
512
+ function MessageToolbar({ onMark, onInsert, labelOf }) {
513
+ const [isEmojiOpen, setIsEmojiOpen] = useState2(false);
514
+ return /* @__PURE__ */ jsxs7("div", { className: "adn-toolbar", children: [
515
+ MESSAGE_FORMAT_MARKS.map(({ format, delimiter }) => /* @__PURE__ */ jsx7(
516
+ "button",
517
+ {
518
+ type: "button",
519
+ className: "adn-toolbar__button",
520
+ title: labelOf(`toolbar.${format}`),
521
+ "aria-label": labelOf(`toolbar.${format}`),
522
+ onMouseDown: (event) => {
523
+ event.preventDefault();
524
+ onMark(delimiter);
525
+ },
526
+ children: FORMAT_ICON[format]
527
+ },
528
+ format
529
+ )),
530
+ /* @__PURE__ */ jsx7("span", { className: "adn-toolbar__divider", "aria-hidden": "true" }),
531
+ /* @__PURE__ */ jsxs7("div", { className: "adn-toolbar__emoji", children: [
532
+ /* @__PURE__ */ jsx7(
533
+ "button",
534
+ {
535
+ type: "button",
536
+ className: "adn-toolbar__button",
537
+ title: labelOf("toolbar.emoji"),
538
+ "aria-label": labelOf("toolbar.emoji"),
539
+ "aria-expanded": isEmojiOpen,
540
+ onMouseDown: (event) => {
541
+ event.preventDefault();
542
+ setIsEmojiOpen((current) => !current);
543
+ },
544
+ children: /* @__PURE__ */ jsx7(Smile, { "aria-hidden": "true", className: "adn-settings__button-icon" })
545
+ }
546
+ ),
547
+ isEmojiOpen && /* @__PURE__ */ jsx7("div", { className: "adn-toolbar__palette", role: "group", "aria-label": labelOf("toolbar.emoji"), children: MESSAGE_EMOJI.map((emoji) => /* @__PURE__ */ jsx7(
548
+ "button",
549
+ {
550
+ type: "button",
551
+ className: "adn-toolbar__emoji-button",
552
+ onMouseDown: (event) => {
553
+ event.preventDefault();
554
+ onInsert(emoji);
555
+ setIsEmojiOpen(false);
556
+ },
557
+ children: emoji
558
+ },
559
+ emoji
560
+ )) })
561
+ ] })
562
+ ] });
563
+ }
564
+
565
+ // src/components/MessageBodyField.tsx
566
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
567
+ function MessageBodyField({ value, rows = 5, onChange, onSelect, onFocus, labelOf }) {
568
+ const textareaRef = useRef2(null);
569
+ const [pendingSelection, setPendingSelection] = useState3();
570
+ useLayoutEffect(() => {
571
+ if (!pendingSelection) return;
572
+ const textarea = textareaRef.current;
573
+ if (!textarea) return;
574
+ textarea.focus();
575
+ textarea.setSelectionRange(pendingSelection[0], pendingSelection[1]);
576
+ setPendingSelection(void 0);
577
+ }, [pendingSelection]);
578
+ function currentRange() {
579
+ const textarea = textareaRef.current;
580
+ if (!textarea) return [value.length, value.length];
581
+ return [textarea.selectionStart, textarea.selectionEnd];
582
+ }
583
+ function handleMark(delimiter) {
584
+ const [selectionStart, selectionEnd] = currentRange();
585
+ const result = applyMark({ text: value, delimiter, selectionStart, selectionEnd });
586
+ onChange(result.text);
587
+ setPendingSelection([result.selectionStart, result.selectionEnd]);
588
+ }
589
+ function handleInsert(insertion) {
590
+ const [selectionStart, selectionEnd] = currentRange();
591
+ const result = insertAt({ text: value, insertion, selectionStart, selectionEnd });
592
+ onChange(result.text);
593
+ setPendingSelection([result.selectionStart, result.selectionEnd]);
594
+ }
595
+ return /* @__PURE__ */ jsxs8("div", { className: "adn-message-field", children: [
596
+ /* @__PURE__ */ jsx8(MessageToolbar, { onMark: handleMark, onInsert: handleInsert, labelOf }),
597
+ /* @__PURE__ */ jsx8(
598
+ "textarea",
599
+ {
600
+ ref: textareaRef,
601
+ rows,
602
+ value,
603
+ onChange: (event) => onChange(event.target.value),
604
+ onSelect: (event) => onSelect?.(event.currentTarget.selectionStart),
605
+ onFocus
606
+ }
607
+ )
608
+ ] });
609
+ }
610
+
611
+ // src/components/TemplatePreview.tsx
612
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
613
+ function StatusIcons() {
614
+ return /* @__PURE__ */ jsxs9("span", { className: "adn-preview-status__icons", children: [
615
+ /* @__PURE__ */ jsxs9("svg", { width: "15", height: "10", viewBox: "0 0 15 10", "aria-hidden": "true", children: [
616
+ /* @__PURE__ */ jsx9("rect", { x: "0", y: "6", width: "2.5", height: "4", rx: "0.6", fill: "currentColor" }),
617
+ /* @__PURE__ */ jsx9("rect", { x: "4", y: "4", width: "2.5", height: "6", rx: "0.6", fill: "currentColor" }),
618
+ /* @__PURE__ */ jsx9("rect", { x: "8", y: "2", width: "2.5", height: "8", rx: "0.6", fill: "currentColor" }),
619
+ /* @__PURE__ */ jsx9("rect", { x: "12", y: "0", width: "2.5", height: "10", rx: "0.6", fill: "currentColor" })
620
+ ] }),
621
+ /* @__PURE__ */ jsxs9("svg", { width: "13", height: "10", viewBox: "0 0 13 10", "aria-hidden": "true", children: [
622
+ /* @__PURE__ */ jsx9("path", { d: "M6.5 9.2 1 3.6a7.8 7.8 0 0 1 11 0Z", fill: "none", stroke: "currentColor", strokeWidth: "1.3" }),
623
+ /* @__PURE__ */ jsx9("circle", { cx: "6.5", cy: "8", r: "1", fill: "currentColor" })
624
+ ] }),
625
+ /* @__PURE__ */ jsxs9("svg", { width: "20", height: "10", viewBox: "0 0 20 10", "aria-hidden": "true", children: [
626
+ /* @__PURE__ */ jsx9("rect", { x: "0.5", y: "0.5", width: "16", height: "9", rx: "2.5", fill: "none", stroke: "currentColor", opacity: "0.5" }),
627
+ /* @__PURE__ */ jsx9("rect", { x: "2", y: "2", width: "11", height: "6", rx: "1.2", fill: "currentColor" }),
628
+ /* @__PURE__ */ jsx9("rect", { x: "18", y: "3.5", width: "1.6", height: "3", rx: "0.8", fill: "currentColor", opacity: "0.5" })
629
+ ] })
630
+ ] });
631
+ }
632
+ function Phone({
633
+ children,
634
+ os,
635
+ tone,
636
+ time
637
+ }) {
638
+ const android = os === "android";
639
+ const classes = ["adn-preview-phone", `adn-preview-phone--${android ? "android" : "ios"}`];
640
+ if (tone === "dark") classes.push("adn-preview-phone--dark");
641
+ return /* @__PURE__ */ jsxs9("div", { className: classes.join(" "), children: [
642
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-phone__btn adn-preview-phone__btn--mute" }),
643
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-phone__btn adn-preview-phone__btn--up" }),
644
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-phone__btn adn-preview-phone__btn--down" }),
645
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-phone__btn adn-preview-phone__btn--power" }),
646
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-phone__screen", children: [
647
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-status", children: [
648
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-status__time", children: time }),
649
+ android ? /* @__PURE__ */ jsx9("span", { className: "adn-preview-phone__punch" }) : /* @__PURE__ */ jsx9("span", { className: "adn-preview-phone__island" }),
650
+ /* @__PURE__ */ jsx9(StatusIcons, {})
651
+ ] }),
652
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-phone__content", children }),
653
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-phone__gesture" })
654
+ ] })
655
+ ] });
656
+ }
657
+ function Icon({ d, size = 16 }) {
658
+ return /* @__PURE__ */ jsx9(
659
+ "svg",
660
+ {
661
+ width: size,
662
+ height: size,
663
+ viewBox: "0 0 24 24",
664
+ fill: "none",
665
+ stroke: "currentColor",
666
+ strokeWidth: "1.7",
667
+ strokeLinecap: "round",
668
+ strokeLinejoin: "round",
669
+ "aria-hidden": "true",
670
+ children: /* @__PURE__ */ jsx9("path", { d })
671
+ }
672
+ );
673
+ }
674
+ var ICON = {
675
+ back: "M19 12H5M12 19l-7-7 7-7",
676
+ archive: "M3 8h18v12H3zM3 4h18v4H3M10 12h4",
677
+ report: "M12 8v5M12 16.5v.01M12 3 2 20h20Z",
678
+ trash: "M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6",
679
+ unread: "M3 5h18v14H3zM3 5l9 7 9-7",
680
+ move: "M3 7h6l2 2h10v10H3zM3 7V5h6l2 2",
681
+ more: "M12 6v.01M12 12v.01M12 18v.01",
682
+ prev: "M15 19l-7-7 7-7",
683
+ next: "M9 5l7 7-7 7",
684
+ print: "M6 9V3h12v6M6 18H4v-6h16v6h-2M8 14h8v7H8z",
685
+ popout: "M14 4h6v6M20 4l-9 9M18 14v6H4V6h6",
686
+ star: "m12 3 2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 9.8l6.5-.9Z",
687
+ reply: "M9 17H4V7M4 7l7 7M20 17v-3a6 6 0 0 0-6-6H4",
688
+ pencil: "M16.5 3.5a2.1 2.1 0 0 1 3 3L8 18l-4 1 1-4Z",
689
+ inbox: "M3 12h5l2 3h4l2-3h5M3 12l2-7h14l2 7v7H3z",
690
+ search: "M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14M20 20l-3.5-3.5",
691
+ help: "M12 17v.01M9.5 9a2.5 2.5 0 1 1 3.5 2.3c-.6.3-1 .9-1 1.7",
692
+ video: "M3 7h11v10H3zM14 10l7-3v10l-7-3",
693
+ call: "M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a1 1 0 0 1-1 1A16 16 0 0 1 4 5a1 1 0 0 1 1-1",
694
+ mic: "M12 3a3 3 0 0 1 3 3v5a3 3 0 0 1-6 0V6a3 3 0 0 1 3-3M5 11a7 7 0 0 0 14 0M12 18v3",
695
+ forward: "M15 17h5V7M20 7l-7 7M4 17v-3a6 6 0 0 1 6-6h10",
696
+ replyAll: "M7 17H3V9M3 9l5 5M11 17H8V9M8 9l5 5M20 17v-3a6 6 0 0 0-6-6H8",
697
+ chevron: "m6 9 6 6 6-6",
698
+ settings: "M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6M19 12a7 7 0 0 0-.1-1l2-1.5-2-3.4-2.3 1a7 7 0 0 0-1.7-1L14.5 3h-4l-.4 2.6a7 7 0 0 0-1.7 1l-2.3-1-2 3.4L6.1 11a7 7 0 0 0 0 2l-2 1.5 2 3.4 2.3-1a7 7 0 0 0 1.7 1l.4 2.6h4l.4-2.6a7 7 0 0 0 1.7-1l2.3 1 2-3.4-2-1.5c.1-.3.1-.7.1-1"
699
+ };
700
+ function EmailDesktop({
701
+ rendered,
702
+ emailHtml,
703
+ senderName,
704
+ labels
705
+ }) {
706
+ return /* @__PURE__ */ jsxs9("div", { className: "adn-preview-browser", children: [
707
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-browser__bar", children: [
708
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-browser__dot" }),
709
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-browser__dot" }),
710
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-browser__dot" }),
711
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-browser__address", children: labels.address })
712
+ ] }),
713
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mailapp", children: [
714
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mailapp__bar", children: [
715
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mailapp__menu", "aria-hidden": "true", children: [
716
+ /* @__PURE__ */ jsx9("span", {}),
717
+ /* @__PURE__ */ jsx9("span", {}),
718
+ /* @__PURE__ */ jsx9("span", {})
719
+ ] }),
720
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mailapp__search", children: [
721
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.search, size: 15 }),
722
+ /* @__PURE__ */ jsx9("span", { children: labels.mailbox })
723
+ ] }),
724
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mailapp__account", children: [
725
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.help, size: 15 }),
726
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.settings, size: 15 }),
727
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-avatar adn-preview-avatar--small", children: senderName.slice(0, 1) })
728
+ ] })
729
+ ] }),
730
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mailapp__split", children: [
731
+ /* @__PURE__ */ jsxs9("nav", { className: "adn-preview-mailapp__rail", "aria-hidden": "true", children: [
732
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mailapp__compose", children: /* @__PURE__ */ jsx9(Icon, { d: ICON.pencil, size: 16 }) }),
733
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mailapp__rail-item adn-preview-mailapp__rail-item--active", children: /* @__PURE__ */ jsx9(Icon, { d: ICON.inbox, size: 16 }) }),
734
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mailapp__rail-item", children: /* @__PURE__ */ jsx9(Icon, { d: ICON.star, size: 16 }) })
735
+ ] }),
736
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-browser__viewport", children: [
737
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mailapp__toolbar", children: [
738
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.back }),
739
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mailapp__divider" }),
740
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.archive }),
741
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.report }),
742
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.trash }),
743
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mailapp__divider" }),
744
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.unread }),
745
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.move }),
746
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.more }),
747
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mailapp__spacer" }),
748
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mailapp__counter", children: labels.counter }),
749
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.prev, size: 14 }),
750
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.next, size: 14 })
751
+ ] }),
752
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mail", children: [
753
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mail__subject-row", children: [
754
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-mail__subject", children: rendered.title }),
755
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__folder", children: labels.folder }),
756
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__subject-actions", children: [
757
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.print, size: 15 }),
758
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.popout, size: 15 })
759
+ ] })
760
+ ] }),
761
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mail__from", children: [
762
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-avatar", children: senderName.slice(0, 1) }),
763
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__identity", children: [
764
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__sender-row", children: [
765
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__sender", children: senderName }),
766
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__address", children: labels.senderAddress }),
767
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__unsubscribe", children: labels.unsubscribe })
768
+ ] }),
769
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__to", children: labels.to })
770
+ ] }),
771
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__from-actions", children: [
772
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__time", children: labels.now }),
773
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.star, size: 15 }),
774
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.reply, size: 15 }),
775
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.more, size: 15 })
776
+ ] })
777
+ ] }),
778
+ /* @__PURE__ */ jsx9(MailBody, { html: emailHtml, text: rendered.body })
779
+ ] })
780
+ ] })
781
+ ] })
782
+ ] })
783
+ ] });
784
+ }
785
+ function EmailMobile({
786
+ rendered,
787
+ emailHtml,
788
+ senderName,
789
+ os,
790
+ labels
791
+ }) {
792
+ return /* @__PURE__ */ jsxs9(Phone, { os, time: labels.time, children: [
793
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mailapp__actions", children: [
794
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.back, size: 18 }),
795
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mailapp__spacer" }),
796
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.archive, size: 18 }),
797
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.trash, size: 18 }),
798
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.unread, size: 18 }),
799
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.more, size: 18 })
800
+ ] }),
801
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-mailapp__scroll", children: /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mail adn-preview-mail--compact", children: [
802
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-mail__subject-row", children: /* @__PURE__ */ jsx9("div", { className: "adn-preview-mail__subject", children: rendered.title }) }),
803
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__folder", children: labels.folder }),
804
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mail__from adn-preview-mail__from--mobile", children: [
805
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-avatar adn-preview-avatar--large", children: senderName.slice(0, 1) }),
806
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__identity", children: [
807
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__sender-row", children: [
808
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__sender", children: senderName }),
809
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__time", children: labels.now })
810
+ ] }),
811
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__recipients", children: [
812
+ labels.to,
813
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.chevron, size: 12 })
814
+ ] })
815
+ ] }),
816
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-mail__from-actions", children: /* @__PURE__ */ jsx9(Icon, { d: ICON.star, size: 17 }) })
817
+ ] }),
818
+ /* @__PURE__ */ jsx9(MailBody, { html: emailHtml, text: rendered.body }),
819
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-mail__reply", children: [
820
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__reply-button", children: [
821
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.reply, size: 14 }),
822
+ labels.reply
823
+ ] }),
824
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__reply-button", children: [
825
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.replyAll, size: 14 }),
826
+ labels.replyAll
827
+ ] }),
828
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-mail__reply-button", children: [
829
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.forward, size: 14 }),
830
+ labels.forward
831
+ ] })
832
+ ] })
833
+ ] }) })
834
+ ] });
835
+ }
836
+ function WhatsAppPreview({
837
+ rendered,
838
+ labels,
839
+ os,
840
+ senderName
841
+ }) {
842
+ return /* @__PURE__ */ jsxs9(Phone, { os, time: labels.time, children: [
843
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-wa__header", children: [
844
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.back, size: 18 }),
845
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-wa__avatar", children: senderName.slice(0, 1) }),
846
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-wa__contact", children: [
847
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-wa__name", children: senderName }),
848
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-wa__status", children: labels.online })
849
+ ] }),
850
+ /* @__PURE__ */ jsxs9("span", { className: "adn-preview-wa__header-actions", children: [
851
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.video, size: 17 }),
852
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.call, size: 17 }),
853
+ /* @__PURE__ */ jsx9(Icon, { d: ICON.more, size: 17 })
854
+ ] })
855
+ ] }),
856
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-wa", children: [
857
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-wa__day", children: labels.today }),
858
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-wa__bubble", children: [
859
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-wa__text", children: rendered.body }),
860
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-wa__time", children: labels.now })
861
+ ] })
862
+ ] }),
863
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-wa__composer", children: [
864
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-wa__input", children: labels.compose }),
865
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-wa__send", children: /* @__PURE__ */ jsx9(Icon, { d: ICON.mic, size: 16 }) })
866
+ ] })
867
+ ] });
868
+ }
869
+ function SmsPreview({
870
+ rendered,
871
+ os,
872
+ labels
873
+ }) {
874
+ return /* @__PURE__ */ jsx9(Phone, { os, time: labels.time, children: /* @__PURE__ */ jsx9("div", { className: "adn-preview-sms", children: /* @__PURE__ */ jsx9("div", { className: "adn-preview-sms__bubble", children: rendered.body }) }) });
875
+ }
876
+ function PushPreview({
877
+ rendered,
878
+ senderName,
879
+ labels,
880
+ os
881
+ }) {
882
+ return /* @__PURE__ */ jsx9(Phone, { os, tone: "dark", time: labels.time, children: /* @__PURE__ */ jsx9("div", { className: "adn-preview-push", children: /* @__PURE__ */ jsxs9("div", { className: "adn-preview-push__card", children: [
883
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-push__app", children: [
884
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-avatar adn-preview-avatar--small", children: senderName.slice(0, 1) }),
885
+ /* @__PURE__ */ jsx9("span", { children: senderName }),
886
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-push__time", children: labels.now })
887
+ ] }),
888
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-push__title", children: rendered.title }),
889
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-push__body", children: rendered.body })
890
+ ] }) }) });
891
+ }
892
+ function InboxPreview({ rendered }) {
893
+ return /* @__PURE__ */ jsxs9("div", { className: "adn-preview-inbox", children: [
894
+ /* @__PURE__ */ jsx9("span", { className: "adn-preview-inbox__dot" }),
895
+ /* @__PURE__ */ jsxs9("div", { className: "adn-preview-inbox__text", children: [
896
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-inbox__title", children: rendered.title }),
897
+ /* @__PURE__ */ jsx9("div", { className: "adn-preview-inbox__body", children: rendered.body })
898
+ ] })
899
+ ] });
900
+ }
901
+ function MailBody({ html, text }) {
902
+ if (!html) return /* @__PURE__ */ jsx9("div", { className: "adn-preview-mail__body", children: text });
903
+ return /* @__PURE__ */ jsx9(
904
+ "iframe",
905
+ {
906
+ className: "adn-preview-mail__body adn-preview-mail__frame",
907
+ sandbox: "",
908
+ srcDoc: html,
909
+ title: text.slice(0, 60)
910
+ }
911
+ );
912
+ }
913
+ function TemplatePreview({ channel, viewport, rendered, emailHtml, senderName, labels }) {
914
+ const sender = senderName ?? rendered.title.slice(0, 1).toUpperCase();
915
+ if (channel === "whatsapp") {
916
+ return /* @__PURE__ */ jsx9(WhatsAppPreview, { rendered, labels, os: viewport, senderName: sender });
917
+ }
918
+ if (channel === "sms") return /* @__PURE__ */ jsx9(SmsPreview, { rendered, os: viewport, labels });
919
+ if (channel === "push") {
920
+ return /* @__PURE__ */ jsx9(PushPreview, { rendered, senderName: sender, labels, os: viewport });
921
+ }
922
+ if (channel === "inbox") return /* @__PURE__ */ jsx9(InboxPreview, { rendered });
923
+ return viewport === "browser" ? /* @__PURE__ */ jsx9(EmailDesktop, { rendered, emailHtml, senderName: sender, labels }) : /* @__PURE__ */ jsx9(EmailMobile, { rendered, emailHtml, senderName: sender, os: viewport, labels });
924
+ }
925
+
926
+ // src/components/NotificationSettingsWorkspace.tsx
927
+ import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
928
+ function isHtmlBody(body) {
929
+ return /<\/?[a-zA-Z][\w:-]*(\s|>|\/)/.test(body);
930
+ }
303
931
  function NotificationSettingsWorkspace({
304
932
  labels: labelsOverride,
305
933
  channels,
@@ -307,9 +935,12 @@ function NotificationSettingsWorkspace({
307
935
  previewPayload,
308
936
  templateLabelOf,
309
937
  renderChannelFields,
938
+ validateEmailHtml,
310
939
  renderHeader,
311
940
  renderHeaderActions,
312
- className
941
+ className,
942
+ senderName,
943
+ categoryLabelOf
313
944
  }) {
314
945
  const { messages } = useNotificationContext();
315
946
  const label = (key) => labelsOverride?.[key] ?? messages[key] ?? key;
@@ -319,15 +950,17 @@ function NotificationSettingsWorkspace({
319
950
  ...previewPayload ? { previewPayload } : {},
320
951
  ...channels[0] ? { defaultChannel: channels[0].id } : {}
321
952
  });
322
- const [cursor, setCursor] = useState2({
953
+ const [cursor, setCursor] = useState4({
323
954
  field: "body",
324
955
  cursorIndex: 0
325
956
  });
957
+ const [cursorChannel, setCursorChannel] = useState4(void 0);
958
+ const [activeChannel, setActiveChannel] = useState4(void 0);
326
959
  function rememberCursor(field, cursorIndex) {
327
960
  setCursor({ field, cursorIndex: cursorIndex ?? 0 });
328
961
  }
329
962
  const policies = useCategoryPolicies();
330
- const [tab, setTab] = useState2("messages");
963
+ const [tab, setTab] = useState4("messages");
331
964
  function isEnabled(category, channel) {
332
965
  const row = (preferencesQuery.data ?? []).find(
333
966
  (preference) => preference.category === category && preference.channel === channel
@@ -344,15 +977,23 @@ function NotificationSettingsWorkspace({
344
977
  );
345
978
  updatePreferences.mutate(next);
346
979
  }
347
- return /* @__PURE__ */ jsxs6("div", { className: `adn-settings ${className ?? ""}`, children: [
348
- renderHeader ? renderHeader() : /* @__PURE__ */ jsxs6("header", { className: "adn-settings__header", children: [
349
- /* @__PURE__ */ jsxs6("div", { children: [
350
- /* @__PURE__ */ jsx6("h1", { className: "adn-settings__title", children: label("settings.title") }),
351
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__description", children: label("settings.description") })
980
+ function sortMarkOf(field) {
981
+ if (editor.sort?.field !== field) return "\u2195";
982
+ return editor.sort.direction === SORT_DIRECTIONS.ASC ? "\u2191" : "\u2193";
983
+ }
984
+ function ariaSortOf(field) {
985
+ if (editor.sort?.field !== field) return "none";
986
+ return editor.sort.direction === SORT_DIRECTIONS.ASC ? "ascending" : "descending";
987
+ }
988
+ return /* @__PURE__ */ jsxs10("div", { className: `adn-settings ${className ?? ""}`, children: [
989
+ renderHeader ? renderHeader() : /* @__PURE__ */ jsxs10("header", { className: "adn-settings__header", children: [
990
+ /* @__PURE__ */ jsxs10("div", { children: [
991
+ /* @__PURE__ */ jsx10("h1", { className: "adn-settings__title", children: label("settings.title") }),
992
+ /* @__PURE__ */ jsx10("p", { className: "adn-settings__description", children: label("settings.description") })
352
993
  ] }),
353
994
  renderHeaderActions?.()
354
995
  ] }),
355
- /* @__PURE__ */ jsx6("div", { className: "adn-settings__tabs", role: "tablist", children: ["messages", "routing"].map((id) => /* @__PURE__ */ jsx6(
996
+ /* @__PURE__ */ jsx10("div", { className: "adn-settings__tabs", role: "tablist", children: ["messages", "routing"].map((id) => /* @__PURE__ */ jsx10(
356
997
  "button",
357
998
  {
358
999
  type: "button",
@@ -364,13 +1005,13 @@ function NotificationSettingsWorkspace({
364
1005
  },
365
1006
  id
366
1007
  )) }),
367
- tab === "routing" && /* @__PURE__ */ jsxs6("section", { className: "adn-settings__policies", children: [
368
- /* @__PURE__ */ jsx6("h2", { className: "adn-settings__section-title", children: label("settings.policiesTitle") }),
369
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.policiesHint") }),
370
- categories.map((category) => /* @__PURE__ */ jsxs6("div", { className: "adn-settings__category", children: [
371
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__category-title", children: category.label }),
372
- /* @__PURE__ */ jsx6("div", { className: "adn-settings__category-channels", children: channels.map((channel) => /* @__PURE__ */ jsxs6("label", { className: "adn-settings__toggle", children: [
373
- /* @__PURE__ */ jsx6(
1008
+ tab === "routing" && /* @__PURE__ */ jsxs10("section", { className: "adn-settings__policies", children: [
1009
+ /* @__PURE__ */ jsx10("h2", { className: "adn-settings__section-title", children: label("settings.policiesTitle") }),
1010
+ /* @__PURE__ */ jsx10("p", { className: "adn-settings__hint", children: label("settings.policiesHint") }),
1011
+ categories.map((category) => /* @__PURE__ */ jsxs10("div", { className: "adn-settings__category", children: [
1012
+ /* @__PURE__ */ jsx10("p", { className: "adn-settings__category-title", children: category.label }),
1013
+ /* @__PURE__ */ jsx10("div", { className: "adn-settings__category-channels", children: channels.map((channel) => /* @__PURE__ */ jsxs10("label", { className: "adn-settings__toggle", children: [
1014
+ /* @__PURE__ */ jsx10(
374
1015
  "input",
375
1016
  {
376
1017
  type: "checkbox",
@@ -378,23 +1019,23 @@ function NotificationSettingsWorkspace({
378
1019
  onChange: () => policies.toggle({ category: category.id, channel: channel.id })
379
1020
  }
380
1021
  ),
381
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__channel-label", children: channel.label })
1022
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__channel-label", children: channel.label })
382
1023
  ] }, channel.id)) })
383
1024
  ] }, category.id)),
384
- policies.error && /* @__PURE__ */ jsx6("p", { className: "adn-settings__error", children: policies.error }),
385
- /* @__PURE__ */ jsxs6("div", { className: "adn-settings__actions", children: [
386
- /* @__PURE__ */ jsx6("button", { type: "button", onClick: policies.save, disabled: !policies.isDirty || policies.isSaving, children: policies.isSaving ? label("settings.saving") : label("settings.savePolicies") }),
387
- policies.isDirty && /* @__PURE__ */ jsx6("button", { type: "button", onClick: policies.reset, children: label("settings.discard") })
1025
+ policies.error && /* @__PURE__ */ jsx10("p", { className: "adn-settings__error", children: policies.error }),
1026
+ /* @__PURE__ */ jsxs10("div", { className: "adn-settings__actions", children: [
1027
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: policies.save, disabled: !policies.isDirty || policies.isSaving, children: policies.isSaving ? label("settings.saving") : label("settings.savePolicies") }),
1028
+ policies.isDirty && /* @__PURE__ */ jsx10("button", { type: "button", onClick: policies.reset, children: label("settings.discard") })
388
1029
  ] })
389
1030
  ] }),
390
- tab === "routing" && /* @__PURE__ */ jsxs6("section", { className: "adn-settings__channels", children: [
391
- /* @__PURE__ */ jsx6("h2", { className: "adn-settings__section-title", children: label("settings.channelsTitle") }),
392
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.channelsHint") }),
393
- categories.map((category) => /* @__PURE__ */ jsxs6("div", { className: "adn-settings__category", children: [
394
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__category-label", children: category.label }),
395
- category.hint && /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: category.hint }),
396
- /* @__PURE__ */ jsx6("div", { className: "adn-settings__channel-grid", children: channels.map((channel) => /* @__PURE__ */ jsxs6("label", { className: "adn-settings__channel", children: [
397
- /* @__PURE__ */ jsx6(
1031
+ tab === "routing" && /* @__PURE__ */ jsxs10("section", { className: "adn-settings__channels", children: [
1032
+ /* @__PURE__ */ jsx10("h2", { className: "adn-settings__section-title", children: label("settings.channelsTitle") }),
1033
+ /* @__PURE__ */ jsx10("p", { className: "adn-settings__hint", children: label("settings.channelsHint") }),
1034
+ categories.map((category) => /* @__PURE__ */ jsxs10("div", { className: "adn-settings__category", children: [
1035
+ /* @__PURE__ */ jsx10("p", { className: "adn-settings__category-label", children: category.label }),
1036
+ category.hint && /* @__PURE__ */ jsx10("p", { className: "adn-settings__hint", children: category.hint }),
1037
+ /* @__PURE__ */ jsx10("div", { className: "adn-settings__channel-grid", children: channels.map((channel) => /* @__PURE__ */ jsxs10("label", { className: "adn-settings__channel", children: [
1038
+ /* @__PURE__ */ jsx10(
398
1039
  "input",
399
1040
  {
400
1041
  type: "checkbox",
@@ -403,194 +1044,396 @@ function NotificationSettingsWorkspace({
403
1044
  onChange: () => toggle(category.id, channel.id)
404
1045
  }
405
1046
  ),
406
- /* @__PURE__ */ jsxs6("span", { children: [
407
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__channel-label", children: channel.label }),
408
- channel.hint && /* @__PURE__ */ jsx6("span", { className: "adn-settings__hint", children: channel.hint })
1047
+ /* @__PURE__ */ jsxs10("span", { children: [
1048
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__channel-label", children: channel.label }),
1049
+ channel.hint && /* @__PURE__ */ jsx10("span", { className: "adn-settings__hint", children: channel.hint })
409
1050
  ] })
410
1051
  ] }, channel.id)) })
411
1052
  ] }, category.id))
412
1053
  ] }),
413
- tab === "messages" && /* @__PURE__ */ jsxs6("div", { className: "adn-settings__templates", children: [
414
- /* @__PURE__ */ jsxs6("section", { className: "adn-settings__template-list", children: [
415
- /* @__PURE__ */ jsxs6("header", { className: "adn-settings__list-header", children: [
416
- /* @__PURE__ */ jsxs6("div", { children: [
417
- /* @__PURE__ */ jsx6("h2", { className: "adn-settings__section-title", children: label("settings.templatesTitle") }),
418
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.templatesHint") })
1054
+ tab === "messages" && /* @__PURE__ */ jsxs10("div", { className: editor.draft ? "adn-settings__templates" : "adn-settings__templates adn-settings__templates--browsing", children: [
1055
+ /* @__PURE__ */ jsxs10("section", { className: "adn-settings__template-list", children: [
1056
+ /* @__PURE__ */ jsx10("header", { className: "adn-settings__list-header", children: /* @__PURE__ */ jsxs10("div", { className: "adn-settings__list-header-row", children: [
1057
+ /* @__PURE__ */ jsx10("h2", { className: "adn-settings__section-title", children: label("settings.templatesTitle") }),
1058
+ /* @__PURE__ */ jsxs10("div", { className: "adn-settings__list-header-actions", children: [
1059
+ /* @__PURE__ */ jsx10("div", { className: "adn-settings__view-switch", role: "group", "aria-label": label("settings.viewLabel"), children: [TEMPLATE_VIEWS.TABLE, TEMPLATE_VIEWS.LIST].map((view) => /* @__PURE__ */ jsx10(
1060
+ "button",
1061
+ {
1062
+ type: "button",
1063
+ "aria-pressed": editor.view === view,
1064
+ className: editor.view === view ? "adn-settings__view adn-settings__view--on" : "adn-settings__view",
1065
+ onClick: () => editor.setView(view),
1066
+ children: label(`settings.view.${view}`)
1067
+ },
1068
+ view
1069
+ )) }),
1070
+ /* @__PURE__ */ jsxs10("button", { type: "button", className: "adn-settings__new", onClick: editor.startNew, children: [
1071
+ /* @__PURE__ */ jsx10(Plus, { className: "adn-settings__button-icon", "aria-hidden": "true" }),
1072
+ label("settings.newTemplate")
1073
+ ] })
1074
+ ] })
1075
+ ] }) }),
1076
+ /* @__PURE__ */ jsxs10("div", { className: "adn-settings__list-filters", children: [
1077
+ /* @__PURE__ */ jsxs10("label", { className: "adn-settings__search", children: [
1078
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__field-label adn-settings__visually-hidden", children: label("settings.searchLabel") }),
1079
+ /* @__PURE__ */ jsx10(
1080
+ "input",
1081
+ {
1082
+ type: "search",
1083
+ value: editor.search,
1084
+ placeholder: label("settings.searchPlaceholder"),
1085
+ onChange: (event) => editor.setSearch(event.target.value)
1086
+ }
1087
+ )
419
1088
  ] }),
420
- /* @__PURE__ */ jsx6("button", { type: "button", className: "adn-settings__new", onClick: editor.startNew, children: label("settings.newTemplate") })
421
- ] }),
422
- editor.isLoading && /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("list.loading") }),
423
- !editor.isLoading && editor.templates.length === 0 && /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.templatesEmpty") }),
424
- /* @__PURE__ */ jsx6("ul", { children: editor.templates.map((template) => /* @__PURE__ */ jsxs6("li", { className: "adn-settings__row", children: [
425
- /* @__PURE__ */ jsxs6(
1089
+ editor.categories.length > 1 && /* @__PURE__ */ jsx10("div", { className: "adn-settings__filter-row", children: editor.categories.map((category) => /* @__PURE__ */ jsx10(
426
1090
  "button",
427
1091
  {
428
1092
  type: "button",
429
- onClick: () => editor.select(template),
430
- className: editor.selected?.id === template.id ? "adn-settings__row--active" : void 0,
431
- children: [
432
- /* @__PURE__ */ jsxs6("span", { className: "adn-settings__row-main", children: [
433
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__row-title", children: templateLabelOf?.(template) ?? template.key }),
434
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__row-body", children: template.body })
435
- ] }),
436
- /* @__PURE__ */ jsx6("span", { className: `adn-settings__badge adn-settings__badge--${template.channel}`, children: label(`channel.${template.channel}`) }),
437
- /* @__PURE__ */ jsxs6("span", { className: "adn-settings__version", children: [
438
- label("settings.version"),
439
- template.version
440
- ] })
441
- ]
442
- }
443
- ),
444
- /* @__PURE__ */ jsx6(
1093
+ "aria-pressed": editor.categoryFilter.includes(category),
1094
+ className: editor.categoryFilter.includes(category) ? "adn-settings__filter adn-settings__filter--on" : "adn-settings__filter",
1095
+ onClick: () => editor.toggleCategoryFilter(category),
1096
+ children: categoryLabelOf?.(category) ?? category
1097
+ },
1098
+ category
1099
+ )) }),
1100
+ /* @__PURE__ */ jsx10("div", { className: "adn-settings__filter-row", children: channels.map((channel) => /* @__PURE__ */ jsx10(
445
1101
  "button",
446
1102
  {
447
1103
  type: "button",
448
- className: "adn-settings__remove",
449
- "aria-label": `${label("settings.remove")} ${template.key}`,
450
- disabled: editor.isDeactivating,
451
- onClick: () => editor.deactivate(template.id),
452
- children: label("settings.remove")
453
- }
454
- )
455
- ] }, template.id)) })
456
- ] }),
457
- /* @__PURE__ */ jsxs6("section", { className: "adn-settings__editor", children: [
458
- !editor.draft && /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.pickTemplate") }),
459
- editor.draft && /* @__PURE__ */ jsxs6(Fragment, { children: [
460
- /* @__PURE__ */ jsxs6("header", { className: "adn-settings__editor-header", children: [
461
- /* @__PURE__ */ jsxs6("div", { children: [
462
- /* @__PURE__ */ jsx6("h2", { className: "adn-settings__section-title", children: editor.selected ? templateLabelOf?.(editor.selected) ?? editor.selected.key : "" }),
463
- /* @__PURE__ */ jsxs6("p", { className: "adn-settings__hint", children: [
464
- editor.draft.channel,
465
- " \xB7 ",
466
- editor.draft.locale,
467
- " \xB7 ",
468
- label("settings.version"),
469
- editor.selected?.version
470
- ] })
471
- ] }),
472
- /* @__PURE__ */ jsx6("button", { type: "button", onClick: editor.clear, children: label("settings.close") })
1104
+ "aria-pressed": editor.channelFilter.includes(channel.id),
1105
+ className: editor.channelFilter.includes(channel.id) ? "adn-settings__filter adn-settings__filter--on" : "adn-settings__filter",
1106
+ onClick: () => editor.toggleChannelFilter(channel.id),
1107
+ children: channel.label
1108
+ },
1109
+ channel.id
1110
+ )) }),
1111
+ editor.hasFilters && /* @__PURE__ */ jsx10("button", { type: "button", className: "adn-settings__clear", onClick: editor.clearFilters, children: label("settings.clearFilters") })
1112
+ ] }),
1113
+ editor.isLoading && /* @__PURE__ */ jsx10("p", { className: "adn-settings__hint", children: label("list.loading") }),
1114
+ !editor.isLoading && editor.totalCount === 0 && /* @__PURE__ */ jsx10("p", { className: "adn-settings__hint", children: label("settings.templatesEmpty") }),
1115
+ !editor.isLoading && editor.totalCount > 0 && editor.templates.length === 0 && /* @__PURE__ */ jsx10("p", { className: "adn-settings__hint", children: label("settings.noResults") }),
1116
+ editor.view === TEMPLATE_VIEWS.TABLE && editor.templates.length > 0 && /* `overflow-x` no contêiner: a página nunca rola na horizontal (web.md §10). */
1117
+ /* @__PURE__ */ jsx10("div", { className: "adn-settings__table-scroll", children: /* @__PURE__ */ jsxs10("table", { className: "adn-settings__table", children: [
1118
+ /* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsx10("tr", { children: TEMPLATE_COLUMNS.map(({ labelKey, field, headerHidden }) => /* @__PURE__ */ jsx10("th", { scope: "col", "aria-sort": field ? ariaSortOf(field) : void 0, children: field ? /* @__PURE__ */ jsxs10("button", { type: "button", onClick: () => editor.toggleSort(field), children: [
1119
+ label(labelKey),
1120
+ /* @__PURE__ */ jsx10("span", { "aria-hidden": "true", className: "adn-settings__sort-mark", children: sortMarkOf(field) })
1121
+ ] }) : /* @__PURE__ */ jsx10("span", { className: headerHidden ? "adn-settings__visually-hidden" : void 0, children: label(labelKey) }) }, labelKey)) }) }),
1122
+ /* @__PURE__ */ jsx10("tbody", { children: editor.templates.map((template) => (
1123
+ /* A linha inteira abre o template: na tabela so a celula da chave era clicavel,
1124
+ e o alvo real de quem varre a lista e a linha. O botao da chave continua
1125
+ existindo — e ele que recebe o foco pelo teclado. */
1126
+ /* @__PURE__ */ jsxs10(
1127
+ "tr",
1128
+ {
1129
+ onClick: () => editor.select(template),
1130
+ className: editor.selected?.id === template.id ? "adn-settings__table-row adn-settings__table-row--active" : "adn-settings__table-row",
1131
+ children: [
1132
+ /* @__PURE__ */ jsx10("td", { children: /* @__PURE__ */ jsx10(
1133
+ "button",
1134
+ {
1135
+ type: "button",
1136
+ className: "adn-settings__table-key",
1137
+ onClick: () => editor.select(template),
1138
+ children: templateLabelOf?.(template) ?? template.key
1139
+ }
1140
+ ) }),
1141
+ /* @__PURE__ */ jsx10("td", { className: "adn-settings__table-body", children: template.body }),
1142
+ /* @__PURE__ */ jsx10("td", { children: /* @__PURE__ */ jsx10("span", { className: `adn-settings__badge adn-settings__badge--${template.channel}`, children: label(`channel.${template.channel}`) }) }),
1143
+ /* @__PURE__ */ jsxs10("td", { className: "adn-settings__version", children: [
1144
+ label("settings.version"),
1145
+ template.version
1146
+ ] }),
1147
+ /* @__PURE__ */ jsx10("td", { children: /* @__PURE__ */ jsxs10(
1148
+ "button",
1149
+ {
1150
+ type: "button",
1151
+ className: "adn-settings__remove",
1152
+ "aria-label": `${label("settings.remove")} ${template.key}`,
1153
+ disabled: editor.isDeactivating,
1154
+ onClick: (event) => {
1155
+ event.stopPropagation();
1156
+ editor.deactivate(template.id);
1157
+ },
1158
+ children: [
1159
+ /* @__PURE__ */ jsx10(Trash22, { className: "adn-settings__button-icon", "aria-hidden": "true" }),
1160
+ label("settings.remove")
1161
+ ]
1162
+ }
1163
+ ) })
1164
+ ]
1165
+ },
1166
+ template.id
1167
+ )
1168
+ )) })
1169
+ ] }) }),
1170
+ editor.view === TEMPLATE_VIEWS.LIST && editor.groups.map((group) => /* @__PURE__ */ jsxs10("div", { className: "adn-settings__group", children: [
1171
+ /* @__PURE__ */ jsxs10("p", { className: "adn-settings__group-title", children: [
1172
+ categoryLabelOf?.(group.category) ?? group.category,
1173
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__group-count", children: group.templates.length })
473
1174
  ] }),
474
- !editor.isIdentityLocked && /* @__PURE__ */ jsxs6("div", { className: "adn-settings__identity", children: [
475
- /* @__PURE__ */ jsxs6("label", { className: "adn-settings__field", children: [
476
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__field-label", children: label("settings.key") }),
477
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__hint", children: label("settings.keyHint") }),
478
- /* @__PURE__ */ jsx6("input", { value: editor.draft.key, onChange: (event) => editor.update({ key: event.target.value }) })
479
- ] }),
480
- /* @__PURE__ */ jsxs6("label", { className: "adn-settings__field", children: [
481
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__field-label", children: label("settings.channel") }),
482
- /* @__PURE__ */ jsx6(
483
- "select",
484
- {
485
- value: editor.draft.channel,
486
- onChange: (event) => editor.update({ channel: event.target.value }),
487
- children: channels.map((channel) => /* @__PURE__ */ jsx6("option", { value: channel.id, children: channel.label }, channel.id))
488
- }
489
- )
490
- ] }),
491
- /* @__PURE__ */ jsxs6("label", { className: "adn-settings__field", children: [
492
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__field-label", children: label("settings.locale") }),
493
- /* @__PURE__ */ jsx6(
494
- "input",
495
- {
496
- value: editor.draft.locale,
497
- onChange: (event) => editor.update({ locale: event.target.value })
498
- }
499
- )
1175
+ /* @__PURE__ */ jsx10("ul", { children: group.templates.map((template) => /* @__PURE__ */ jsxs10("li", { className: "adn-settings__row", children: [
1176
+ /* @__PURE__ */ jsxs10(
1177
+ "button",
1178
+ {
1179
+ type: "button",
1180
+ onClick: () => editor.select(template),
1181
+ className: editor.selected?.id === template.id ? "adn-settings__row--active" : void 0,
1182
+ children: [
1183
+ /* @__PURE__ */ jsxs10("span", { className: "adn-settings__row-main", children: [
1184
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__row-title", children: templateLabelOf?.(template) ?? template.key }),
1185
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__row-body", children: template.body })
1186
+ ] }),
1187
+ /* @__PURE__ */ jsx10("span", { className: `adn-settings__badge adn-settings__badge--${template.channel}`, children: label(`channel.${template.channel}`) }),
1188
+ /* @__PURE__ */ jsxs10("span", { className: "adn-settings__version", children: [
1189
+ label("settings.version"),
1190
+ template.version
1191
+ ] })
1192
+ ]
1193
+ }
1194
+ ),
1195
+ /* @__PURE__ */ jsxs10(
1196
+ "button",
1197
+ {
1198
+ type: "button",
1199
+ className: "adn-settings__remove",
1200
+ "aria-label": `${label("settings.remove")} ${template.key}`,
1201
+ disabled: editor.isDeactivating,
1202
+ onClick: () => editor.deactivate(template.id),
1203
+ children: [
1204
+ /* @__PURE__ */ jsx10(Trash22, { className: "adn-settings__button-icon", "aria-hidden": "true" }),
1205
+ label("settings.remove")
1206
+ ]
1207
+ }
1208
+ )
1209
+ ] }, template.id)) })
1210
+ ] }, group.category))
1211
+ ] }),
1212
+ editor.draft && /* @__PURE__ */ jsx10("section", { className: "adn-settings__editor", children: /* @__PURE__ */ jsxs10(Fragment2, { children: [
1213
+ /* @__PURE__ */ jsxs10("header", { className: "adn-settings__editor-header", children: [
1214
+ /* @__PURE__ */ jsxs10("div", { children: [
1215
+ /* @__PURE__ */ jsx10("h2", { className: "adn-settings__section-title", children: editor.selected ? templateLabelOf?.(editor.selected) ?? editor.selected.key : "" }),
1216
+ /* @__PURE__ */ jsxs10("p", { className: "adn-settings__hint", children: [
1217
+ editor.draft.channels.join(" \xB7 "),
1218
+ " \xB7 ",
1219
+ editor.draft.locale,
1220
+ " \xB7 ",
1221
+ label("settings.version"),
1222
+ editor.selected?.version
500
1223
  ] })
501
1224
  ] }),
502
- editor.variables.length > 0 && /* @__PURE__ */ jsxs6("div", { className: "adn-settings__variables", children: [
503
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__field-label", children: label("settings.variablesTitle") }),
504
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.variablesHint") }),
505
- /* @__PURE__ */ jsx6("ul", { children: editor.variables.map((variable) => {
506
- const used = editor.variableDiff.used.includes(variable.name);
507
- const missing = editor.variableDiff.missingRequired.includes(variable.name);
508
- return /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsxs6(
509
- "button",
1225
+ /* @__PURE__ */ jsxs10("button", { type: "button", className: "adn-settings__close", onClick: editor.clear, children: [
1226
+ /* @__PURE__ */ jsx10(X, { className: "adn-settings__button-icon", "aria-hidden": "true" }),
1227
+ label("settings.close")
1228
+ ] })
1229
+ ] }),
1230
+ !editor.isIdentityLocked && /* @__PURE__ */ jsxs10("div", { className: "adn-settings__identity", children: [
1231
+ /* @__PURE__ */ jsxs10("label", { className: "adn-settings__field", children: [
1232
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__field-label", children: label("settings.key") }),
1233
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__hint", children: label("settings.keyHint") }),
1234
+ /* @__PURE__ */ jsx10("input", { value: editor.draft.key, onChange: (event) => editor.update({ key: event.target.value }) })
1235
+ ] }),
1236
+ /* @__PURE__ */ jsxs10("fieldset", { className: "adn-settings__field adn-settings__field--channels", children: [
1237
+ /* @__PURE__ */ jsx10("legend", { className: "adn-settings__field-label", children: label("settings.channel") }),
1238
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__hint", children: label("settings.channelHint") }),
1239
+ /* @__PURE__ */ jsx10("div", { className: "adn-settings__channel-picker", children: channels.map((channel) => /* @__PURE__ */ jsxs10("label", { className: "adn-settings__channel-chip", children: [
1240
+ /* @__PURE__ */ jsx10(
1241
+ "input",
510
1242
  {
511
- type: "button",
512
- className: [
513
- "adn-settings__variable",
514
- used ? "adn-settings__variable--used" : "",
515
- missing ? "adn-settings__variable--missing" : ""
516
- ].filter(Boolean).join(" "),
517
- onClick: () => editor.insertVariable({ ...cursor, name: variable.name }),
518
- children: [
519
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__variable-name", children: `{{${variable.name}}}` }),
520
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__hint", children: variable.example })
521
- ]
1243
+ type: "checkbox",
1244
+ checked: editor.draft?.channels.includes(channel.id) ?? false,
1245
+ onChange: () => {
1246
+ editor.toggleChannel(channel.id);
1247
+ if (!editor.draft?.channels.includes(channel.id)) setActiveChannel(channel.id);
1248
+ }
522
1249
  }
523
- ) }, variable.name);
524
- }) })
525
- ] }),
526
- editor.variableDiff.unknown.length > 0 && /* @__PURE__ */ jsxs6("p", { className: "adn-settings__error", children: [
527
- label("settings.unknownVariables"),
528
- " ",
529
- editor.variableDiff.unknown.join(", ")
1250
+ ),
1251
+ /* @__PURE__ */ jsx10("span", { children: channel.label })
1252
+ ] }, channel.id)) })
530
1253
  ] }),
531
- /* @__PURE__ */ jsxs6("label", { className: "adn-settings__field", children: [
532
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__field-label", children: label("settings.subject") }),
533
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__hint", children: label("settings.subjectHint") }),
534
- /* @__PURE__ */ jsx6(
1254
+ /* @__PURE__ */ jsxs10("label", { className: "adn-settings__field", children: [
1255
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__field-label", children: label("settings.locale") }),
1256
+ /* @__PURE__ */ jsx10(
535
1257
  "input",
536
1258
  {
537
- value: editor.draft.subject,
538
- onChange: (event) => editor.update({ subject: event.target.value }),
539
- onSelect: (event) => rememberCursor("subject", event.currentTarget.selectionStart)
1259
+ value: editor.draft.locale,
1260
+ onChange: (event) => editor.update({ locale: event.target.value })
540
1261
  }
541
1262
  )
542
- ] }),
543
- /* @__PURE__ */ jsxs6("label", { className: "adn-settings__field", children: [
544
- /* @__PURE__ */ jsx6("span", { className: "adn-settings__field-label", children: label("settings.body") }),
545
- /* @__PURE__ */ jsx6(
546
- "textarea",
1263
+ ] })
1264
+ ] }),
1265
+ editor.variables.length > 0 && /* @__PURE__ */ jsxs10("div", { className: "adn-settings__variables", children: [
1266
+ /* @__PURE__ */ jsx10("p", { className: "adn-settings__field-label", children: label("settings.variablesTitle") }),
1267
+ /* @__PURE__ */ jsx10("p", { className: "adn-settings__hint", children: label("settings.variablesHint") }),
1268
+ /* @__PURE__ */ jsx10("ul", { children: editor.variables.map((variable) => {
1269
+ const used = editor.variableDiff.used.includes(variable.name);
1270
+ const missing = editor.variableDiff.missingRequired.includes(variable.name);
1271
+ return /* @__PURE__ */ jsx10("li", { children: /* @__PURE__ */ jsxs10(
1272
+ "button",
547
1273
  {
548
- rows: 4,
549
- value: editor.draft.body,
550
- onChange: (event) => editor.update({ body: event.target.value }),
551
- onSelect: (event) => rememberCursor("body", event.currentTarget.selectionStart)
1274
+ type: "button",
1275
+ className: [
1276
+ "adn-settings__variable",
1277
+ used ? "adn-settings__variable--used" : "",
1278
+ missing ? "adn-settings__variable--missing" : ""
1279
+ ].filter(Boolean).join(" "),
1280
+ onClick: () => editor.insertVariable({
1281
+ ...cursor,
1282
+ name: variable.name,
1283
+ channel: cursorChannel ?? editor.draft?.channels[0] ?? ""
1284
+ }),
1285
+ children: [
1286
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__variable-name", children: `{{${variable.name}}}` }),
1287
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__hint", children: variable.example })
1288
+ ]
552
1289
  }
553
- )
554
- ] }),
555
- renderChannelFields?.({
556
- channel: editor.draft.channel,
557
- value: editor.draft.whatsappTemplateName,
558
- onChange: (value) => editor.update({ whatsappTemplateName: value })
559
- }),
560
- editor.previews.length > 0 && /* @__PURE__ */ jsxs6("div", { className: "adn-settings__previews", children: [
561
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__preview-title", children: label("settings.previewTitle") }),
562
- /* @__PURE__ */ jsx6("div", { className: "adn-settings__preview-frames", children: editor.previews.map((frame) => /* @__PURE__ */ jsxs6("figure", { className: "adn-settings__preview", children: [
563
- /* @__PURE__ */ jsxs6("figcaption", { className: "adn-settings__hint", children: [
564
- label(`settings.viewport.${frame.viewport}`),
565
- " \xB7 ",
566
- frame.width,
567
- "px"
568
- ] }),
569
- /* @__PURE__ */ jsxs6("div", { className: "adn-settings__preview-frame", style: { width: frame.width }, children: [
570
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__preview-subject", children: frame.rendered.title }),
571
- /* @__PURE__ */ jsx6("p", { className: "adn-settings__preview-body", children: frame.rendered.body })
572
- ] }),
573
- frame.rendered.constraints.filter((constraint) => constraint.exceeded).map((constraint) => /* @__PURE__ */ jsxs6("p", { className: "adn-settings__preview-warning", children: [
574
- label(`settings.constraint.${constraint.field}`),
575
- " ",
576
- constraint.actual,
577
- "/",
578
- constraint.limit
579
- ] }, constraint.field))
580
- ] }, frame.viewport)) })
581
- ] }),
582
- editor.error && /* @__PURE__ */ jsx6("p", { className: "adn-settings__error", children: editor.error }),
583
- /* @__PURE__ */ jsxs6("div", { className: "adn-settings__actions", children: [
584
- /* @__PURE__ */ jsx6("button", { type: "button", onClick: editor.save, disabled: !editor.isDirty || !editor.canSave || editor.isSaving, children: editor.isSaving ? label("settings.saving") : label("settings.save") }),
585
- !editor.isDirty && /* @__PURE__ */ jsx6("span", { className: "adn-settings__hint", children: label("settings.unchanged") })
586
- ] })
1290
+ ) }, variable.name);
1291
+ }) })
1292
+ ] }),
1293
+ editor.variableDiff.unknown.length > 0 && /* @__PURE__ */ jsxs10("p", { className: "adn-settings__error", children: [
1294
+ label("settings.unknownVariables"),
1295
+ " ",
1296
+ editor.variableDiff.unknown.join(", ")
1297
+ ] }),
1298
+ /* @__PURE__ */ jsx10("div", { className: "adn-settings__channel-tabs", role: "tablist", children: channels.filter((channel) => editor.draft?.channels.includes(channel.id)).map((channel) => {
1299
+ const vazio = (editor.draft?.byChannel[channel.id]?.body ?? "").length === 0;
1300
+ const ativo = (activeChannel ?? editor.draft?.channels[0]) === channel.id;
1301
+ return /* @__PURE__ */ jsxs10(
1302
+ "button",
1303
+ {
1304
+ type: "button",
1305
+ role: "tab",
1306
+ "aria-selected": ativo,
1307
+ className: ativo ? "adn-settings__tab adn-settings__tab--active" : "adn-settings__tab",
1308
+ onClick: () => setActiveChannel(channel.id),
1309
+ children: [
1310
+ channel.label,
1311
+ vazio && /* @__PURE__ */ jsx10("span", { className: "adn-settings__tab-dot", "aria-hidden": "true" })
1312
+ ]
1313
+ },
1314
+ channel.id
1315
+ );
1316
+ }) }),
1317
+ channels.filter((channel) => editor.draft?.channels.includes(channel.id)).filter((channel) => (activeChannel ?? editor.draft?.channels[0]) === channel.id).map((channel) => {
1318
+ const content = editor.draft?.byChannel[channel.id];
1319
+ const frames = editor.previews.filter((frame) => frame.channel === channel.id);
1320
+ return /* @__PURE__ */ jsxs10("section", { className: "adn-settings__channel-block", children: [
1321
+ /* @__PURE__ */ jsxs10("header", { className: "adn-settings__channel-block-header", children: [
1322
+ /* @__PURE__ */ jsx10("h3", { className: "adn-settings__preview-channel", children: channel.label }),
1323
+ channel.hint && /* @__PURE__ */ jsx10("span", { className: "adn-settings__hint", children: channel.hint })
1324
+ ] }),
1325
+ /* @__PURE__ */ jsxs10("label", { className: "adn-settings__field", children: [
1326
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__field-label", children: label("settings.subject") }),
1327
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__hint", children: label("settings.subjectHint") }),
1328
+ /* @__PURE__ */ jsx10(
1329
+ "input",
1330
+ {
1331
+ value: content?.subject ?? "",
1332
+ onChange: (event) => editor.updateChannel(channel.id, { subject: event.target.value }),
1333
+ onSelect: (event) => rememberCursor("subject", event.currentTarget.selectionStart),
1334
+ onFocus: () => setCursorChannel(channel.id)
1335
+ }
1336
+ )
1337
+ ] }),
1338
+ /* @__PURE__ */ jsxs10("label", { className: "adn-settings__field", children: [
1339
+ /* @__PURE__ */ jsx10("span", { className: "adn-settings__field-label", children: label("settings.body") }),
1340
+ channel.id === "email" && isHtmlBody(content?.body ?? "") ? /* @__PURE__ */ jsx10(
1341
+ HtmlCodeField,
1342
+ {
1343
+ value: content?.body ?? "",
1344
+ onChange: (next) => editor.updateChannel(channel.id, { body: next }),
1345
+ onSelect: (cursorIndex) => rememberCursor("body", cursorIndex),
1346
+ onFocus: () => setCursorChannel(channel.id),
1347
+ ...validateEmailHtml ? { problems: validateEmailHtml(content?.body ?? "").problems } : {}
1348
+ }
1349
+ ) : /* @__PURE__ */ jsx10(
1350
+ MessageBodyField,
1351
+ {
1352
+ value: content?.body ?? "",
1353
+ onChange: (next) => editor.updateChannel(channel.id, { body: next }),
1354
+ onSelect: (cursorIndex) => rememberCursor("body", cursorIndex),
1355
+ onFocus: () => setCursorChannel(channel.id),
1356
+ labelOf: label
1357
+ }
1358
+ )
1359
+ ] }),
1360
+ renderChannelFields?.({
1361
+ channel: channel.id,
1362
+ value: content?.whatsappTemplateName ?? "",
1363
+ onChange: (value) => editor.updateChannel(channel.id, { whatsappTemplateName: value })
1364
+ }),
1365
+ frames.length > 0 && /* @__PURE__ */ jsxs10("div", { className: "adn-settings__previews", children: [
1366
+ /* @__PURE__ */ jsx10("p", { className: "adn-settings__preview-title", children: label("settings.previewTitle") }),
1367
+ /* @__PURE__ */ jsx10("div", { className: "adn-settings__preview-frames", children: frames.map((frame) => /* @__PURE__ */ jsxs10("figure", { className: "adn-settings__preview", children: [
1368
+ /* @__PURE__ */ jsxs10("figcaption", { className: "adn-settings__hint", children: [
1369
+ label(`settings.viewport.${frame.viewport}`),
1370
+ " \xB7 ",
1371
+ frame.width,
1372
+ "px"
1373
+ ] }),
1374
+ /* @__PURE__ */ jsx10(
1375
+ "div",
1376
+ {
1377
+ className: "adn-settings__preview-frame",
1378
+ style: { "--adn-preview-width": `${frame.width}px` },
1379
+ children: /* @__PURE__ */ jsx10(
1380
+ TemplatePreview,
1381
+ {
1382
+ channel: frame.channel,
1383
+ viewport: frame.viewport,
1384
+ rendered: frame.rendered,
1385
+ ...frame.channel === "email" && isHtmlBody(content?.body ?? "") ? { emailHtml: content?.body ?? "" } : {},
1386
+ labels: {
1387
+ to: label("preview.to"),
1388
+ now: label("preview.now"),
1389
+ mailbox: label("preview.mailbox"),
1390
+ time: label("preview.time"),
1391
+ address: label("preview.address"),
1392
+ counter: label("preview.counter"),
1393
+ folder: label("preview.folder"),
1394
+ senderAddress: label("preview.senderAddress"),
1395
+ unsubscribe: label("preview.unsubscribe"),
1396
+ online: label("preview.online"),
1397
+ today: label("preview.today"),
1398
+ compose: label("preview.compose"),
1399
+ reply: label("preview.reply"),
1400
+ forward: label("preview.forward"),
1401
+ replyAll: label("preview.replyAll")
1402
+ },
1403
+ ...senderName ? { senderName } : {}
1404
+ }
1405
+ )
1406
+ }
1407
+ ),
1408
+ frame.rendered.constraints.filter((constraint) => constraint.exceeded).map((constraint) => /* @__PURE__ */ jsxs10("p", { className: "adn-settings__preview-warning", children: [
1409
+ label(`settings.constraint.${constraint.field}`),
1410
+ " ",
1411
+ constraint.actual,
1412
+ "/",
1413
+ constraint.limit
1414
+ ] }, constraint.field))
1415
+ ] }, `${frame.channel}:${frame.viewport}`)) })
1416
+ ] })
1417
+ ] }, channel.id);
1418
+ }),
1419
+ editor.error && /* @__PURE__ */ jsx10("p", { className: "adn-settings__error", children: editor.error }),
1420
+ /* @__PURE__ */ jsxs10("div", { className: "adn-settings__actions", children: [
1421
+ /* @__PURE__ */ jsx10("button", { type: "button", onClick: editor.save, disabled: !editor.isDirty || !editor.canSave || editor.isSaving, children: editor.isSaving ? label("settings.saving") : label("settings.save") }),
1422
+ !editor.isDirty && /* @__PURE__ */ jsx10("span", { className: "adn-settings__hint", children: label("settings.unchanged") })
587
1423
  ] })
588
- ] })
1424
+ ] }) })
589
1425
  ] })
590
1426
  ] });
591
1427
  }
592
1428
  export {
593
1429
  DEFAULT_LOCALE,
1430
+ HTML_TOKEN,
1431
+ HtmlCodeField,
1432
+ MESSAGE_EMOJI,
1433
+ MESSAGE_FORMAT,
1434
+ MESSAGE_FORMAT_MARKS,
1435
+ MessageBodyField,
1436
+ MessageToolbar,
594
1437
  NOTIFICATION_QUERY_KEYS,
595
1438
  NotificationBell,
596
1439
  NotificationItem,
@@ -599,10 +1442,17 @@ export {
599
1442
  NotificationSettingsWorkspace,
600
1443
  NotificationsWorkspace,
601
1444
  PreferencesPanel,
1445
+ SORT_DIRECTIONS,
1446
+ TEMPLATE_COLUMNS,
1447
+ TEMPLATE_SORT_FIELDS,
1448
+ TEMPLATE_VIEWS,
1449
+ applyMark,
602
1450
  flattenNotificationPages,
603
1451
  formatNotificationTime,
604
1452
  formatNotificationTimestamp,
1453
+ insertAt,
605
1454
  resolveMessages,
1455
+ tokenizeHtml,
606
1456
  useCategoryPolicies,
607
1457
  useDeactivateTemplate,
608
1458
  useDeleteNotification,