handoff fixes
This commit is contained in:
parent
aabb63f947
commit
3f4bcc26d9
4 changed files with 137 additions and 28 deletions
|
|
@ -2,6 +2,8 @@ import { Mail, UserRound, X } from "lucide-react";
|
|||
import { useEffect, useMemo, useState } from "react";
|
||||
import AgentSpark from "./AgentSpark";
|
||||
import {
|
||||
ALL_MAIL_LABEL,
|
||||
ALL_TYPES_ID,
|
||||
buildHandoffSummary,
|
||||
EMAIL_TYPE_OPTIONS,
|
||||
HANDOFF_LABELS,
|
||||
|
|
@ -62,19 +64,33 @@ export default function HumanHandoffDrawer({
|
|||
);
|
||||
|
||||
function toggleLabel(label) {
|
||||
setLabels((current) => (
|
||||
current.includes(label)
|
||||
? current.filter((item) => item !== label)
|
||||
: [...current, label]
|
||||
));
|
||||
if (label === ALL_MAIL_LABEL) {
|
||||
setLabels((current) => (
|
||||
current.includes(ALL_MAIL_LABEL) ? [] : [ALL_MAIL_LABEL]
|
||||
));
|
||||
return;
|
||||
}
|
||||
setLabels((current) => {
|
||||
const withoutAll = current.filter((item) => item !== ALL_MAIL_LABEL);
|
||||
return withoutAll.includes(label)
|
||||
? withoutAll.filter((item) => item !== label)
|
||||
: [...withoutAll, label];
|
||||
});
|
||||
}
|
||||
|
||||
function toggleEmailType(typeId) {
|
||||
setEmailTypes((current) => (
|
||||
current.includes(typeId)
|
||||
? current.filter((item) => item !== typeId)
|
||||
: [...current, typeId]
|
||||
));
|
||||
if (typeId === ALL_TYPES_ID) {
|
||||
setEmailTypes((current) => (
|
||||
current.includes(ALL_TYPES_ID) ? [] : [ALL_TYPES_ID]
|
||||
));
|
||||
return;
|
||||
}
|
||||
setEmailTypes((current) => {
|
||||
const withoutAll = current.filter((item) => item !== ALL_TYPES_ID);
|
||||
return withoutAll.includes(typeId)
|
||||
? withoutAll.filter((item) => item !== typeId)
|
||||
: [...withoutAll, typeId];
|
||||
});
|
||||
}
|
||||
|
||||
function insertExample(example) {
|
||||
|
|
@ -137,7 +153,10 @@ export default function HumanHandoffDrawer({
|
|||
|
||||
<section className="handoff-form-section">
|
||||
<h3>Hand off emails with these labels</h3>
|
||||
<p className="handoff-helper">An email matching any selected label will be eligible for handoff.</p>
|
||||
<p className="handoff-helper">
|
||||
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.
|
||||
</p>
|
||||
<div className="handoff-label-toolbar">
|
||||
<input
|
||||
type="search"
|
||||
|
|
@ -145,7 +164,13 @@ export default function HumanHandoffDrawer({
|
|||
value={labelQuery}
|
||||
onChange={(event) => setLabelQuery(event.target.value)}
|
||||
/>
|
||||
<button type="button" onClick={() => setLabels([...HANDOFF_LABELS])}>Select all</button>
|
||||
<button type="button" onClick={() => setLabels([ALL_MAIL_LABEL])}>All mail</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setLabels(HANDOFF_LABELS.filter((label) => label !== ALL_MAIL_LABEL))}
|
||||
>
|
||||
Select categories
|
||||
</button>
|
||||
</div>
|
||||
<div className="handoff-label-grid">
|
||||
{filteredLabels.map((label) => (
|
||||
|
|
@ -163,7 +188,10 @@ export default function HumanHandoffDrawer({
|
|||
|
||||
<section className="handoff-form-section">
|
||||
<h3>Hand off these types of email</h3>
|
||||
<p className="handoff-helper">Emails matching any selected type can be considered for handoff.</p>
|
||||
<p className="handoff-helper">
|
||||
Types are also inferred from email content. Choose <strong>All types</strong> if you
|
||||
do not want to restrict by category.
|
||||
</p>
|
||||
<div className="handoff-type-grid">
|
||||
{EMAIL_TYPE_OPTIONS.map((type) => (
|
||||
<label key={type.id} className={`handoff-type-card${emailTypes.includes(type.id) ? " selected" : ""}`}>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,22 @@
|
|||
export const HANDOFF_LABELS = ["Important", "Finance", "Clients", "Projects", "Personal", "Support"];
|
||||
export const ALL_MAIL_LABEL = "All mail";
|
||||
export const ALL_TYPES_ID = "all";
|
||||
|
||||
export const HANDOFF_LABELS = [
|
||||
ALL_MAIL_LABEL,
|
||||
"Important",
|
||||
"Finance",
|
||||
"Clients",
|
||||
"Projects",
|
||||
"Personal",
|
||||
"Support",
|
||||
];
|
||||
|
||||
export const EMAIL_TYPE_OPTIONS = [
|
||||
{
|
||||
id: ALL_TYPES_ID,
|
||||
title: "All types",
|
||||
description: "Any incoming email, regardless of category",
|
||||
},
|
||||
{
|
||||
id: "utility",
|
||||
title: "Utility",
|
||||
|
|
@ -46,12 +62,16 @@ export function buildHandoffSummary({
|
|||
emailTypes,
|
||||
instructions,
|
||||
}) {
|
||||
const labelText = labels?.length
|
||||
? `${joinOrNone(labels)} emails`
|
||||
: "eligible emails";
|
||||
const typeText = emailTypes?.length
|
||||
? typeTitles(emailTypes).join(" or ").toLowerCase()
|
||||
: "any type";
|
||||
const labelText = labels?.includes(ALL_MAIL_LABEL)
|
||||
? "All incoming emails"
|
||||
: labels?.length
|
||||
? `${joinOrNone(labels)} emails`
|
||||
: "eligible emails";
|
||||
const typeText = emailTypes?.includes(ALL_TYPES_ID)
|
||||
? "any type"
|
||||
: emailTypes?.length
|
||||
? typeTitles(emailTypes).join(" or ").toLowerCase()
|
||||
: "any type";
|
||||
const instructionText = instructions?.trim()
|
||||
? "when they require your personal decision or attention"
|
||||
: "when your handoff instructions apply";
|
||||
|
|
@ -61,8 +81,14 @@ export function buildHandoffSummary({
|
|||
|
||||
export function buildRuleCardSummary(rule) {
|
||||
const parts = [];
|
||||
if (rule.labels?.length) parts.push(rule.labels.join(", "));
|
||||
if (rule.email_types?.length) {
|
||||
if (rule.labels?.includes(ALL_MAIL_LABEL)) {
|
||||
parts.push("All mail");
|
||||
} else if (rule.labels?.length) {
|
||||
parts.push(rule.labels.join(", "));
|
||||
}
|
||||
if (rule.email_types?.includes(ALL_TYPES_ID)) {
|
||||
parts.push("All types");
|
||||
} else if (rule.email_types?.length) {
|
||||
parts.push(typeTitles(rule.email_types).join(", "));
|
||||
}
|
||||
const meta = parts.length ? parts.join(" • ") : "All eligible emails";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue