@handled-ai/design-system 0.18.6 → 0.18.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/components/score-why-chips.d.ts +1 -1
- package/dist/components/signal-priority-popover.d.ts +1 -1
- package/dist/components/timeline-activity.d.ts +16 -1
- package/dist/components/timeline-activity.js +69 -1
- package/dist/components/timeline-activity.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/prototype/index.d.ts +1 -1
- package/dist/prototype/prototype-accounts-view.d.ts +1 -1
- package/dist/prototype/prototype-admin-view.d.ts +1 -1
- package/dist/prototype/prototype-config.d.ts +1 -1
- package/dist/prototype/prototype-inbox-view.d.ts +15 -3
- package/dist/prototype/prototype-inbox-view.js +156 -36
- package/dist/prototype/prototype-inbox-view.js.map +1 -1
- package/dist/prototype/prototype-insights-view.d.ts +1 -1
- package/dist/prototype/prototype-shell.d.ts +1 -1
- package/dist/{signal-priority-popover-DWaAMhPI.d.ts → signal-priority-popover-BT6CPYNs.d.ts} +17 -1
- package/package.json +2 -1
- package/src/components/__tests__/timeline-activity.test.tsx +152 -0
- package/src/components/timeline-activity.tsx +112 -1
- package/src/prototype/__tests__/detail-view-attention.test.tsx +2 -2
- package/src/prototype/__tests__/detail-view-timeline-system-events.test.tsx +409 -0
- package/src/prototype/prototype-config.ts +21 -0
- package/src/prototype/prototype-inbox-view.tsx +227 -30
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { Q as QueueItem, l as SignalScoreData, o as SignalScoreUrgencyLabel } from '../signal-priority-popover-
|
|
2
|
+
import { Q as QueueItem, l as SignalScoreData, o as SignalScoreUrgencyLabel } from '../signal-priority-popover-BT6CPYNs.js';
|
|
3
3
|
import './feedback-primitives.js';
|
|
4
4
|
import './quick-action-sidebar-nav.js';
|
|
5
5
|
import './quick-action-modal.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import 'react';
|
|
2
2
|
import './feedback-primitives.js';
|
|
3
|
-
export { P as PriorityFactor, S as SignalPriorityPopover, k as SignalPriorityPopoverProps } from '../signal-priority-popover-
|
|
3
|
+
export { P as PriorityFactor, S as SignalPriorityPopover, k as SignalPriorityPopoverProps } from '../signal-priority-popover-BT6CPYNs.js';
|
|
4
4
|
import './quick-action-sidebar-nav.js';
|
|
5
5
|
import './quick-action-modal.js';
|
|
6
6
|
import './score-breakdown.js';
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
|
+
type TimelineEventTone = "red" | "amber" | "emerald" | "violet" | "blue" | "slate" | "salesforce" | "gmail";
|
|
4
|
+
interface TimelineEventActor {
|
|
5
|
+
kind: "user" | "integration" | "system";
|
|
6
|
+
name?: string;
|
|
7
|
+
initials?: string;
|
|
8
|
+
avatarUrl?: string;
|
|
9
|
+
verb?: string;
|
|
10
|
+
}
|
|
3
11
|
interface TimelineEvent {
|
|
4
12
|
id: string;
|
|
5
13
|
icon: React.ReactNode;
|
|
@@ -24,11 +32,18 @@ interface TimelineEvent {
|
|
|
24
32
|
defaultExpanded?: boolean;
|
|
25
33
|
isInteractive?: boolean;
|
|
26
34
|
onSourceClick?: () => void;
|
|
35
|
+
tone?: TimelineEventTone;
|
|
36
|
+
actor?: TimelineEventActor;
|
|
37
|
+
isSystemNoise?: boolean;
|
|
27
38
|
}
|
|
39
|
+
declare const TONE_CLASSES: Record<TimelineEventTone, {
|
|
40
|
+
dot: string;
|
|
41
|
+
icon: string;
|
|
42
|
+
}>;
|
|
28
43
|
interface TimelineActivityProps {
|
|
29
44
|
events: TimelineEvent[];
|
|
30
45
|
className?: string;
|
|
31
46
|
}
|
|
32
47
|
declare function TimelineActivity({ events, className }: TimelineActivityProps): React.JSX.Element;
|
|
33
48
|
|
|
34
|
-
export { TimelineActivity, type TimelineActivityProps, type TimelineEvent };
|
|
49
|
+
export { TONE_CLASSES, TimelineActivity, type TimelineActivityProps, type TimelineEvent, type TimelineEventActor, type TimelineEventTone };
|
|
@@ -5,6 +5,42 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { cn } from "../lib/utils.js";
|
|
7
7
|
import { ChevronDown, ChevronUp, ExternalLink } from "lucide-react";
|
|
8
|
+
const TONE_CLASSES = {
|
|
9
|
+
red: {
|
|
10
|
+
dot: "bg-red-50 border-red-200 dark:bg-red-950/30 dark:border-red-900/40",
|
|
11
|
+
icon: "text-red-600 dark:text-red-300"
|
|
12
|
+
},
|
|
13
|
+
amber: {
|
|
14
|
+
dot: "bg-amber-50 border-amber-200 dark:bg-amber-950/30 dark:border-amber-900/40",
|
|
15
|
+
icon: "text-amber-600 dark:text-amber-300"
|
|
16
|
+
},
|
|
17
|
+
emerald: {
|
|
18
|
+
dot: "bg-emerald-50 border-emerald-200 dark:bg-emerald-950/30 dark:border-emerald-900/40",
|
|
19
|
+
icon: "text-emerald-600 dark:text-emerald-300"
|
|
20
|
+
},
|
|
21
|
+
violet: {
|
|
22
|
+
dot: "bg-violet-50 border-violet-200 dark:bg-violet-950/30 dark:border-violet-900/40",
|
|
23
|
+
icon: "text-violet-600 dark:text-violet-300"
|
|
24
|
+
},
|
|
25
|
+
blue: {
|
|
26
|
+
dot: "bg-blue-50 border-blue-200 dark:bg-blue-950/30 dark:border-blue-900/40",
|
|
27
|
+
icon: "text-blue-600 dark:text-blue-300"
|
|
28
|
+
},
|
|
29
|
+
slate: {
|
|
30
|
+
dot: "bg-slate-100 border-slate-200 dark:bg-slate-800/50 dark:border-slate-700",
|
|
31
|
+
icon: "text-slate-500 dark:text-slate-300"
|
|
32
|
+
},
|
|
33
|
+
salesforce: {
|
|
34
|
+
dot: "bg-white border-[#00A1E0]/25 dark:bg-background dark:border-[#00A1E0]/25",
|
|
35
|
+
icon: "text-[#00A1E0]"
|
|
36
|
+
},
|
|
37
|
+
gmail: {
|
|
38
|
+
dot: "bg-white border-red-200 dark:bg-background dark:border-red-900/40",
|
|
39
|
+
icon: "text-red-500 dark:text-red-300"
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const NEUTRAL_DOT_CLASSES = "border-border/60 bg-background";
|
|
43
|
+
const NEUTRAL_ICON_CLASSES = "text-muted-foreground";
|
|
8
44
|
function TimelineActivity({ events, className }) {
|
|
9
45
|
return /* @__PURE__ */ jsx("div", { className: cn("space-y-0", className), children: events.map((event, index) => /* @__PURE__ */ jsx(
|
|
10
46
|
TimelineItem,
|
|
@@ -15,20 +51,51 @@ function TimelineActivity({ events, className }) {
|
|
|
15
51
|
event.id
|
|
16
52
|
)) });
|
|
17
53
|
}
|
|
54
|
+
function ActorByline({ actor, time }) {
|
|
55
|
+
var _a, _b, _c;
|
|
56
|
+
if (actor.kind === "system") return null;
|
|
57
|
+
if (actor.kind === "integration") {
|
|
58
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-1.5 text-xs text-muted-foreground", "data-testid": "actor-byline", children: [
|
|
59
|
+
/* @__PURE__ */ jsx("span", { children: "Integration" }),
|
|
60
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
61
|
+
/* @__PURE__ */ jsx("span", { children: time })
|
|
62
|
+
] });
|
|
63
|
+
}
|
|
64
|
+
const verb = (_a = actor.verb) != null ? _a : "performed this action";
|
|
65
|
+
const displayInitials = (_b = actor.initials) != null ? _b : actor.name ? actor.name.charAt(0).toUpperCase() : "?";
|
|
66
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-1.5 text-xs text-muted-foreground", "data-testid": "actor-byline", children: [
|
|
67
|
+
actor.avatarUrl ? /* @__PURE__ */ jsx(
|
|
68
|
+
"img",
|
|
69
|
+
{
|
|
70
|
+
src: actor.avatarUrl,
|
|
71
|
+
alt: (_c = actor.name) != null ? _c : "User",
|
|
72
|
+
className: "h-4 w-4 rounded-full object-cover"
|
|
73
|
+
}
|
|
74
|
+
) : /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 items-center justify-center rounded-full bg-muted-foreground/10 text-[8px] font-semibold text-muted-foreground", children: displayInitials }),
|
|
75
|
+
actor.name && /* @__PURE__ */ jsx("span", { className: "text-foreground font-medium", children: actor.name }),
|
|
76
|
+
/* @__PURE__ */ jsx("span", { children: verb }),
|
|
77
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
78
|
+
/* @__PURE__ */ jsx("span", { children: time })
|
|
79
|
+
] });
|
|
80
|
+
}
|
|
18
81
|
function TimelineItem({ event, isLast }) {
|
|
19
82
|
var _a, _b, _c, _d;
|
|
20
83
|
const [expanded, setExpanded] = React.useState((_a = event.defaultExpanded) != null ? _a : false);
|
|
21
84
|
const [showAllRecipients, setShowAllRecipients] = React.useState(false);
|
|
22
85
|
const hasContent = !!event.content;
|
|
23
86
|
const hasEmail = !!event.email;
|
|
87
|
+
const toneStyle = event.tone ? TONE_CLASSES[event.tone] : null;
|
|
88
|
+
const dotClasses = toneStyle ? toneStyle.dot : NEUTRAL_DOT_CLASSES;
|
|
89
|
+
const iconClasses = toneStyle ? toneStyle.icon : NEUTRAL_ICON_CLASSES;
|
|
24
90
|
return /* @__PURE__ */ jsxs("div", { className: "group relative flex gap-3.5", children: [
|
|
25
91
|
!isLast && /* @__PURE__ */ jsx("div", { className: "absolute left-[9px] top-5 bottom-[-6px] w-px bg-border/60" }),
|
|
26
|
-
/* @__PURE__ */ jsx("div", { className: "relative z-10 mt-1 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-background", children: /* @__PURE__ */ jsx("div", { className: "flex h-4.5 w-4.5 items-center justify-center rounded-full border
|
|
92
|
+
/* @__PURE__ */ jsx("div", { className: "relative z-10 mt-1 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-background", children: /* @__PURE__ */ jsx("div", { className: cn("flex h-4.5 w-4.5 items-center justify-center rounded-full border ring-4 ring-background", dotClasses, iconClasses), "data-testid": "timeline-dot", children: event.icon }) }),
|
|
27
93
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 pb-5 pt-0.5", children: [
|
|
28
94
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1 sm:flex-row sm:items-start sm:justify-between", children: [
|
|
29
95
|
/* @__PURE__ */ jsx("div", { className: "pr-4 text-[13px] leading-relaxed text-foreground", children: event.title }),
|
|
30
96
|
/* @__PURE__ */ jsx("span", { className: "mt-0.5 shrink-0 whitespace-nowrap text-[11px] text-muted-foreground/70", children: event.time })
|
|
31
97
|
] }),
|
|
98
|
+
event.actor && /* @__PURE__ */ jsx(ActorByline, { actor: event.actor, time: event.time }),
|
|
32
99
|
(hasContent || hasEmail) && /* @__PURE__ */ jsx("div", { className: "mt-2", children: event.isInteractive ? hasEmail ? /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-md border border-border/80 bg-muted/20", children: /* @__PURE__ */ jsx(
|
|
33
100
|
"div",
|
|
34
101
|
{
|
|
@@ -176,6 +243,7 @@ function TimelineItem({ event, isLast }) {
|
|
|
176
243
|
] });
|
|
177
244
|
}
|
|
178
245
|
export {
|
|
246
|
+
TONE_CLASSES,
|
|
179
247
|
TimelineActivity
|
|
180
248
|
};
|
|
181
249
|
//# sourceMappingURL=timeline-activity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/timeline-activity.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../lib/utils\"\nimport { ChevronDown, ChevronUp, ExternalLink } from \"lucide-react\"\n\nexport interface TimelineEvent {\n id: string\n icon: React.ReactNode\n title: React.ReactNode\n time: string\n preview?: React.ReactNode\n email?: {\n from: string\n fromEmail?: string\n to: string\n cc?: string\n bcc?: string\n date?: string\n subject?: string\n body: React.ReactNode\n }\n content?: React.ReactNode\n source?: {\n label: string\n url: string\n }\n defaultExpanded?: boolean\n isInteractive?: boolean\n onSourceClick?: () => void\n}\n\nexport interface TimelineActivityProps {\n events: TimelineEvent[]\n className?: string\n}\n\nexport function TimelineActivity({ events, className }: TimelineActivityProps) {\n return (\n <div className={cn(\"space-y-0\", className)}>\n {events.map((event, index) => (\n <TimelineItem\n key={event.id}\n event={event}\n isLast={index === events.length - 1}\n />\n ))}\n </div>\n )\n}\n\nfunction TimelineItem({ event, isLast }: { event: TimelineEvent; isLast: boolean }) {\n const [expanded, setExpanded] = React.useState(event.defaultExpanded ?? false)\n const [showAllRecipients, setShowAllRecipients] = React.useState(false)\n const hasContent = !!event.content\n const hasEmail = !!event.email\n\n return (\n <div className=\"group relative flex gap-3.5\">\n {!isLast && (\n <div className=\"absolute left-[9px] top-5 bottom-[-6px] w-px bg-border/60\" />\n )}\n\n <div className=\"relative z-10 mt-1 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-background\">\n <div className=\"flex h-4.5 w-4.5 items-center justify-center rounded-full border border-border/60 bg-background text-muted-foreground ring-4 ring-background\">\n {event.icon}\n </div>\n </div>\n\n <div className=\"flex-1 pb-5 pt-0.5\">\n <div className=\"flex min-w-0 flex-col gap-1 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"pr-4 text-[13px] leading-relaxed text-foreground\">\n {event.title}\n </div>\n <span className=\"mt-0.5 shrink-0 whitespace-nowrap text-[11px] text-muted-foreground/70\">\n {event.time}\n </span>\n </div>\n\n {(hasContent || hasEmail) && (\n <div className=\"mt-2\">\n {event.isInteractive ? (\n hasEmail ? (\n <div className=\"overflow-hidden rounded-md border border-border/80 bg-muted/20\">\n <div\n className={cn(\n \"px-3 py-2.5 text-sm\",\n !expanded && \"cursor-pointer hover:bg-muted/30 transition-colors\"\n )}\n onClick={() => !expanded && setExpanded(true)}\n >\n {expanded && event.email ? (\n <div className=\"space-y-3\">\n <div>\n <div className=\"flex items-center justify-between gap-4\">\n <div className=\"flex min-w-0 items-baseline gap-1.5\">\n <span className=\"font-semibold text-foreground text-[13px] whitespace-nowrap\">{event.email.from}</span>\n {event.email.fromEmail && (\n <span className=\"text-muted-foreground/60 text-xs truncate\">{event.email.fromEmail}</span>\n )}\n </div>\n {event.email.date && (\n <span className=\"shrink-0 text-xs text-muted-foreground/50 whitespace-nowrap\">{event.email.date}</span>\n )}\n </div>\n <div className=\"mt-0.5 flex items-center gap-1 text-xs text-muted-foreground\">\n <span className=\"truncate\">\n To {event.email.to}\n {!showAllRecipients && (event.email.cc || event.email.bcc) ? (\n <>, ...</>\n ) : null}\n {showAllRecipients && event.email.cc ? (\n <>, {event.email.cc}</>\n ) : null}\n {showAllRecipients && event.email.bcc ? (\n <> <span className=\"text-muted-foreground/40\">bcc</span> {event.email.bcc}</>\n ) : null}\n </span>\n {(event.email.cc || event.email.bcc) && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n setShowAllRecipients((prev) => !prev)\n }}\n className=\"shrink-0 text-muted-foreground/40 hover:text-muted-foreground transition-colors\"\n >\n <ChevronDown className={cn(\"h-3 w-3 transition-transform\", showAllRecipients && \"rotate-180\")} />\n </button>\n )}\n </div>\n </div>\n\n <div className=\"whitespace-pre-line text-sm leading-relaxed text-foreground/90\">\n {event.email.body}\n </div>\n\n <button\n onClick={(e) => {\n e.stopPropagation()\n setExpanded(false)\n }}\n className=\"mt-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground\"\n >\n Show less <ChevronUp className=\"h-3 w-3\" />\n </button>\n </div>\n ) : (\n <div className=\"flex items-center justify-between gap-2 text-muted-foreground\">\n <span className=\"line-clamp-1 pr-3 text-[13px]\">\n <span className=\"text-muted-foreground\">{event.email?.from}</span>\n <span className=\"mx-1.5 text-muted-foreground/40\">·</span>\n {event.email?.subject ? (\n <>\n <span className=\"text-muted-foreground\">{event.email.subject}</span>\n <span className=\"mx-1.5 text-muted-foreground/40\">·</span>\n </>\n ) : null}\n <span className=\"text-muted-foreground\">{event.preview}</span>\n </span>\n <button className=\"flex shrink-0 items-center gap-1 text-[11px] font-semibold uppercase tracking-wider transition-colors hover:text-foreground\">\n Expand <ChevronDown className=\"h-3 w-3\" />\n </button>\n </div>\n )}\n </div>\n </div>\n ) : (\n <div className=\"overflow-hidden rounded-md border border-border/80 bg-muted/20\">\n <div\n className={cn(\n \"px-3 py-2.5 text-sm\",\n !expanded && \"cursor-pointer hover:bg-muted/30 transition-colors\"\n )}\n onClick={() => !expanded && setExpanded(true)}\n >\n {expanded ? (\n <div className=\"space-y-2\">\n {event.content}\n <div className=\"mt-2 flex items-center gap-3\">\n {event.source ? (\n event.onSourceClick ? (\n <button\n type=\"button\"\n onClick={(e) => { e.stopPropagation(); event.onSourceClick?.(); }}\n className=\"mr-auto inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground\"\n >\n Open in {event.source.label}\n <ExternalLink className=\"h-3 w-3\" />\n </button>\n ) : (\n <a\n href={event.source.url}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n className=\"mr-auto inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground\"\n >\n Open in {event.source.label}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n )\n ) : null}\n <button\n onClick={(e) => { e.stopPropagation(); setExpanded(false); }}\n className=\"flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground\"\n >\n Show less <ChevronUp className=\"h-3 w-3\" />\n </button>\n </div>\n </div>\n ) : (\n <div className=\"flex items-center justify-between gap-2 text-muted-foreground\">\n <span className=\"line-clamp-1 pr-3\">\n {event.preview ?? event.content}\n </span>\n <button className=\"flex shrink-0 items-center gap-1 text-[11px] font-semibold uppercase tracking-wider transition-colors hover:text-foreground\">\n Expand <ChevronDown className=\"h-3 w-3\" />\n </button>\n </div>\n )}\n </div>\n </div>\n )\n ) : (\n <div className=\"pr-2 text-sm leading-relaxed text-muted-foreground\">\n {event.content}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["_a"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/timeline-activity.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../lib/utils\"\nimport { ChevronDown, ChevronUp, ExternalLink } from \"lucide-react\"\n\nexport type TimelineEventTone =\n | \"red\"\n | \"amber\"\n | \"emerald\"\n | \"violet\"\n | \"blue\"\n | \"slate\"\n | \"salesforce\"\n | \"gmail\"\n\nexport interface TimelineEventActor {\n kind: \"user\" | \"integration\" | \"system\"\n name?: string\n initials?: string\n avatarUrl?: string\n verb?: string\n}\n\nexport interface TimelineEvent {\n id: string\n icon: React.ReactNode\n title: React.ReactNode\n time: string\n preview?: React.ReactNode\n email?: {\n from: string\n fromEmail?: string\n to: string\n cc?: string\n bcc?: string\n date?: string\n subject?: string\n body: React.ReactNode\n }\n content?: React.ReactNode\n source?: {\n label: string\n url: string\n }\n defaultExpanded?: boolean\n isInteractive?: boolean\n onSourceClick?: () => void\n tone?: TimelineEventTone\n actor?: TimelineEventActor\n isSystemNoise?: boolean\n}\n\n// ---------------------------------------------------------------------------\n// Tone class map — every class is a complete static string literal so\n// Tailwind's JIT scanner can detect them. NO interpolation.\n// ---------------------------------------------------------------------------\n\nexport const TONE_CLASSES: Record<\n TimelineEventTone,\n { dot: string; icon: string }\n> = {\n red: {\n dot: \"bg-red-50 border-red-200 dark:bg-red-950/30 dark:border-red-900/40\",\n icon: \"text-red-600 dark:text-red-300\",\n },\n amber: {\n dot: \"bg-amber-50 border-amber-200 dark:bg-amber-950/30 dark:border-amber-900/40\",\n icon: \"text-amber-600 dark:text-amber-300\",\n },\n emerald: {\n dot: \"bg-emerald-50 border-emerald-200 dark:bg-emerald-950/30 dark:border-emerald-900/40\",\n icon: \"text-emerald-600 dark:text-emerald-300\",\n },\n violet: {\n dot: \"bg-violet-50 border-violet-200 dark:bg-violet-950/30 dark:border-violet-900/40\",\n icon: \"text-violet-600 dark:text-violet-300\",\n },\n blue: {\n dot: \"bg-blue-50 border-blue-200 dark:bg-blue-950/30 dark:border-blue-900/40\",\n icon: \"text-blue-600 dark:text-blue-300\",\n },\n slate: {\n dot: \"bg-slate-100 border-slate-200 dark:bg-slate-800/50 dark:border-slate-700\",\n icon: \"text-slate-500 dark:text-slate-300\",\n },\n salesforce: {\n dot: \"bg-white border-[#00A1E0]/25 dark:bg-background dark:border-[#00A1E0]/25\",\n icon: \"text-[#00A1E0]\",\n },\n gmail: {\n dot: \"bg-white border-red-200 dark:bg-background dark:border-red-900/40\",\n icon: \"text-red-500 dark:text-red-300\",\n },\n}\n\nconst NEUTRAL_DOT_CLASSES = \"border-border/60 bg-background\"\nconst NEUTRAL_ICON_CLASSES = \"text-muted-foreground\"\n\nexport interface TimelineActivityProps {\n events: TimelineEvent[]\n className?: string\n}\n\nexport function TimelineActivity({ events, className }: TimelineActivityProps) {\n return (\n <div className={cn(\"space-y-0\", className)}>\n {events.map((event, index) => (\n <TimelineItem\n key={event.id}\n event={event}\n isLast={index === events.length - 1}\n />\n ))}\n </div>\n )\n}\n\nfunction ActorByline({ actor, time }: { actor: TimelineEventActor; time: string }) {\n if (actor.kind === \"system\") return null\n\n if (actor.kind === \"integration\") {\n return (\n <div className=\"mt-1 flex items-center gap-1.5 text-xs text-muted-foreground\" data-testid=\"actor-byline\">\n <span>Integration</span>\n <span className=\"text-muted-foreground/40\">·</span>\n <span>{time}</span>\n </div>\n )\n }\n\n // actor.kind === \"user\"\n const verb = actor.verb ?? \"performed this action\"\n const displayInitials = actor.initials ?? (actor.name ? actor.name.charAt(0).toUpperCase() : \"?\")\n\n return (\n <div className=\"mt-1 flex items-center gap-1.5 text-xs text-muted-foreground\" data-testid=\"actor-byline\">\n {actor.avatarUrl ? (\n <img\n src={actor.avatarUrl}\n alt={actor.name ?? \"User\"}\n className=\"h-4 w-4 rounded-full object-cover\"\n />\n ) : (\n <span className=\"flex h-4 w-4 items-center justify-center rounded-full bg-muted-foreground/10 text-[8px] font-semibold text-muted-foreground\">\n {displayInitials}\n </span>\n )}\n {actor.name && <span className=\"text-foreground font-medium\">{actor.name}</span>}\n <span>{verb}</span>\n <span className=\"text-muted-foreground/40\">·</span>\n <span>{time}</span>\n </div>\n )\n}\n\nfunction TimelineItem({ event, isLast }: { event: TimelineEvent; isLast: boolean }) {\n const [expanded, setExpanded] = React.useState(event.defaultExpanded ?? false)\n const [showAllRecipients, setShowAllRecipients] = React.useState(false)\n const hasContent = !!event.content\n const hasEmail = !!event.email\n\n const toneStyle = event.tone ? TONE_CLASSES[event.tone] : null\n const dotClasses = toneStyle ? toneStyle.dot : NEUTRAL_DOT_CLASSES\n const iconClasses = toneStyle ? toneStyle.icon : NEUTRAL_ICON_CLASSES\n\n return (\n <div className=\"group relative flex gap-3.5\">\n {!isLast && (\n <div className=\"absolute left-[9px] top-5 bottom-[-6px] w-px bg-border/60\" />\n )}\n\n <div className=\"relative z-10 mt-1 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-background\">\n <div className={cn(\"flex h-4.5 w-4.5 items-center justify-center rounded-full border ring-4 ring-background\", dotClasses, iconClasses)} data-testid=\"timeline-dot\">\n {event.icon}\n </div>\n </div>\n\n <div className=\"flex-1 pb-5 pt-0.5\">\n <div className=\"flex min-w-0 flex-col gap-1 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"pr-4 text-[13px] leading-relaxed text-foreground\">\n {event.title}\n </div>\n <span className=\"mt-0.5 shrink-0 whitespace-nowrap text-[11px] text-muted-foreground/70\">\n {event.time}\n </span>\n </div>\n\n {event.actor && <ActorByline actor={event.actor} time={event.time} />}\n\n {(hasContent || hasEmail) && (\n <div className=\"mt-2\">\n {event.isInteractive ? (\n hasEmail ? (\n <div className=\"overflow-hidden rounded-md border border-border/80 bg-muted/20\">\n <div\n className={cn(\n \"px-3 py-2.5 text-sm\",\n !expanded && \"cursor-pointer hover:bg-muted/30 transition-colors\"\n )}\n onClick={() => !expanded && setExpanded(true)}\n >\n {expanded && event.email ? (\n <div className=\"space-y-3\">\n <div>\n <div className=\"flex items-center justify-between gap-4\">\n <div className=\"flex min-w-0 items-baseline gap-1.5\">\n <span className=\"font-semibold text-foreground text-[13px] whitespace-nowrap\">{event.email.from}</span>\n {event.email.fromEmail && (\n <span className=\"text-muted-foreground/60 text-xs truncate\">{event.email.fromEmail}</span>\n )}\n </div>\n {event.email.date && (\n <span className=\"shrink-0 text-xs text-muted-foreground/50 whitespace-nowrap\">{event.email.date}</span>\n )}\n </div>\n <div className=\"mt-0.5 flex items-center gap-1 text-xs text-muted-foreground\">\n <span className=\"truncate\">\n To {event.email.to}\n {!showAllRecipients && (event.email.cc || event.email.bcc) ? (\n <>, ...</>\n ) : null}\n {showAllRecipients && event.email.cc ? (\n <>, {event.email.cc}</>\n ) : null}\n {showAllRecipients && event.email.bcc ? (\n <> <span className=\"text-muted-foreground/40\">bcc</span> {event.email.bcc}</>\n ) : null}\n </span>\n {(event.email.cc || event.email.bcc) && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n setShowAllRecipients((prev) => !prev)\n }}\n className=\"shrink-0 text-muted-foreground/40 hover:text-muted-foreground transition-colors\"\n >\n <ChevronDown className={cn(\"h-3 w-3 transition-transform\", showAllRecipients && \"rotate-180\")} />\n </button>\n )}\n </div>\n </div>\n\n <div className=\"whitespace-pre-line text-sm leading-relaxed text-foreground/90\">\n {event.email.body}\n </div>\n\n <button\n onClick={(e) => {\n e.stopPropagation()\n setExpanded(false)\n }}\n className=\"mt-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground\"\n >\n Show less <ChevronUp className=\"h-3 w-3\" />\n </button>\n </div>\n ) : (\n <div className=\"flex items-center justify-between gap-2 text-muted-foreground\">\n <span className=\"line-clamp-1 pr-3 text-[13px]\">\n <span className=\"text-muted-foreground\">{event.email?.from}</span>\n <span className=\"mx-1.5 text-muted-foreground/40\">·</span>\n {event.email?.subject ? (\n <>\n <span className=\"text-muted-foreground\">{event.email.subject}</span>\n <span className=\"mx-1.5 text-muted-foreground/40\">·</span>\n </>\n ) : null}\n <span className=\"text-muted-foreground\">{event.preview}</span>\n </span>\n <button className=\"flex shrink-0 items-center gap-1 text-[11px] font-semibold uppercase tracking-wider transition-colors hover:text-foreground\">\n Expand <ChevronDown className=\"h-3 w-3\" />\n </button>\n </div>\n )}\n </div>\n </div>\n ) : (\n <div className=\"overflow-hidden rounded-md border border-border/80 bg-muted/20\">\n <div\n className={cn(\n \"px-3 py-2.5 text-sm\",\n !expanded && \"cursor-pointer hover:bg-muted/30 transition-colors\"\n )}\n onClick={() => !expanded && setExpanded(true)}\n >\n {expanded ? (\n <div className=\"space-y-2\">\n {event.content}\n <div className=\"mt-2 flex items-center gap-3\">\n {event.source ? (\n event.onSourceClick ? (\n <button\n type=\"button\"\n onClick={(e) => { e.stopPropagation(); event.onSourceClick?.(); }}\n className=\"mr-auto inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground\"\n >\n Open in {event.source.label}\n <ExternalLink className=\"h-3 w-3\" />\n </button>\n ) : (\n <a\n href={event.source.url}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n className=\"mr-auto inline-flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground\"\n >\n Open in {event.source.label}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n )\n ) : null}\n <button\n onClick={(e) => { e.stopPropagation(); setExpanded(false); }}\n className=\"flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground\"\n >\n Show less <ChevronUp className=\"h-3 w-3\" />\n </button>\n </div>\n </div>\n ) : (\n <div className=\"flex items-center justify-between gap-2 text-muted-foreground\">\n <span className=\"line-clamp-1 pr-3\">\n {event.preview ?? event.content}\n </span>\n <button className=\"flex shrink-0 items-center gap-1 text-[11px] font-semibold uppercase tracking-wider transition-colors hover:text-foreground\">\n Expand <ChevronDown className=\"h-3 w-3\" />\n </button>\n </div>\n )}\n </div>\n </div>\n )\n ) : (\n <div className=\"pr-2 text-sm leading-relaxed text-muted-foreground\">\n {event.content}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["_a"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMe
|
|
|
29
29
|
export { EmptyState, EmptyStateProps } from './components/empty-state.js';
|
|
30
30
|
export { ActivityItem, ConnectedApps, EntityActivityItem, EntityDetails, EntityMetadataField, EntityMetadataGrid, EntityPanel, EntityPanelBrandIcons, EntityPanelHeader, EntityPanelTabs, EntitySection, PanelMode, PotentialContacts, RecentActivity, SystemActivity, useEntityPanel } from './components/entity-panel.js';
|
|
31
31
|
export { FeedbackActions, FeedbackActionsProps, FeedbackChipGroup, FeedbackChipGroupProps, FeedbackChipTree, FeedbackFooter, FeedbackFooterProps, FeedbackInput, FeedbackInputProps, FeedbackSubmitData, InlineFeedbackControl, InlineFeedbackControlProps, PersistedFeedbackData } from './components/feedback-primitives.js';
|
|
32
|
-
export { A as AccountFilterTab, a as AccountsViewConfig, b as AdminTab, c as AdminViewConfig, B as BriefStyleVariant, E as EntityPanelConfig, d as EntityPanelSection, I as InboxDetailSections, e as InboxSortOption, f as InboxViewConfig, g as InsightsCustomTab, h as InsightsViewConfig, P as PriorityFactor, i as PrototypeBrandConfig, j as PrototypeConfig, Q as QueueItem, S as SignalPriorityPopover, k as SignalPriorityPopoverProps, l as SignalScoreData, m as SignalScoreExplanationBucket, n as SignalScoreExplanationSignal, o as SignalScoreUrgencyLabel, W as WorkQueueViewConfig } from './signal-priority-popover-
|
|
32
|
+
export { A as AccountFilterTab, a as AccountsViewConfig, b as AdminTab, c as AdminViewConfig, B as BriefStyleVariant, E as EntityPanelConfig, d as EntityPanelSection, I as InboxDetailSections, e as InboxSortOption, f as InboxViewConfig, g as InsightsCustomTab, h as InsightsViewConfig, P as PriorityFactor, i as PrototypeBrandConfig, j as PrototypeConfig, Q as QueueItem, S as SignalPriorityPopover, k as SignalPriorityPopoverProps, l as SignalScoreData, m as SignalScoreExplanationBucket, n as SignalScoreExplanationSignal, o as SignalScoreUrgencyLabel, T as TimelineSystemEventsConfig, W as WorkQueueViewConfig } from './signal-priority-popover-BT6CPYNs.js';
|
|
33
33
|
export { FilterChip, FilterChipProps } from './components/filter-chip.js';
|
|
34
34
|
export { InboxGroupHeader, InboxRow, InboxRowProps } from './components/inbox-row.js';
|
|
35
35
|
export { AssigneeFilter, InboxFilterCategory, InboxToolbar, InboxToolbarProps } from './components/inbox-toolbar.js';
|
|
@@ -81,7 +81,7 @@ export { Switch } from './components/switch.js';
|
|
|
81
81
|
export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from './components/table.js';
|
|
82
82
|
export { Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants } from './components/tabs.js';
|
|
83
83
|
export { Textarea } from './components/textarea.js';
|
|
84
|
-
export { TimelineActivity, TimelineActivityProps, TimelineEvent } from './components/timeline-activity.js';
|
|
84
|
+
export { TONE_CLASSES, TimelineActivity, TimelineActivityProps, TimelineEvent, TimelineEventActor, TimelineEventTone } from './components/timeline-activity.js';
|
|
85
85
|
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './components/tooltip.js';
|
|
86
86
|
export { ActorByline, ActorBylineProps, UserPill, UserPillProps } from './components/user-display.js';
|
|
87
87
|
export { VariableAutocomplete, VariableAutocompleteProps, VariableDef, VariableGroup } from './components/variable-autocomplete.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AccountFilterTab, a as AccountsViewConfig, b as AdminTab, c as AdminViewConfig, B as BriefStyleVariant, E as EntityPanelConfig, d as EntityPanelSection, I as InboxDetailSections, e as InboxSortOption, f as InboxViewConfig, g as InsightsCustomTab, h as InsightsViewConfig, i as PrototypeBrandConfig, j as PrototypeConfig, Q as QueueItem, l as SignalScoreData, m as SignalScoreExplanationBucket, n as SignalScoreExplanationSignal, o as SignalScoreUrgencyLabel, W as WorkQueueViewConfig } from '../signal-priority-popover-
|
|
1
|
+
export { A as AccountFilterTab, a as AccountsViewConfig, b as AdminTab, c as AdminViewConfig, B as BriefStyleVariant, E as EntityPanelConfig, d as EntityPanelSection, I as InboxDetailSections, e as InboxSortOption, f as InboxViewConfig, g as InsightsCustomTab, h as InsightsViewConfig, i as PrototypeBrandConfig, j as PrototypeConfig, Q as QueueItem, l as SignalScoreData, m as SignalScoreExplanationBucket, n as SignalScoreExplanationSignal, o as SignalScoreUrgencyLabel, T as TimelineSystemEventsConfig, W as WorkQueueViewConfig } from '../signal-priority-popover-BT6CPYNs.js';
|
|
2
2
|
export { PrototypeShell, PrototypeShellProps } from './prototype-shell.js';
|
|
3
3
|
export { DetailView, DetailViewProps, PrototypeInboxView, PrototypeInboxViewProps } from './prototype-inbox-view.js';
|
|
4
4
|
export { PrototypeInsightsView, PrototypeInsightsViewProps } from './prototype-insights-view.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { a as AccountsViewConfig } from '../signal-priority-popover-
|
|
2
|
+
import { a as AccountsViewConfig } from '../signal-priority-popover-BT6CPYNs.js';
|
|
3
3
|
import { DataRow } from '../components/data-table.js';
|
|
4
4
|
import '../components/feedback-primitives.js';
|
|
5
5
|
import '../components/quick-action-sidebar-nav.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { c as AdminViewConfig } from '../signal-priority-popover-
|
|
2
|
+
import { c as AdminViewConfig } from '../signal-priority-popover-BT6CPYNs.js';
|
|
3
3
|
import '../components/feedback-primitives.js';
|
|
4
4
|
import '../components/quick-action-sidebar-nav.js';
|
|
5
5
|
import '../components/quick-action-modal.js';
|
|
@@ -11,7 +11,7 @@ import '../charts/pipeline-overview.js';
|
|
|
11
11
|
import '../components/timeline-activity.js';
|
|
12
12
|
import '../components/signal-feedback-inline.js';
|
|
13
13
|
import 'lucide-react';
|
|
14
|
-
export { A as AccountFilterTab, a as AccountsViewConfig, b as AdminTab, c as AdminViewConfig, B as BriefStyleVariant, E as EntityPanelConfig, d as EntityPanelSection, I as InboxDetailSections, e as InboxSortOption, f as InboxViewConfig, g as InsightsCustomTab, h as InsightsViewConfig, i as PrototypeBrandConfig, j as PrototypeConfig, Q as QueueItem, l as SignalScoreData, m as SignalScoreExplanationBucket, n as SignalScoreExplanationSignal, o as SignalScoreUrgencyLabel, W as WorkQueueViewConfig } from '../signal-priority-popover-
|
|
14
|
+
export { A as AccountFilterTab, a as AccountsViewConfig, b as AdminTab, c as AdminViewConfig, B as BriefStyleVariant, E as EntityPanelConfig, d as EntityPanelSection, I as InboxDetailSections, e as InboxSortOption, f as InboxViewConfig, g as InsightsCustomTab, h as InsightsViewConfig, i as PrototypeBrandConfig, j as PrototypeConfig, Q as QueueItem, l as SignalScoreData, m as SignalScoreExplanationBucket, n as SignalScoreExplanationSignal, o as SignalScoreUrgencyLabel, T as TimelineSystemEventsConfig, W as WorkQueueViewConfig } from '../signal-priority-popover-BT6CPYNs.js';
|
|
15
15
|
import '../components/feedback-primitives.js';
|
|
16
16
|
import '../components/quick-action-modal.js';
|
|
17
17
|
import '../components/data-table-condition-filter.js';
|
|
@@ -3,7 +3,7 @@ import { ApprovalState, OpportunityPreview } from '../components/signal-feedback
|
|
|
3
3
|
import { SourceDef } from '../components/detail-view.js';
|
|
4
4
|
import { SuggestedAction, SuggestedContact } from '../components/suggested-actions.js';
|
|
5
5
|
import { TimelineEvent } from '../components/timeline-activity.js';
|
|
6
|
-
import { Q as QueueItem, I as InboxDetailSections, l as SignalScoreData, f as InboxViewConfig, B as BriefStyleVariant } from '../signal-priority-popover-
|
|
6
|
+
import { Q as QueueItem, I as InboxDetailSections, l as SignalScoreData, f as InboxViewConfig, B as BriefStyleVariant, T as TimelineSystemEventsConfig } from '../signal-priority-popover-BT6CPYNs.js';
|
|
7
7
|
import '../components/feedback-primitives.js';
|
|
8
8
|
import '../components/quick-action-sidebar-nav.js';
|
|
9
9
|
import '../components/quick-action-modal.js';
|
|
@@ -68,8 +68,20 @@ interface DetailViewProps {
|
|
|
68
68
|
onRequestApproval?: () => Promise<void>;
|
|
69
69
|
/** Number of important/attention-worthy events to highlight on the collapsed timeline header. */
|
|
70
70
|
attentionCount?: number;
|
|
71
|
+
/** Configuration for the system-noise events toggle (score changes, etc.). */
|
|
72
|
+
timelineSystemEventsConfig?: TimelineSystemEventsConfig;
|
|
73
|
+
/** @deprecated Use `timelineSystemEventsConfig.toggleLabel`. */
|
|
74
|
+
timelineSystemEventsToggleLabel?: string;
|
|
75
|
+
/** @deprecated Use `timelineSystemEventsConfig.storageKey`. */
|
|
76
|
+
timelineSystemEventsStorageKey?: string;
|
|
77
|
+
/** @deprecated Use `timelineSystemEventsConfig.defaultVisible`. */
|
|
78
|
+
timelineSystemEventsDefaultVisible?: boolean;
|
|
79
|
+
/** @deprecated Use `timelineSystemEventsConfig.hiddenHint`. */
|
|
80
|
+
timelineSystemEventsHiddenHint?: string;
|
|
81
|
+
/** @deprecated Use `timelineSystemEventsConfig.visibleHint`. */
|
|
82
|
+
timelineSystemEventsVisibleHint?: string;
|
|
71
83
|
}
|
|
72
|
-
declare function DetailView({ item, sections, getSignalScore, buildSuggestedActions, buildSourceItems: _buildSourceItems, getTimelineEvents, accountContacts, emailSignature, iconMap, onOpenEntityPanel, onOpenRecentActivity, onSuggestedActionFeedback: _onSuggestedActionFeedback, onScoreFeedback: _onScoreFeedback, onSignalApprove, getSignalApprovalState, signalLabels, hideApproveButton, signalBriefCopy, briefStyleVariant, renderDetailExtra, renderBeforeScore, renderAfterScore, lastActivityTime, renderTitleExtra, renderTitleSubtext, renderMetadataExtra, onOpenSignalBucket, approveButtonIconUrl, opportunityPreview, onRequestApproval, attentionCount, }: DetailViewProps): React.JSX.Element;
|
|
73
|
-
declare function PrototypeInboxView({ items, filterCategories, detailSections, accountContacts, buildAccountContacts, emailSignature, buildSuggestedActions: buildSuggestedActionsProp, buildSourceItems: buildSourceItemsProp, getSignalScore: getSignalScoreProp, getTimelineEvents, iconMap, hideToolbarActions, hideHoverActions, onSuggestedActionFeedback, onScoreFeedback, onOpenSignalBucket, headerActions, onOpenEntityPanel, onOpenRecentActivity, onItemSelect, defaultViewMode, buildEntityChips, quickFilterTabs, hideAccountsButton, accountDetailsLabel, onSignalApprove, getSignalApprovalState, signalLabels, hideApproveButton, signalBriefCopy, briefStyleVariant, renderDetailExtra, renderBeforeScore, renderAfterScore, lastActivityTime, renderTitleExtra, renderTitleSubtext, sortOptions, activeSortId, onSortChange, }: PrototypeInboxViewProps): React.JSX.Element;
|
|
84
|
+
declare function DetailView({ item, sections, getSignalScore, buildSuggestedActions, buildSourceItems: _buildSourceItems, getTimelineEvents, accountContacts, emailSignature, iconMap, onOpenEntityPanel, onOpenRecentActivity, onSuggestedActionFeedback: _onSuggestedActionFeedback, onScoreFeedback: _onScoreFeedback, onSignalApprove, getSignalApprovalState, signalLabels, hideApproveButton, signalBriefCopy, briefStyleVariant, renderDetailExtra, renderBeforeScore, renderAfterScore, lastActivityTime, renderTitleExtra, renderTitleSubtext, renderMetadataExtra, onOpenSignalBucket, approveButtonIconUrl, opportunityPreview, onRequestApproval, attentionCount, timelineSystemEventsConfig: configProp, timelineSystemEventsToggleLabel, timelineSystemEventsStorageKey, timelineSystemEventsDefaultVisible, timelineSystemEventsHiddenHint, timelineSystemEventsVisibleHint, }: DetailViewProps): React.JSX.Element;
|
|
85
|
+
declare function PrototypeInboxView({ items, filterCategories, detailSections, accountContacts, buildAccountContacts, emailSignature, buildSuggestedActions: buildSuggestedActionsProp, buildSourceItems: buildSourceItemsProp, getSignalScore: getSignalScoreProp, getTimelineEvents, iconMap, hideToolbarActions, hideHoverActions, onSuggestedActionFeedback, onScoreFeedback, onOpenSignalBucket, headerActions, onOpenEntityPanel, onOpenRecentActivity, onItemSelect, defaultViewMode, buildEntityChips, quickFilterTabs, hideAccountsButton, accountDetailsLabel, onSignalApprove, getSignalApprovalState, signalLabels, hideApproveButton, signalBriefCopy, briefStyleVariant, renderDetailExtra, renderBeforeScore, renderAfterScore, lastActivityTime, timelineSystemEventsConfig, attentionCount, renderTitleExtra, renderTitleSubtext, sortOptions, activeSortId, onSortChange, }: PrototypeInboxViewProps): React.JSX.Element;
|
|
74
86
|
|
|
75
87
|
export { DetailView, type DetailViewProps, PrototypeInboxView, type PrototypeInboxViewProps };
|
|
@@ -86,6 +86,88 @@ const DEFAULT_SIGNAL_SCORE = {
|
|
|
86
86
|
],
|
|
87
87
|
confidence: 72
|
|
88
88
|
};
|
|
89
|
+
function TimelineSection({
|
|
90
|
+
timelineEvents,
|
|
91
|
+
showTimeline,
|
|
92
|
+
setShowTimeline,
|
|
93
|
+
showSystemEvents,
|
|
94
|
+
setShowSystemEvents,
|
|
95
|
+
attentionCount,
|
|
96
|
+
sysEvtConfig,
|
|
97
|
+
lastActivityTime
|
|
98
|
+
}) {
|
|
99
|
+
var _a;
|
|
100
|
+
const visibleEvents = [];
|
|
101
|
+
let hiddenCount = 0;
|
|
102
|
+
for (const e of timelineEvents) {
|
|
103
|
+
if (e.isSystemNoise) hiddenCount++;
|
|
104
|
+
if (!e.isSystemNoise || showSystemEvents) visibleEvents.push(e);
|
|
105
|
+
}
|
|
106
|
+
const hasSystemNoise = hiddenCount > 0;
|
|
107
|
+
const toggleLabel = (_a = sysEvtConfig == null ? void 0 : sysEvtConfig.toggleLabel) != null ? _a : "System events";
|
|
108
|
+
const firstVisibleTime = (!hasSystemNoise || showSystemEvents) && lastActivityTime ? lastActivityTime : visibleEvents.length > 0 ? visibleEvents[0].time : "";
|
|
109
|
+
const visibleCount = visibleEvents.length;
|
|
110
|
+
const eventCountLabel = `${visibleCount} ${visibleCount === 1 ? "event" : "events"}`;
|
|
111
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
112
|
+
/* @__PURE__ */ jsxs(
|
|
113
|
+
"div",
|
|
114
|
+
{
|
|
115
|
+
className: "group/timeline flex w-full items-center justify-between gap-2 py-2 rounded-md transition-colors hover:bg-muted/40 -mx-2 px-2",
|
|
116
|
+
"data-testid": "timeline-header",
|
|
117
|
+
children: [
|
|
118
|
+
/* @__PURE__ */ jsxs(
|
|
119
|
+
"button",
|
|
120
|
+
{
|
|
121
|
+
type: "button",
|
|
122
|
+
onClick: () => setShowTimeline((prev) => !prev),
|
|
123
|
+
className: "flex items-center gap-2 cursor-pointer bg-transparent border-0 p-0",
|
|
124
|
+
"data-testid": "timeline-collapse-btn",
|
|
125
|
+
children: [
|
|
126
|
+
/* @__PURE__ */ jsx("h3", { className: "text-xs font-bold text-muted-foreground uppercase tracking-wider group-hover/timeline:text-foreground transition-colors", children: "Activity timeline" }),
|
|
127
|
+
!showTimeline && attentionCount != null && attentionCount > 0 && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-destructive/10 px-1.5 py-0.5 text-[10px] font-semibold text-destructive border border-destructive/20", children: [
|
|
128
|
+
attentionCount,
|
|
129
|
+
" new"
|
|
130
|
+
] }),
|
|
131
|
+
!showTimeline && firstVisibleTime && /* @__PURE__ */ jsxs("span", { className: "text-[11px] text-muted-foreground/60", "data-testid": "last-activity-hint", children: [
|
|
132
|
+
"\xB7 Last activity ",
|
|
133
|
+
firstVisibleTime
|
|
134
|
+
] }),
|
|
135
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
136
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-muted-foreground", "data-testid": "event-count", children: eventCountLabel }),
|
|
137
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `h-3.5 w-3.5 text-muted-foreground transition-transform duration-200 ${showTimeline ? "rotate-180" : ""}` })
|
|
138
|
+
] })
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
),
|
|
142
|
+
hasSystemNoise && /* @__PURE__ */ jsxs(
|
|
143
|
+
"button",
|
|
144
|
+
{
|
|
145
|
+
type: "button",
|
|
146
|
+
onClick: () => setShowSystemEvents((prev) => !prev),
|
|
147
|
+
className: "flex shrink-0 items-center gap-1.5 rounded-full border border-border bg-background px-2.5 py-1 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-muted/40 hover:text-foreground cursor-pointer",
|
|
148
|
+
"aria-pressed": showSystemEvents,
|
|
149
|
+
"data-testid": "system-events-toggle",
|
|
150
|
+
children: [
|
|
151
|
+
toggleLabel,
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
"span",
|
|
154
|
+
{
|
|
155
|
+
className: "inline-flex items-center justify-center rounded-full bg-muted px-1.5 text-[10px] font-semibold min-w-[18px] tabular-nums",
|
|
156
|
+
"data-testid": "hidden-count-badge",
|
|
157
|
+
children: hiddenCount
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
]
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
),
|
|
166
|
+
showTimeline && visibleEvents.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(TimelineActivity, { events: visibleEvents }) }),
|
|
167
|
+
showTimeline && !showSystemEvents && (sysEvtConfig == null ? void 0 : sysEvtConfig.hiddenHint) && hasSystemNoise && /* @__PURE__ */ jsx("p", { className: "mt-2 text-[11px] text-muted-foreground/60 border-t border-dashed border-border pt-2", "data-testid": "timeline-footer-hint", children: sysEvtConfig.hiddenHint }),
|
|
168
|
+
showTimeline && showSystemEvents && (sysEvtConfig == null ? void 0 : sysEvtConfig.visibleHint) && hasSystemNoise && /* @__PURE__ */ jsx("p", { className: "mt-2 text-[11px] text-muted-foreground/60 border-t border-dashed border-border pt-2", "data-testid": "timeline-footer-hint", children: sysEvtConfig.visibleHint.replace("{count}", String(hiddenCount)) })
|
|
169
|
+
] });
|
|
170
|
+
}
|
|
89
171
|
function DetailView({
|
|
90
172
|
item,
|
|
91
173
|
sections,
|
|
@@ -117,11 +199,63 @@ function DetailView({
|
|
|
117
199
|
approveButtonIconUrl,
|
|
118
200
|
opportunityPreview,
|
|
119
201
|
onRequestApproval,
|
|
120
|
-
attentionCount
|
|
202
|
+
attentionCount,
|
|
203
|
+
timelineSystemEventsConfig: configProp,
|
|
204
|
+
timelineSystemEventsToggleLabel,
|
|
205
|
+
timelineSystemEventsStorageKey,
|
|
206
|
+
timelineSystemEventsDefaultVisible,
|
|
207
|
+
timelineSystemEventsHiddenHint,
|
|
208
|
+
timelineSystemEventsVisibleHint
|
|
121
209
|
}) {
|
|
122
|
-
var _a, _b, _c, _d
|
|
210
|
+
var _a, _b, _c, _d;
|
|
211
|
+
const sysEvtConfig = React.useMemo(() => {
|
|
212
|
+
if (configProp) return configProp;
|
|
213
|
+
if (timelineSystemEventsToggleLabel || timelineSystemEventsStorageKey || timelineSystemEventsDefaultVisible !== void 0 || timelineSystemEventsHiddenHint || timelineSystemEventsVisibleHint) {
|
|
214
|
+
return {
|
|
215
|
+
toggleLabel: timelineSystemEventsToggleLabel,
|
|
216
|
+
storageKey: timelineSystemEventsStorageKey,
|
|
217
|
+
defaultVisible: timelineSystemEventsDefaultVisible,
|
|
218
|
+
hiddenHint: timelineSystemEventsHiddenHint,
|
|
219
|
+
visibleHint: timelineSystemEventsVisibleHint
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
return void 0;
|
|
223
|
+
}, [
|
|
224
|
+
configProp,
|
|
225
|
+
timelineSystemEventsToggleLabel,
|
|
226
|
+
timelineSystemEventsStorageKey,
|
|
227
|
+
timelineSystemEventsDefaultVisible,
|
|
228
|
+
timelineSystemEventsHiddenHint,
|
|
229
|
+
timelineSystemEventsVisibleHint
|
|
230
|
+
]);
|
|
123
231
|
const [showTimeline, setShowTimeline] = React.useState(false);
|
|
124
232
|
const [extraActions, setExtraActions] = React.useState([]);
|
|
233
|
+
const sysEvtDefaultVisible = (_a = sysEvtConfig == null ? void 0 : sysEvtConfig.defaultVisible) != null ? _a : false;
|
|
234
|
+
const sysEvtStorageKey = sysEvtConfig == null ? void 0 : sysEvtConfig.storageKey;
|
|
235
|
+
const [showSystemEvents, setShowSystemEvents] = React.useState(sysEvtDefaultVisible);
|
|
236
|
+
const initialReadDoneRef = React.useRef(false);
|
|
237
|
+
React.useEffect(() => {
|
|
238
|
+
if (!sysEvtStorageKey) {
|
|
239
|
+
initialReadDoneRef.current = true;
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
const stored = localStorage.getItem(sysEvtStorageKey);
|
|
244
|
+
if (stored !== null) {
|
|
245
|
+
setShowSystemEvents(stored === "true");
|
|
246
|
+
}
|
|
247
|
+
} catch (e) {
|
|
248
|
+
}
|
|
249
|
+
initialReadDoneRef.current = true;
|
|
250
|
+
}, [sysEvtStorageKey]);
|
|
251
|
+
React.useEffect(() => {
|
|
252
|
+
if (!sysEvtStorageKey) return;
|
|
253
|
+
if (!initialReadDoneRef.current) return;
|
|
254
|
+
try {
|
|
255
|
+
localStorage.setItem(sysEvtStorageKey, String(showSystemEvents));
|
|
256
|
+
} catch (e) {
|
|
257
|
+
}
|
|
258
|
+
}, [showSystemEvents, sysEvtStorageKey]);
|
|
125
259
|
React.useEffect(() => {
|
|
126
260
|
setShowTimeline(false);
|
|
127
261
|
setExtraActions([]);
|
|
@@ -203,8 +337,8 @@ function DetailView({
|
|
|
203
337
|
{
|
|
204
338
|
score: signalData.score,
|
|
205
339
|
urgencyLabel: signalData.urgencyLabel,
|
|
206
|
-
urgencyExplanation: (
|
|
207
|
-
factors: (
|
|
340
|
+
urgencyExplanation: (_b = signalData.urgencyExplanation) != null ? _b : signalData.signalBrief,
|
|
341
|
+
factors: (_c = signalData.priorityFactors) != null ? _c : [],
|
|
208
342
|
metaText: void 0,
|
|
209
343
|
feedbackChips: signalData.priorityFeedbackChips,
|
|
210
344
|
onFeedbackSubmit: signalData.onPriorityFeedback,
|
|
@@ -213,7 +347,7 @@ function DetailView({
|
|
|
213
347
|
initialPriorityFeedback: signalData.initialPriorityFeedback
|
|
214
348
|
}
|
|
215
349
|
),
|
|
216
|
-
signalData.timeChipLabel && /* @__PURE__ */ jsx(Badge, { variant: "outline", title: (
|
|
350
|
+
signalData.timeChipLabel && /* @__PURE__ */ jsx(Badge, { variant: "outline", title: (_d = signalData.timeChipDetail) != null ? _d : void 0, children: signalData.timeChipLabel }),
|
|
217
351
|
/* @__PURE__ */ jsxs(
|
|
218
352
|
"button",
|
|
219
353
|
{
|
|
@@ -252,37 +386,19 @@ function DetailView({
|
|
|
252
386
|
] });
|
|
253
387
|
})(),
|
|
254
388
|
renderAfterScore == null ? void 0 : renderAfterScore(item),
|
|
255
|
-
sections.timeline && timelineEvents.length > 0 && /* @__PURE__ */
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
] }),
|
|
269
|
-
!showTimeline && (lastActivityTime || timelineEvents.length > 0 && timelineEvents[0].time) && /* @__PURE__ */ jsxs("span", { className: "text-[11px] text-muted-foreground/60", children: [
|
|
270
|
-
"\xB7 Last activity ",
|
|
271
|
-
(_e = lastActivityTime != null ? lastActivityTime : (_d = timelineEvents[0]) == null ? void 0 : _d.time) != null ? _e : ""
|
|
272
|
-
] })
|
|
273
|
-
] }),
|
|
274
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
275
|
-
/* @__PURE__ */ jsxs("span", { className: "text-[11px] font-medium text-muted-foreground", children: [
|
|
276
|
-
timelineEvents.length,
|
|
277
|
-
" events"
|
|
278
|
-
] }),
|
|
279
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: `h-3.5 w-3.5 text-muted-foreground transition-transform duration-200 ${showTimeline ? "rotate-180" : ""}` })
|
|
280
|
-
] })
|
|
281
|
-
]
|
|
282
|
-
}
|
|
283
|
-
),
|
|
284
|
-
showTimeline && /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(TimelineActivity, { events: timelineEvents }) })
|
|
285
|
-
] })
|
|
389
|
+
sections.timeline && timelineEvents.length > 0 && /* @__PURE__ */ jsx(
|
|
390
|
+
TimelineSection,
|
|
391
|
+
{
|
|
392
|
+
timelineEvents,
|
|
393
|
+
showTimeline,
|
|
394
|
+
setShowTimeline,
|
|
395
|
+
showSystemEvents,
|
|
396
|
+
setShowSystemEvents,
|
|
397
|
+
attentionCount,
|
|
398
|
+
sysEvtConfig,
|
|
399
|
+
lastActivityTime
|
|
400
|
+
}
|
|
401
|
+
)
|
|
286
402
|
] }),
|
|
287
403
|
sections.suggestedActions && /* @__PURE__ */ jsx(SignalApproval.Gate, { children: /* @__PURE__ */ jsx(
|
|
288
404
|
SuggestedActions,
|
|
@@ -343,6 +459,8 @@ function PrototypeInboxView({
|
|
|
343
459
|
renderBeforeScore,
|
|
344
460
|
renderAfterScore,
|
|
345
461
|
lastActivityTime,
|
|
462
|
+
timelineSystemEventsConfig,
|
|
463
|
+
attentionCount,
|
|
346
464
|
renderTitleExtra,
|
|
347
465
|
renderTitleSubtext,
|
|
348
466
|
sortOptions,
|
|
@@ -540,6 +658,8 @@ function PrototypeInboxView({
|
|
|
540
658
|
renderBeforeScore,
|
|
541
659
|
renderAfterScore,
|
|
542
660
|
lastActivityTime,
|
|
661
|
+
timelineSystemEventsConfig,
|
|
662
|
+
attentionCount,
|
|
543
663
|
renderTitleExtra,
|
|
544
664
|
renderTitleSubtext,
|
|
545
665
|
onOpenSignalBucket
|