handoff minor fixes
This commit is contained in:
parent
d4bb4df40d
commit
48eea5d201
8 changed files with 99 additions and 28 deletions
|
|
@ -132,6 +132,37 @@ function selectionInside(editor) {
|
||||||
return { selection, range };
|
return { selection, range };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ALIGN_BY_COMMAND = {
|
||||||
|
justifyLeft: "left",
|
||||||
|
justifyCenter: "center",
|
||||||
|
justifyRight: "right",
|
||||||
|
};
|
||||||
|
|
||||||
|
function alignmentBlock(editor, range) {
|
||||||
|
if (!editor || !range) return null;
|
||||||
|
let node = range.startContainer;
|
||||||
|
if (node.nodeType !== Node.ELEMENT_NODE) node = node.parentElement;
|
||||||
|
const block = node?.closest?.("li, p, div, blockquote, h1, h2, h3, h4");
|
||||||
|
if (!block || !editor.contains(block)) return null;
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
function explicitAlignment(block) {
|
||||||
|
if (!block) return "";
|
||||||
|
const value = (block.style?.textAlign || block.getAttribute?.("align") || "").toLowerCase();
|
||||||
|
if (value === "center") return "center";
|
||||||
|
if (value === "right" || value === "end") return "right";
|
||||||
|
if (value === "left" || value === "start") return "left";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearAlignment(block) {
|
||||||
|
if (!block) return;
|
||||||
|
block.style.textAlign = "";
|
||||||
|
if (!block.getAttribute("style")) block.removeAttribute("style");
|
||||||
|
block.removeAttribute("align");
|
||||||
|
}
|
||||||
|
|
||||||
function FormatButton({ title, active, onClick, children }) {
|
function FormatButton({ title, active, onClick, children }) {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|
@ -389,14 +420,17 @@ export default function ComposeModal({
|
||||||
|
|
||||||
function updateFormatState() {
|
function updateFormatState() {
|
||||||
try {
|
try {
|
||||||
|
const editor = editorRef.current;
|
||||||
|
const current = selectionInside(editor);
|
||||||
|
const align = explicitAlignment(alignmentBlock(editor, current?.range));
|
||||||
setFormatState({
|
setFormatState({
|
||||||
bold: document.queryCommandState("bold"),
|
bold: document.queryCommandState("bold"),
|
||||||
italic: document.queryCommandState("italic"),
|
italic: document.queryCommandState("italic"),
|
||||||
underline: document.queryCommandState("underline"),
|
underline: document.queryCommandState("underline"),
|
||||||
strikeThrough: document.queryCommandState("strikeThrough"),
|
strikeThrough: document.queryCommandState("strikeThrough"),
|
||||||
justifyLeft: document.queryCommandState("justifyLeft"),
|
justifyLeft: align === "left",
|
||||||
justifyCenter: document.queryCommandState("justifyCenter"),
|
justifyCenter: align === "center",
|
||||||
justifyRight: document.queryCommandState("justifyRight"),
|
justifyRight: align === "right",
|
||||||
insertUnorderedList: document.queryCommandState("insertUnorderedList"),
|
insertUnorderedList: document.queryCommandState("insertUnorderedList"),
|
||||||
insertOrderedList: document.queryCommandState("insertOrderedList"),
|
insertOrderedList: document.queryCommandState("insertOrderedList"),
|
||||||
});
|
});
|
||||||
|
|
@ -408,7 +442,16 @@ export default function ComposeModal({
|
||||||
function execFormat(command, value = null) {
|
function execFormat(command, value = null) {
|
||||||
restoreSelection();
|
restoreSelection();
|
||||||
document.execCommand("defaultParagraphSeparator", false, "div");
|
document.execCommand("defaultParagraphSeparator", false, "div");
|
||||||
document.execCommand(command, false, value);
|
const align = ALIGN_BY_COMMAND[command];
|
||||||
|
if (align) {
|
||||||
|
const editor = editorRef.current;
|
||||||
|
const current = selectionInside(editor);
|
||||||
|
const block = alignmentBlock(editor, current?.range);
|
||||||
|
if (explicitAlignment(block) === align) clearAlignment(block);
|
||||||
|
else document.execCommand(command, false, value);
|
||||||
|
} else {
|
||||||
|
document.execCommand(command, false, value);
|
||||||
|
}
|
||||||
saveSelection();
|
saveSelection();
|
||||||
syncBodyFromEditor();
|
syncBodyFromEditor();
|
||||||
updateFormatState();
|
updateFormatState();
|
||||||
|
|
@ -678,12 +721,14 @@ export default function ComposeModal({
|
||||||
orgDomain={orgDomain}
|
orgDomain={orgDomain}
|
||||||
inline
|
inline
|
||||||
autoFocus
|
autoFocus
|
||||||
|
trailing={(!showCc || !showBcc) ? (
|
||||||
|
<div className="compose-recipient-toggles">
|
||||||
|
{!showCc && <button type="button" onClick={() => setShowCc(true)}>Cc</button>}
|
||||||
|
{!showBcc && <button type="button" onClick={() => setShowBcc(true)}>Bcc</button>}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="compose-recipient-toggles">
|
|
||||||
{!showCc && <button type="button" onClick={() => setShowCc(true)}>Cc</button>}
|
|
||||||
{!showBcc && <button type="button" onClick={() => setShowBcc(true)}>Bcc</button>}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{showCc && (
|
{showCc && (
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ export default function DashboardPage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeMobileMenu() {
|
function closeMobileMenu() {
|
||||||
if (window.matchMedia("(max-width: 767px)").matches) {
|
if (window.matchMedia("(max-width: 767.98px)").matches) {
|
||||||
setMenuOpen(false);
|
setMenuOpen(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +219,7 @@ export default function DashboardPage() {
|
||||||
setLens("all");
|
setLens("all");
|
||||||
setAgentNav(actionKey);
|
setAgentNav(actionKey);
|
||||||
closeMobileMenu();
|
closeMobileMenu();
|
||||||
const compact = window.matchMedia("(max-width: 1199px)").matches;
|
const compact = window.matchMedia("(max-width: 1199.98px)").matches;
|
||||||
setSheet(actionKey === "handoff" || !compact ? null : "agent");
|
setSheet(actionKey === "handoff" || !compact ? null : "agent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import {
|
||||||
} from "../api";
|
} from "../api";
|
||||||
import AgentSpark from "./AgentSpark";
|
import AgentSpark from "./AgentSpark";
|
||||||
import HumanHandoffDrawer from "./HumanHandoffDrawer";
|
import HumanHandoffDrawer from "./HumanHandoffDrawer";
|
||||||
import { buildRuleCardChips } from "../utils/handoffUtils";
|
import { buildRuleCardChips, typeLabel } from "../utils/handoffUtils";
|
||||||
|
|
||||||
function ruleScope(rule) {
|
function ruleScope(rule) {
|
||||||
return buildRuleCardChips(rule).filter((chip) => chip !== rule.name).join(" · ");
|
return buildRuleCardChips(rule).filter((chip) => chip !== rule.name).join(" · ");
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,9 @@ export default function HumanHandoffDrawer({
|
||||||
<div className="handoff-drawer-body">
|
<div className="handoff-drawer-body">
|
||||||
<section className="handoff-form-section">
|
<section className="handoff-form-section">
|
||||||
<h3>Rule</h3>
|
<h3>Rule</h3>
|
||||||
<label className="handoff-field-label" htmlFor="handoff-rule-name">Rule name</label>
|
<label className="handoff-field-label" htmlFor="handoff-rule-name">
|
||||||
|
Rule name <span className="handoff-required" aria-hidden="true">*</span>
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
id="handoff-rule-name"
|
id="handoff-rule-name"
|
||||||
className="handoff-text-input"
|
className="handoff-text-input"
|
||||||
|
|
@ -152,7 +154,9 @@ export default function HumanHandoffDrawer({
|
||||||
|
|
||||||
<section className="handoff-form-section">
|
<section className="handoff-form-section">
|
||||||
<h3>Human owner</h3>
|
<h3>Human owner</h3>
|
||||||
<label className="handoff-field-label" htmlFor="handoff-owner-email">Owner email address</label>
|
<label className="handoff-field-label" htmlFor="handoff-owner-email">
|
||||||
|
Owner email address <span className="handoff-required" aria-hidden="true">*</span>
|
||||||
|
</label>
|
||||||
<div className="handoff-email-input">
|
<div className="handoff-email-input">
|
||||||
<Mail size={16} strokeWidth={1.75} />
|
<Mail size={16} strokeWidth={1.75} />
|
||||||
<input
|
<input
|
||||||
|
|
@ -178,7 +182,7 @@ export default function HumanHandoffDrawer({
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="handoff-form-section">
|
<section className="handoff-form-section">
|
||||||
<h3>Hand off emails with these labels</h3>
|
<h3>Hand off emails with these labels <span className="handoff-required" aria-hidden="true">*</span></h3>
|
||||||
<p className="handoff-helper">
|
<p className="handoff-helper">
|
||||||
These are content-based handoff categories, not inbox tabs. Gentic infers them from
|
These are content-based handoff categories, not inbox tabs. Gentic infers them from
|
||||||
subject and body text. Choose <strong>All mail</strong> to hand off every incoming email.
|
subject and body text. Choose <strong>All mail</strong> to hand off every incoming email.
|
||||||
|
|
@ -213,7 +217,7 @@ export default function HumanHandoffDrawer({
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="handoff-form-section">
|
<section className="handoff-form-section">
|
||||||
<h3>Hand off these types of email</h3>
|
<h3>Hand off these types of email <span className="handoff-required" aria-hidden="true">*</span></h3>
|
||||||
<p className="handoff-helper">
|
<p className="handoff-helper">
|
||||||
Types are also inferred from email content. Choose <strong>All types</strong> if you
|
Types are also inferred from email content. Choose <strong>All types</strong> if you
|
||||||
do not want to restrict by category.
|
do not want to restrict by category.
|
||||||
|
|
@ -234,7 +238,7 @@ export default function HumanHandoffDrawer({
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="handoff-form-section">
|
<section className="handoff-form-section">
|
||||||
<h3>When should the agent hand off?</h3>
|
<h3>When should the agent hand off? <span className="handoff-required" aria-hidden="true">*</span></h3>
|
||||||
<p className="handoff-helper">Write this naturally, just as you would instruct your agent.</p>
|
<p className="handoff-helper">Write this naturally, just as you would instruct your agent.</p>
|
||||||
<textarea
|
<textarea
|
||||||
className="handoff-instructions"
|
className="handoff-instructions"
|
||||||
|
|
@ -298,7 +302,14 @@ export default function HumanHandoffDrawer({
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="handoff-btn primary"
|
className="handoff-btn primary"
|
||||||
disabled={saving || !ruleName.trim() || !ownerEmail.trim()}
|
disabled={
|
||||||
|
saving
|
||||||
|
|| !ruleName.trim()
|
||||||
|
|| !ownerEmail.trim()
|
||||||
|
|| !labels.length
|
||||||
|
|| !emailTypes.length
|
||||||
|
|| !instructions.trim()
|
||||||
|
}
|
||||||
onClick={() => onSave({
|
onClick={() => onSave({
|
||||||
name: ruleName.trim(),
|
name: ruleName.trim(),
|
||||||
priority,
|
priority,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ export default function RecipientField({
|
||||||
onFocus,
|
onFocus,
|
||||||
autoFocus = false,
|
autoFocus = false,
|
||||||
inline = false,
|
inline = false,
|
||||||
|
trailing = null,
|
||||||
}) {
|
}) {
|
||||||
const [input, setInput] = useState("");
|
const [input, setInput] = useState("");
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
@ -138,6 +139,7 @@ export default function RecipientField({
|
||||||
<div className={`compose-recipient-field${inline ? " inline" : ""}`} ref={wrapRef}>
|
<div className={`compose-recipient-field${inline ? " inline" : ""}`} ref={wrapRef}>
|
||||||
{label ? <span className="compose-recipient-label">{label}</span> : null}
|
{label ? <span className="compose-recipient-label">{label}</span> : null}
|
||||||
<div className="compose-recipient-chips" onClick={() => inputRef.current?.focus()}>
|
<div className="compose-recipient-chips" onClick={() => inputRef.current?.focus()}>
|
||||||
|
{trailing}
|
||||||
{recipients.map((recipient, index) => (
|
{recipients.map((recipient, index) => (
|
||||||
<span
|
<span
|
||||||
key={`${recipientKey(recipient)}-${index}`}
|
key={`${recipientKey(recipient)}-${index}`}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
.shell-sheet-bar,
|
.shell-sheet-bar,
|
||||||
.mobile-more-layer { display:none; }
|
.mobile-more-layer { display:none; }
|
||||||
|
|
||||||
@media (min-width:768px) and (max-width:1199px) {
|
@media (min-width:768px) and (max-width:1199.98px) {
|
||||||
html,body { overflow-x:clip; }
|
html,body { overflow-x:clip; }
|
||||||
.dashboard { display:grid; grid-template-columns:72px minmax(0,1fr); overflow-x:clip; }
|
.dashboard { display:grid; grid-template-columns:72px minmax(0,1fr); overflow-x:clip; }
|
||||||
.dashboard-mobile-header { display:none; }
|
.dashboard-mobile-header { display:none; }
|
||||||
|
|
@ -157,7 +157,7 @@
|
||||||
.dashboard-sidebar.open .dashboard-profile > button { display:grid; }
|
.dashboard-sidebar.open .dashboard-profile > button { display:grid; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width:767px) {
|
@media (max-width:767.98px) {
|
||||||
html,body { overflow-x:clip; }
|
html,body { overflow-x:clip; }
|
||||||
.dashboard { display:block; min-height:100vh; overflow-x:clip; }
|
.dashboard { display:block; min-height:100vh; overflow-x:clip; }
|
||||||
.dashboard-mobile-header {
|
.dashboard-mobile-header {
|
||||||
|
|
@ -501,7 +501,7 @@
|
||||||
.dashboard-notice { left:16px; right:16px; bottom:calc(76px + env(safe-area-inset-bottom)); }
|
.dashboard-notice { left:16px; right:16px; bottom:calc(76px + env(safe-area-inset-bottom)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width:1199px) {
|
@media (max-width:1199.98px) {
|
||||||
.mailbox-rail.shell-calendar .agent-panel-hello,
|
.mailbox-rail.shell-calendar .agent-panel-hello,
|
||||||
.mailbox-rail.shell-calendar .agent-stat-grid,
|
.mailbox-rail.shell-calendar .agent-stat-grid,
|
||||||
.mailbox-rail.shell-calendar .agent-quick,
|
.mailbox-rail.shell-calendar .agent-quick,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@import url("https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=Manrope:wght@400;500;600;700&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Manrope:wght@400;500;600;700&display=swap");
|
||||||
|
|
||||||
:root { font-family:"DM Sans",sans-serif; color:#080821; background:#fffdfb; font-synthesis:none; --ink:#080821; --muted:#67677a; --coral:#ff6a52; --blush:#fff3ef; --line:#eee9e5; --canvas:#F5F4F2; --workspace:#f0eeeb; --surface:#ffffff; --agent:#7656e8; --agent-soft:#f6f2ff; --agent-border:#ddd4ff; --info:#4d74c4; --info-soft:#eef4ff; --success:#3d8a5d; --success-soft:#eef8f2; --attention:#b7892d; --attention-soft:#fff8ea; --navy:#171329; --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px; --space-5:20px; --space-6:24px; --space-7:32px; --text-content:14px; --text-meta:12px; --text-control:13px; --text-micro:11px; --line-content:1.45; --line-meta:1.4; --radius-xs:6px; --radius-sm:8px; --radius-md:10px; --radius-lg:12px; --radius-xl:16px; --radius-float:20px; --radius-pill:999px; --border-subtle:rgba(20,20,30,0.05); --border-normal:rgba(20,20,30,0.08); --border-strong:rgba(20,20,30,0.12); --shadow-surface:0 1px 2px rgba(20,20,30,0.04),0 12px 32px rgba(20,20,30,0.06); --shadow-float:0 8px 30px rgba(0,0,0,0.08); --shadow-accent:0 5px 14px rgba(255,95,80,0.16); --icon-stroke:1.75; --motion-fast:140ms; --motion-base:180ms; --motion-slow:200ms; --ease-standard:cubic-bezier(.2,.8,.2,1); }
|
:root { font-family:"DM Sans",sans-serif; color:#080821; background:#fffdfb; font-synthesis:none; --ink:#080821; --muted:#67677a; --coral:#ff6a52; --blush:#fff3ef; --line:#eee9e5; --canvas:#F5F4F2; --workspace:#f0eeeb; --surface:#ffffff; --agent:#7656e8; --agent-soft:#f6f2ff; --agent-border:#ddd4ff; --info:#4d74c4; --info-soft:#eef4ff; --success:#3d8a5d; --success-soft:#eef8f2; --attention:#b7892d; --attention-soft:#fff8ea; --navy:#171329; --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px; --space-5:20px; --space-6:24px; --space-7:32px; --text-content:14px; --text-meta:12px; --text-control:13px; --text-micro:11px; --line-content:1.45; --line-meta:1.4; --radius-xs:6px; --radius-sm:8px; --radius-md:10px; --radius-lg:12px; --radius-xl:16px; --radius-float:20px; --radius-pill:999px; --border-subtle:rgba(20,20,30,0.05); --border-normal:rgba(20,20,30,0.08); --border-strong:rgba(20,20,30,0.12); --shadow-surface:0 1px 2px rgba(20,20,30,0.04),0 12px 32px rgba(20,20,30,0.06); --shadow-float:0 8px 30px rgba(0,0,0,0.08); --shadow-accent:0 5px 14px rgba(255,95,80,0.16); --icon-stroke:1.75; --motion-fast:140ms; --motion-base:180ms; --motion-slow:200ms; --ease-standard:cubic-bezier(.2,.8,.2,1); }
|
||||||
* { box-sizing:border-box; }
|
* { box-sizing:border-box; }
|
||||||
|
|
@ -774,9 +774,14 @@ h1 em { color:var(--coral); font-style:normal; font-weight:500; }
|
||||||
.handoff-drawer-foot { padding:14px 22px 18px; display:flex; justify-content:flex-end; gap:8px; border-top:1px solid #f0eef2; background:#fcfbfd; }
|
.handoff-drawer-foot { padding:14px 22px 18px; display:flex; justify-content:flex-end; gap:8px; border-top:1px solid #f0eef2; background:#fcfbfd; }
|
||||||
.handoff-form-section h3 { margin:0 0 8px; font:700 13px/1.3 "DM Sans"; color:#171424; text-transform:none; letter-spacing:0; }
|
.handoff-form-section h3 { margin:0 0 8px; font:700 13px/1.3 "DM Sans"; color:#171424; text-transform:none; letter-spacing:0; }
|
||||||
.handoff-field-label { display:block; margin-bottom:6px; font-size:11px; font-weight:600; color:#5a5562; }
|
.handoff-field-label { display:block; margin-bottom:6px; font-size:11px; font-weight:600; color:#5a5562; }
|
||||||
|
.handoff-required { color:#e15b45; font-weight:700; }
|
||||||
.handoff-helper { margin:8px 0 0; color:#77758a; font-size:11px; line-height:1.5; }
|
.handoff-helper { margin:8px 0 0; color:#77758a; font-size:11px; line-height:1.5; }
|
||||||
.handoff-email-input,.handoff-text-input { width:100%; min-height:42px; padding:0 12px; display:flex; align-items:center; gap:8px; border:1px solid #e4e1e8; border-radius:10px; background:#fff; }
|
.handoff-email-input,.handoff-text-input { width:100%; min-height:42px; padding:0 12px; display:flex; align-items:center; gap:8px; border:1px solid #e4e1e8; border-radius:10px; background:#fff; }
|
||||||
.handoff-email-input input,.handoff-text-input { width:100%; border:0; outline:0; background:transparent; font-size:13px; color:#171424; }
|
.handoff-email-input input,.handoff-text-input { width:100%; border:0; outline:0; background:transparent; font-size:13px; color:#171424; }
|
||||||
|
.handoff-email-input input::placeholder,
|
||||||
|
.handoff-text-input::placeholder,
|
||||||
|
.handoff-label-toolbar input::placeholder,
|
||||||
|
.handoff-instructions::placeholder { color:#c4bfc8; }
|
||||||
.handoff-owner-preview { margin-top:10px; padding:10px 12px; display:flex; align-items:center; gap:10px; border:1px solid #ece9f2; border-radius:10px; background:#faf9fc; }
|
.handoff-owner-preview { margin-top:10px; padding:10px 12px; display:flex; align-items:center; gap:10px; border:1px solid #ece9f2; border-radius:10px; background:#faf9fc; }
|
||||||
.handoff-owner-avatar { width:34px; height:34px; display:grid; place-items:center; border-radius:50%; background:#f6f2ff; color:#7357f6; }
|
.handoff-owner-avatar { width:34px; height:34px; display:grid; place-items:center; border-radius:50%; background:#f6f2ff; color:#7357f6; }
|
||||||
.handoff-owner-preview strong { display:block; font-size:13px; }
|
.handoff-owner-preview strong { display:block; font-size:13px; }
|
||||||
|
|
@ -1094,16 +1099,19 @@ h1 em { color:var(--coral); font-style:normal; font-weight:500; }
|
||||||
.compose-row { height:44px; padding:0 var(--compose-pad); display:grid; grid-template-columns:var(--compose-label) minmax(0,1fr) auto; align-items:center; gap:12px; border-bottom:1px solid #ECE9EE; flex-shrink:0; }
|
.compose-row { height:44px; padding:0 var(--compose-pad); display:grid; grid-template-columns:var(--compose-label) minmax(0,1fr) auto; align-items:center; gap:12px; border-bottom:1px solid #ECE9EE; flex-shrink:0; }
|
||||||
.compose-row-label { color:#77717a; font-size:11px; font-weight:700; }
|
.compose-row-label { color:#77717a; font-size:11px; font-weight:700; }
|
||||||
.compose-row-main { min-width:0; }
|
.compose-row-main { min-width:0; }
|
||||||
.compose-recipient-row .compose-row-main { display:flex; align-items:center; min-height:28px; }
|
.compose-recipient-row { height:auto; min-height:44px; padding-top:8px; padding-bottom:8px; align-items:start; grid-template-columns:var(--compose-label) minmax(0,1fr); }
|
||||||
.compose-recipient-toggles { display:flex; align-items:center; gap:12px; align-self:center; }
|
.compose-recipient-row .compose-row-label { line-height:28px; }
|
||||||
|
.compose-recipient-row .compose-row-main { display:block; min-height:28px; }
|
||||||
|
.compose-recipient-toggles { float:right; height:28px; margin-left:10px; display:flex; align-items:center; gap:12px; }
|
||||||
.compose-recipient-toggles button { padding:0; border:0; background:transparent; color:#847e87; font-size:10px; font-weight:700; line-height:1; }
|
.compose-recipient-toggles button { padding:0; border:0; background:transparent; color:#847e87; font-size:10px; font-weight:700; line-height:1; }
|
||||||
.compose-recipient-toggles button:hover { color:#bc5948; }
|
.compose-recipient-toggles button:hover { color:#bc5948; }
|
||||||
.compose-recipient-field { position:relative; width:100%; }
|
.compose-recipient-field { position:relative; width:100%; }
|
||||||
.compose-recipient-field.inline { display:block; }
|
.compose-recipient-field.inline { display:block; }
|
||||||
.compose-recipient-chips { min-height:28px; display:flex; flex-wrap:wrap; align-items:center; gap:6px; }
|
.compose-recipient-chips { min-height:28px; display:block; }
|
||||||
.compose-recipient-input { flex:1; min-width:80px; height:28px; border:0; border-radius:0; outline:none; background:transparent; color:var(--ink); font:500 12px/28px "DM Sans"; box-shadow:none; }
|
.compose-recipient-input { width:40px; min-width:40px; max-width:100%; height:28px; margin:0; border:0; border-radius:0; outline:none; background:transparent; color:var(--ink); font:500 12px/28px "DM Sans"; box-shadow:none; vertical-align:middle; }
|
||||||
|
.compose-recipient-chips:not(:has(.compose-chip)) .compose-recipient-input { width:160px; }
|
||||||
.compose-recipient-input:focus { outline:none; box-shadow:none; }
|
.compose-recipient-input:focus { outline:none; box-shadow:none; }
|
||||||
.compose-chip { max-width:100%; height:24px; padding:0 4px 0 8px; display:inline-flex; align-items:center; gap:4px; border-radius:6px; background:#f3efec; color:var(--ink); font-size:11px; font-weight:600; }
|
.compose-chip { max-width:100%; height:24px; margin:2px 6px 2px 0; padding:0 4px 0 8px; display:inline-flex; align-items:center; vertical-align:middle; gap:4px; border-radius:6px; background:#f3efec; color:var(--ink); font-size:11px; font-weight:600; }
|
||||||
.compose-chip.external { background:#fff4ea; color:#9a5b28; }
|
.compose-chip.external { background:#fff4ea; color:#9a5b28; }
|
||||||
.compose-chip.invalid { background:#fdeeed; color:#b54f3d; }
|
.compose-chip.invalid { background:#fdeeed; color:#b54f3d; }
|
||||||
.compose-chip.group { background:#eef4ff; color:#4d74c4; }
|
.compose-chip.group { background:#eef4ff; color:#4d74c4; }
|
||||||
|
|
@ -1131,6 +1139,7 @@ h1 em { color:var(--coral); font-style:normal; font-weight:500; }
|
||||||
.compose-attachment-actions button { padding:3px 4px; border:0; border-radius:4px; background:transparent; color:#8a848d; font-size:8px; font-weight:700; }
|
.compose-attachment-actions button { padding:3px 4px; border:0; border-radius:4px; background:transparent; color:#8a848d; font-size:8px; font-weight:700; }
|
||||||
.compose-attachment-actions button:hover { background:#f3efec; color:var(--ink); }
|
.compose-attachment-actions button:hover { background:#f3efec; color:var(--ink); }
|
||||||
.compose-editor { min-height:160px; flex:1; padding:16px; overflow:auto; outline:none; color:var(--ink); font:400 13px/1.6 "DM Sans"; background:#fff; }
|
.compose-editor { min-height:160px; flex:1; padding:16px; overflow:auto; outline:none; color:var(--ink); font:400 13px/1.6 "DM Sans"; background:#fff; }
|
||||||
|
.compose-editor i,.compose-editor em,.compose-editor span[style*="italic"] { font-style:italic; }
|
||||||
.compose-editor:focus { outline:none; box-shadow:none; }
|
.compose-editor:focus { outline:none; box-shadow:none; }
|
||||||
.compose-editor:empty:before { content:attr(data-placeholder); color:#aaa4ac; pointer-events:none; }
|
.compose-editor:empty:before { content:attr(data-placeholder); color:#aaa4ac; pointer-events:none; }
|
||||||
.compose-editor blockquote { margin:8px 0; padding-left:12px; border-left:3px solid #e5dfd9; color:#67677a; }
|
.compose-editor blockquote { margin:8px 0; padding-left:12px; border-left:3px solid #e5dfd9; color:#67677a; }
|
||||||
|
|
@ -1297,7 +1306,7 @@ body.compose-blank-open .mailbox-empty-cta { opacity:.42; filter:saturate(.55);
|
||||||
.dns-copy { width:28px; height:28px; flex:0 0 auto; display:grid; place-items:center; border:1px solid #ece7e3; border-radius:8px; background:white; color:#67677a; }
|
.dns-copy { width:28px; height:28px; flex:0 0 auto; display:grid; place-items:center; border:1px solid #ece7e3; border-radius:8px; background:white; color:#67677a; }
|
||||||
.link-button { border:0; background:transparent; color:var(--coral); font:inherit; font-weight:600; cursor:pointer; padding:0; }
|
.link-button { border:0; background:transparent; color:var(--coral); font:inherit; font-weight:600; cursor:pointer; padding:0; }
|
||||||
.dashboard { grid-template-columns:228px minmax(0,1fr); background:var(--canvas); }
|
.dashboard { grid-template-columns:228px minmax(0,1fr); background:var(--canvas); }
|
||||||
.dashboard-sidebar { width:228px; min-height:100vh; max-height:100vh; padding:var(--space-4) var(--space-3) var(--space-3); display:flex; flex-direction:column; overflow:hidden; border-right:0; color:#d7d3e2; background:linear-gradient(180deg,#171329 0%,#120f24 55%,#100d20 100%); box-shadow:inset -1px 0 0 #ffffff08; position:sticky; top:0; }
|
.dashboard-sidebar { width:228px; min-height:100vh; max-height:100vh; padding:var(--space-4) var(--space-3) var(--space-3); display:flex; flex-direction:column; overflow:hidden; border-right:0; color:#d7d3e2; background:linear-gradient(180deg,#171329 0%,#120f24 55%,#100d20 100%); box-shadow:inset -1px 0 0 #ffffff08; position:sticky; top:0; transform:none; }
|
||||||
.dashboard-brand-row { flex-shrink:0; padding:0 6px 2px; }
|
.dashboard-brand-row { flex-shrink:0; padding:0 6px 2px; }
|
||||||
.dashboard-sidebar-scroll { flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; }
|
.dashboard-sidebar-scroll { flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; }
|
||||||
.dashboard-brand-row>button { color:#c8c3d4; }
|
.dashboard-brand-row>button { color:#c8c3d4; }
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,12 @@ function joinOrNone(items, fallback = "any email") {
|
||||||
return `${items.slice(0, -1).join(", ")} or ${items.at(-1)}`;
|
return `${items.slice(0, -1).join(", ")} or ${items.at(-1)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function typeLabel(id) {
|
||||||
|
return EMAIL_TYPE_OPTIONS.find((item) => item.id === id)?.title || id;
|
||||||
|
}
|
||||||
|
|
||||||
function typeTitles(types) {
|
function typeTitles(types) {
|
||||||
return types.map((id) => EMAIL_TYPE_OPTIONS.find((item) => item.id === id)?.title || id);
|
return types.map(typeLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildHandoffSummary({
|
export function buildHandoffSummary({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue