@handled-ai/design-system 0.18.51 → 0.18.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/components/badge.d.ts +1 -1
  2. package/dist/components/button.d.ts +1 -1
  3. package/dist/components/data-table-filter.d.ts +21 -6
  4. package/dist/components/data-table-filter.js +134 -9
  5. package/dist/components/data-table-filter.js.map +1 -1
  6. package/dist/components/entity-panel.js +5 -5
  7. package/dist/components/entity-panel.js.map +1 -1
  8. package/dist/components/pill.d.ts +1 -1
  9. package/dist/components/score-why-chips.d.ts +1 -1
  10. package/dist/components/signal-feedback-inline.d.ts +28 -12
  11. package/dist/components/signal-feedback-inline.js +146 -10
  12. package/dist/components/signal-feedback-inline.js.map +1 -1
  13. package/dist/components/signal-priority-popover.d.ts +1 -1
  14. package/dist/components/signal-priority-popover.js +7 -16
  15. package/dist/components/signal-priority-popover.js.map +1 -1
  16. package/dist/components/tabs.d.ts +1 -1
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.js.map +1 -1
  19. package/dist/prototype/index.d.ts +1 -1
  20. package/dist/prototype/prototype-accounts-view.d.ts +1 -1
  21. package/dist/prototype/prototype-admin-view.d.ts +1 -1
  22. package/dist/prototype/prototype-config.d.ts +1 -1
  23. package/dist/prototype/prototype-inbox-view.d.ts +3 -3
  24. package/dist/prototype/prototype-inbox-view.js +1 -3
  25. package/dist/prototype/prototype-inbox-view.js.map +1 -1
  26. package/dist/prototype/prototype-insights-view.d.ts +1 -1
  27. package/dist/prototype/prototype-shell.d.ts +1 -1
  28. package/dist/{signal-priority-popover-DTedstRL.d.ts → signal-priority-popover-QJngMAj7.d.ts} +4 -13
  29. package/package.json +1 -1
  30. package/src/components/__tests__/case-panel-why.test.tsx +126 -0
  31. package/src/components/__tests__/data-table-filter.test.tsx +130 -0
  32. package/src/components/__tests__/entity-metadata-grid.test.tsx +27 -1
  33. package/src/components/__tests__/signal-priority-popover.test.tsx +4 -41
  34. package/src/components/data-table-filter.tsx +160 -9
  35. package/src/components/entity-panel.tsx +7 -5
  36. package/src/components/signal-feedback-inline.tsx +181 -20
  37. package/src/components/signal-priority-popover.tsx +6 -19
  38. package/src/index.ts +1 -1
  39. package/src/prototype/__tests__/detail-view-opportunity-preview.test.tsx +90 -0
  40. package/src/prototype/__tests__/detail-view-score-why.test.tsx +0 -34
  41. package/src/prototype/prototype-config.ts +3 -7
  42. package/src/prototype/prototype-inbox-view.tsx +3 -5
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/signal-feedback-inline.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Check, CirclePlus, ExternalLink, Loader2, Lock, ThumbsDown } from \"lucide-react\"\n\ninterface DismissReasonNode {\n label: string\n subOptions?: string[]\n}\n\nconst dismissReasonTree: DismissReasonNode[] = [\n {\n label: \"Not relevant for this account\",\n subOptions: [\n \"Business as usual for this account\",\n \"Account in maintenance mode\",\n \"Wrong contact for this signal\",\n \"Other\",\n ],\n },\n {\n label: \"Bad timing\",\n subOptions: [\n \"Too early in the relationship\",\n \"Too soon after last outreach\",\n \"Wrong time of year for this account\",\n \"Other\",\n ],\n },\n {\n label: \"Inaccurate data\",\n subOptions: [\n \"Wrong amount or number\",\n \"Stale data\",\n \"Account info wrong\",\n \"Other\",\n ],\n },\n {\n label: \"Wrong account\",\n subOptions: [\n \"Different account meant\",\n \"Account not in scope\",\n \"Other\",\n ],\n },\n {\n label: \"Already handled\",\n subOptions: [\n \"Already in conversation\",\n \"Already an open Opportunity\",\n \"Already escalated\",\n \"Other\",\n ],\n },\n {\n label: \"Not actionable\",\n subOptions: [\n \"No clear next step\",\n \"Outside our remit\",\n \"Other\",\n ],\n },\n { label: \"Other\" },\n]\n\nconst approveReasons = [\n \"Right timing\",\n \"Accurate data\",\n \"Good prospect fit\",\n \"Actionable\",\n]\n\ntype ApprovalState = \"pending\" | \"confirming\" | \"creating\" | \"approving-feedback\" | \"dismissing\" | \"approved\" | \"dismissed\" | \"auto-approved\"\n\ninterface SignalApprovalLabels {\n approveButton?: string\n dismissButton?: string\n approvedStatus?: string\n dismissedStatus?: string\n opportunityCreated?: string\n confirmPrompt?: string\n dismissPrompt?: string\n feedbackPrompt?: string\n /** Label shown while the approve action is in progress (e.g. \"Creating Opportunity...\"). */\n creatingStatus?: string\n}\n\nconst DEFAULT_LABELS: Required<SignalApprovalLabels> = {\n approveButton: \"Approve action\",\n dismissButton: \"Not Helpful\",\n approvedStatus: \"Action Approved\",\n dismissedStatus: \"Action Dismissed\",\n opportunityCreated: \"Opportunity Created\",\n confirmPrompt: \"This will approve this action for\",\n dismissPrompt: \"What\\u2019s the issue with this action?\",\n feedbackPrompt: \"Quick feedback \\u2014 what made this action useful?\",\n creatingStatus: \"Creating\\u2026\",\n}\n\ninterface SignalApprovalContextValue {\n approvalState: ApprovalState\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n labels: Required<SignalApprovalLabels>\n hideApproveButton?: boolean\n approveButtonIconUrl?: string\n opportunityPreview?: RootProps['opportunityPreview']\n requestingApproval: boolean\n approve: () => void\n submitApproveFeedback: (reasons: string[], detail: string) => void\n skipApproveFeedback: () => void\n dismiss: (reasons: string[], detail: string, subReason?: string) => void\n requestApproval: () => void\n requestDismiss: () => void\n cancel: () => void\n}\n\nconst SignalApprovalCtx = React.createContext<SignalApprovalContextValue | null>(null)\n\nexport function useSignalApproval() {\n const ctx = React.useContext(SignalApprovalCtx)\n if (!ctx) throw new Error(\"SignalApproval components must be used within SignalApproval.Root\")\n return ctx\n}\n\ninterface RootProps {\n children: React.ReactNode\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n initialApprovalState?: ApprovalState\n labels?: SignalApprovalLabels\n /** When true, the approve/create-opportunity button is hidden but the dismiss button remains. */\n hideApproveButton?: boolean\n /** Optional icon URL for the approve button. Renders an img instead of CirclePlus when provided. */\n approveButtonIconUrl?: string\n /** Optional structured preview data shown in the confirmation dialog. */\n opportunityPreview?: {\n name: string\n stage: string\n closeDate: string\n amount: string\n accountName: string\n }\n /**\n * Async callback fired when the user clicks the approve button, BEFORE\n * transitioning to the \"confirming\" state. While the promise is pending,\n * the button shows a loading spinner. On resolve, transitions to \"confirming\".\n * On reject, stays in \"pending\".\n */\n onRequestApproval?: () => Promise<void>\n /**\n * Called when the user confirms the approval action.\n *\n * - If the callback returns `void` (or `undefined`), the component transitions\n * directly to the feedback step (backward-compatible behavior).\n * - If the callback returns a `Promise<boolean>`, the component shows a\n * \"creating\" loading state while the promise is pending. On `true` it\n * transitions to the feedback step; on `false` it reverts to \"pending\".\n */\n onApprove?: () => void | Promise<boolean>\n onApproveFeedback?: (reasons: string[], detail: string) => void\n onDismiss?: (reasons: string[], detail: string, subReason?: string) => void\n}\n\nfunction Root({ children, companyName, opportunityUrl, scheduledTime, initialApprovalState, labels: labelOverrides, hideApproveButton, approveButtonIconUrl, opportunityPreview, onRequestApproval, onApprove, onApproveFeedback, onDismiss }: RootProps) {\n const labels = React.useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides])\n const [approvalState, setApprovalState] = React.useState<ApprovalState>(initialApprovalState ?? \"pending\")\n const [requestingApproval, setRequestingApproval] = React.useState(false)\n\n // Guard against state updates after unmount (e.g. user navigates away while\n // an async onApprove promise is still in flight).\n const mountedRef = React.useRef(true)\n React.useEffect(() => {\n return () => { mountedRef.current = false }\n }, [])\n\n const requestApproval = React.useCallback(() => {\n if (onRequestApproval) {\n setRequestingApproval(true)\n onRequestApproval()\n .then(() => {\n if (mountedRef.current) {\n setRequestingApproval(false)\n setApprovalState(\"confirming\")\n }\n })\n .catch(() => {\n if (mountedRef.current) {\n setRequestingApproval(false)\n }\n })\n } else {\n setApprovalState(\"confirming\")\n }\n }, [onRequestApproval])\n\n const requestDismiss = React.useCallback(() => {\n setApprovalState(\"dismissing\")\n }, [])\n\n const cancel = React.useCallback(() => {\n setApprovalState(\"pending\")\n }, [])\n\n const approve = React.useCallback(() => {\n const result = onApprove?.()\n // If the callback returns a Promise, show a loading state and wait for it.\n if (result && typeof (result as Promise<boolean>).then === \"function\") {\n setApprovalState(\"creating\")\n ;(result as Promise<boolean>).then((success) => {\n if (mountedRef.current) {\n setApprovalState(success ? \"approving-feedback\" : \"pending\")\n }\n }).catch(() => {\n if (mountedRef.current) {\n setApprovalState(\"pending\")\n }\n })\n } else {\n // Synchronous / void — transition immediately (backward-compatible).\n setApprovalState(\"approving-feedback\")\n }\n }, [onApprove])\n\n const submitApproveFeedback = React.useCallback(\n (reasons: string[], detail: string) => {\n setApprovalState(\"approved\")\n onApproveFeedback?.(reasons, detail)\n },\n [onApproveFeedback]\n )\n\n const skipApproveFeedback = React.useCallback(() => {\n setApprovalState(\"approved\")\n }, [])\n\n const dismiss = React.useCallback(\n (reasons: string[], detail: string, subReason?: string) => {\n setApprovalState(\"dismissed\")\n onDismiss?.(reasons, detail, subReason)\n },\n [onDismiss]\n )\n\n return (\n <SignalApprovalCtx.Provider\n value={{ approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel }}\n >\n {children}\n </SignalApprovalCtx.Provider>\n )\n}\n\n/** Shared dismiss reason picker used in both the \"editing\" and \"initial dismiss\" paths. */\nfunction DismissReasonPicker({\n selectedTopReason,\n selectedSubReason,\n selectTopReason,\n selectSubReason,\n detailText,\n setDetailText,\n needsText,\n canSubmitDismiss,\n handleDismissSubmit,\n topNode,\n submitLabel,\n onCancel,\n}: {\n selectedTopReason: string | null\n selectedSubReason: string | null\n selectTopReason: (label: string) => void\n selectSubReason: (label: string) => void\n detailText: string\n setDetailText: (value: string) => void\n needsText: boolean\n canSubmitDismiss: boolean\n handleDismissSubmit: () => void\n topNode: DismissReasonNode | undefined\n submitLabel: string\n onCancel: () => void\n}) {\n return (\n <>\n <div className=\"flex flex-wrap gap-1.5\">\n {dismissReasonTree.map((node) => {\n const selected = selectedTopReason === node.label\n return (\n <button\n key={node.label}\n type=\"button\"\n onClick={() => selectTopReason(node.label)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-red-200 bg-red-100 text-red-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {node.label}\n </button>\n )\n })}\n </div>\n\n {topNode?.subOptions && (\n <div className=\"ml-3 border-l-2 border-muted pl-3\">\n <div className=\"flex flex-wrap gap-1.5\">\n {topNode.subOptions.map((sub) => {\n const selected = selectedSubReason === sub\n return (\n <button\n key={sub}\n type=\"button\"\n onClick={() => selectSubReason(sub)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-red-200 bg-red-100 text-red-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {sub}\n </button>\n )\n })}\n </div>\n </div>\n )}\n\n {selectedTopReason && (\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && canSubmitDismiss) handleDismissSubmit()\n }}\n placeholder={needsText ? \"Please describe (required)\" : \"Add context (optional)\"}\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleDismissSubmit}\n disabled={!canSubmitDismiss}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${\n canSubmitDismiss\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"cursor-not-allowed bg-muted text-muted-foreground\"\n }`}\n >\n {submitLabel}\n </button>\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n </>\n )\n}\n\nfunction SubmittedFeedback({\n reasons,\n detail,\n subReason,\n variant,\n onEdit,\n}: {\n reasons: string[]\n detail: string\n subReason?: string\n variant: \"approve\" | \"dismiss\"\n onEdit: () => void\n}) {\n if (reasons.length === 0 && !detail) return null\n const pillClass =\n variant === \"approve\"\n ? \"border-emerald-200/60 bg-emerald-50/50 text-emerald-700/70\"\n : \"border-red-200/60 bg-red-50/50 text-red-700/70\"\n\n return (\n <button\n type=\"button\"\n onClick={onEdit}\n className=\"w-full text-left space-y-1.5 group cursor-pointer\"\n >\n {reasons.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {reasons.map((r) => (\n <span\n key={r}\n className={`rounded-full border px-2 py-0.5 text-[10px] font-medium transition-colors group-hover:opacity-80 ${pillClass}`}\n >\n {r}\n </span>\n ))}\n {subReason && (\n <span\n className={`rounded-full border px-2 py-0.5 text-[10px] font-medium transition-colors group-hover:opacity-80 ${pillClass}`}\n >\n {subReason}\n </span>\n )}\n </div>\n )}\n {detail && (\n <p className=\"text-[11px] text-muted-foreground/70 leading-snug group-hover:text-muted-foreground transition-colors\">{detail}</p>\n )}\n </button>\n )\n}\n\nfunction Actions() {\n const { approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel } =\n useSignalApproval()\n const [selectedTopReason, setSelectedTopReason] = React.useState<string | null>(null)\n const [selectedSubReason, setSelectedSubReason] = React.useState<string | null>(null)\n const [selectedReasons, setSelectedReasons] = React.useState<string[]>([])\n const [detailText, setDetailText] = React.useState(\"\")\n const [submittedFeedback, setSubmittedFeedback] = React.useState<{ reasons: string[]; detail: string; subReason?: string } | null>(null)\n const [isEditing, setIsEditing] = React.useState(false)\n\n const topNode = dismissReasonTree.find((n) => n.label === selectedTopReason)\n const hasSubOptions = !!(topNode?.subOptions && topNode.subOptions.length > 0)\n const isTopOther = selectedTopReason === \"Other\" && !hasSubOptions\n const isSubOther = selectedSubReason === \"Other\"\n const needsText = isTopOther || isSubOther\n const canSubmitDismiss =\n selectedTopReason !== null &&\n (!hasSubOptions || selectedSubReason !== null) &&\n (!needsText || detailText.trim().length > 0)\n\n const canSubmitApprove = selectedReasons.length > 0 || detailText.trim().length > 0\n\n const selectTopReason = (label: string) => {\n if (selectedTopReason === label) {\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setDetailText(\"\")\n } else {\n setSelectedTopReason(label)\n setSelectedSubReason(null)\n setDetailText(\"\")\n }\n }\n\n const selectSubReason = (label: string) => {\n setSelectedSubReason(selectedSubReason === label ? null : label)\n }\n\n const toggleReason = (reason: string) => {\n setSelectedReasons((prev) =>\n prev.includes(reason) ? prev.filter((r) => r !== reason) : [...prev, reason]\n )\n }\n\n const startEditing = () => {\n if (submittedFeedback) {\n setSelectedTopReason(submittedFeedback.reasons[0] ?? null)\n setSelectedSubReason(submittedFeedback.subReason ?? null)\n // Note: selectedReasons is only used by the approve editing path.\n // For dismiss feedback this is harmless but unused — the dismiss path\n // reads selectedTopReason/selectedSubReason instead.\n setSelectedReasons([...submittedFeedback.reasons])\n setDetailText(submittedFeedback.detail)\n }\n setIsEditing(true)\n }\n\n const handleDismissSubmit = () => {\n if (!canSubmitDismiss || !selectedTopReason) return\n const fb = { reasons: [selectedTopReason], detail: detailText.trim(), subReason: selectedSubReason ?? undefined }\n setSubmittedFeedback(fb)\n dismiss([selectedTopReason], detailText.trim(), selectedSubReason ?? undefined)\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleApproveSubmit = () => {\n const fb = { reasons: [...selectedReasons], detail: detailText.trim() }\n setSubmittedFeedback(fb)\n submitApproveFeedback(selectedReasons, detailText.trim())\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleEditCancel = () => {\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleCancel = () => {\n cancel()\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setSelectedReasons([])\n setDetailText(\"\")\n }\n\n if (approvalState === \"creating\") {\n return (\n <div className=\"flex items-center gap-2 text-xs font-medium text-muted-foreground\">\n <svg className=\"h-3.5 w-3.5 animate-spin\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n <span>{labels.creatingStatus}</span>\n </div>\n )\n }\n\n if (approvalState === \"approved\") {\n if (isEditing) {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600 mb-2\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a href={opportunityUrl} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\">\n {labels.approvedStatus} <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.approvedStatus}</span>\n )}\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">Edit your feedback</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {approveReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button key={reason} type=\"button\" onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected ? \"border-emerald-200 bg-emerald-100 text-emerald-700\" : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}>{reason}</button>\n )\n })}\n </div>\n <input type=\"text\" value={detailText} onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\" && canSubmitApprove) handleApproveSubmit() }}\n placeholder=\"Tell us more (optional)\"\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\" />\n <div className=\"flex items-center gap-2\">\n <button type=\"button\" onClick={handleApproveSubmit} disabled={!canSubmitApprove}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${canSubmitApprove ? \"bg-foreground text-background hover:bg-foreground/90\" : \"cursor-not-allowed bg-muted text-muted-foreground\"}`}>\n Save\n </button>\n <button type=\"button\" onClick={handleEditCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\">\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a\n href={opportunityUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\"\n >\n {labels.opportunityCreated}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.opportunityCreated}</span>\n )}\n </div>\n {submittedFeedback && (\n <SubmittedFeedback\n reasons={submittedFeedback.reasons}\n detail={submittedFeedback.detail}\n variant=\"approve\"\n onEdit={startEditing}\n />\n )}\n </div>\n )\n }\n\n if (approvalState === \"auto-approved\") {\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600\">\n <Check className=\"h-3.5 w-3.5\" />\n <span>{labels.approvedStatus}</span>\n </div>\n {scheduledTime && (\n <p className=\"text-[11px] text-muted-foreground\">Scheduled: {scheduledTime}</p>\n )}\n </div>\n )\n }\n\n if (approvalState === \"approving-feedback\") {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600 mb-2\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a\n href={opportunityUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\"\n >\n {labels.opportunityCreated}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.opportunityCreated}</span>\n )}\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">{labels.feedbackPrompt}</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {approveReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button\n key={reason}\n type=\"button\"\n onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-emerald-200 bg-emerald-100 text-emerald-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {reason}\n </button>\n )\n })}\n </div>\n\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && canSubmitApprove) handleApproveSubmit()\n }}\n placeholder=\"Tell us more (optional)\"\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleApproveSubmit}\n disabled={!canSubmitApprove}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${\n canSubmitApprove\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"cursor-not-allowed bg-muted text-muted-foreground\"\n }`}\n >\n Submit\n </button>\n <button\n type=\"button\"\n onClick={skipApproveFeedback}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Skip\n </button>\n </div>\n </div>\n )\n }\n\n if (approvalState === \"dismissed\") {\n if (isEditing) {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground mb-2\">\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n <span>{labels.dismissedStatus}</span>\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">Edit your feedback</p>\n <DismissReasonPicker\n selectedTopReason={selectedTopReason}\n selectedSubReason={selectedSubReason}\n selectTopReason={selectTopReason}\n selectSubReason={selectSubReason}\n detailText={detailText}\n setDetailText={setDetailText}\n needsText={needsText}\n canSubmitDismiss={canSubmitDismiss}\n handleDismissSubmit={handleDismissSubmit}\n topNode={topNode}\n submitLabel=\"Save\"\n onCancel={handleEditCancel}\n />\n </div>\n )\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n <span>{labels.dismissedStatus}</span>\n </div>\n {submittedFeedback && (\n <SubmittedFeedback\n reasons={submittedFeedback.reasons}\n detail={submittedFeedback.detail}\n subReason={submittedFeedback.subReason}\n variant=\"dismiss\"\n onEdit={startEditing}\n />\n )}\n </div>\n )\n }\n\n if (approvalState === \"confirming\") {\n return (\n <div className=\"space-y-3\">\n <div className=\"rounded-md border border-border bg-muted/30 p-3\">\n <p className=\"text-sm text-foreground\">\n {labels.confirmPrompt} <strong>{companyName}</strong>. Confirm?\n </p>\n {opportunityPreview && (\n <div className=\"mt-3 space-y-1.5 border-t border-border/50 pt-3\">\n {[\n { label: \"Opportunity\", value: opportunityPreview.name },\n { label: \"Account\", value: opportunityPreview.accountName },\n { label: \"Stage\", value: opportunityPreview.stage },\n { label: \"Close Date\", value: opportunityPreview.closeDate },\n { label: \"Amount\", value: opportunityPreview.amount },\n ].map(({ label, value }) => (\n <div key={label} className=\"flex items-center justify-between text-xs\">\n <span className=\"text-muted-foreground\">{label}</span>\n <span className=\"font-medium text-foreground\">{value}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={approve}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-semibold text-background transition-colors hover:bg-foreground/90\"\n >\n <Check className=\"h-3 w-3\" />\n Confirm\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n if (approvalState === \"dismissing\") {\n return (\n <div className=\"space-y-3\">\n <p className=\"text-xs font-medium text-muted-foreground\">{labels.dismissPrompt}</p>\n <DismissReasonPicker\n selectedTopReason={selectedTopReason}\n selectedSubReason={selectedSubReason}\n selectTopReason={selectTopReason}\n selectSubReason={selectSubReason}\n detailText={detailText}\n setDetailText={setDetailText}\n needsText={needsText}\n canSubmitDismiss={canSubmitDismiss}\n handleDismissSubmit={handleDismissSubmit}\n topNode={topNode}\n submitLabel=\"Submit\"\n onCancel={handleCancel}\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex items-center gap-2\">\n {!hideApproveButton && (\n <button\n type=\"button\"\n onClick={requestApproval}\n disabled={requestingApproval}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md border border-border bg-foreground px-3 text-xs font-semibold text-background shadow-none transition-colors hover:bg-foreground/90 disabled:opacity-50\"\n >\n {requestingApproval ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : approveButtonIconUrl ? (\n <img src={approveButtonIconUrl} alt=\"\" className=\"h-3.5 w-3.5 object-contain\" draggable={false} />\n ) : (\n <CirclePlus className=\"h-3.5 w-3.5\" />\n )}\n {labels.approveButton}\n </button>\n )}\n <button\n type=\"button\"\n onClick={requestDismiss}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md border border-border px-3 text-xs font-medium text-muted-foreground shadow-none transition-colors hover:bg-muted hover:text-foreground\"\n >\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n {labels.dismissButton}\n </button>\n </div>\n )\n}\n\nfunction Gate({ children }: { children: React.ReactNode }) {\n const { approvalState, hideApproveButton } = useSignalApproval()\n // When the approve button is hidden, don't lock content behind approval\n const isLocked = !hideApproveButton &&\n (approvalState === \"pending\" || approvalState === \"confirming\" || approvalState === \"creating\" || approvalState === \"dismissing\")\n\n return (\n <div className=\"relative\">\n {isLocked && (\n <div className=\"pointer-events-none absolute inset-x-0 top-4 z-10 flex justify-center\">\n <div className=\"flex items-center gap-1.5 rounded-full border border-border bg-background px-3 py-1.5 text-xs text-muted-foreground shadow-sm\">\n <Lock className=\"h-3 w-3\" />\n Approve or dismiss the signal above to unlock\n </div>\n </div>\n )}\n <div\n className={`transition-opacity duration-300 ${isLocked ? \"pointer-events-none select-none opacity-40\" : \"opacity-100\"}`}\n >\n {children}\n </div>\n </div>\n )\n}\n\nexport {\n Root as SignalApprovalRoot,\n Actions as SignalApprovalActions,\n Gate as SignalApprovalGate,\n}\nexport const SignalApproval = { Root, Actions, Gate }\nexport type OpportunityPreview = NonNullable<RootProps['opportunityPreview']>\nexport type { ApprovalState, SignalApprovalLabels, SignalApprovalContextValue, RootProps as SignalApprovalRootProps }\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/signal-feedback-inline.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Check, CirclePlus, ExternalLink, Loader2, Lock, ThumbsDown } from \"lucide-react\"\n\ninterface DismissReasonNode {\n label: string\n subOptions?: string[]\n}\n\nconst dismissReasonTree: DismissReasonNode[] = [\n {\n label: \"Not relevant for this account\",\n subOptions: [\n \"Business as usual for this account\",\n \"Account in maintenance mode\",\n \"Wrong contact for this signal\",\n \"Other\",\n ],\n },\n {\n label: \"Bad timing\",\n subOptions: [\n \"Too early in the relationship\",\n \"Too soon after last outreach\",\n \"Wrong time of year for this account\",\n \"Other\",\n ],\n },\n {\n label: \"Inaccurate data\",\n subOptions: [\n \"Wrong amount or number\",\n \"Stale data\",\n \"Account info wrong\",\n \"Other\",\n ],\n },\n {\n label: \"Wrong account\",\n subOptions: [\n \"Different account meant\",\n \"Account not in scope\",\n \"Other\",\n ],\n },\n {\n label: \"Already handled\",\n subOptions: [\n \"Already in conversation\",\n \"Already an open Opportunity\",\n \"Already escalated\",\n \"Other\",\n ],\n },\n {\n label: \"Not actionable\",\n subOptions: [\n \"No clear next step\",\n \"Outside our remit\",\n \"Other\",\n ],\n },\n { label: \"Other\" },\n]\n\nconst approveReasons = [\n \"Right timing\",\n \"Accurate data\",\n \"Good prospect fit\",\n \"Actionable\",\n]\n\ntype ApprovalState = \"pending\" | \"confirming\" | \"creating\" | \"approving-feedback\" | \"dismissing\" | \"approved\" | \"dismissed\" | \"auto-approved\"\n\ninterface OpportunityPreviewOption {\n value: string\n label: string\n}\n\ninterface OpportunityPreview {\n name: string\n stage: string\n closeDate: string\n closeDateValue?: string\n amount: string\n /** Raw draft input value. Numeric values render as currency in the editable field. */\n amountValue?: string | number | null\n accountName: string\n description?: string | null\n churnType?: string | null\n churnTypeOptions?: Array<string | OpportunityPreviewOption>\n}\n\ninterface OpportunityDraft {\n closeDate: string\n amount: string\n description: string\n churnType: string\n}\n\ninterface SignalApprovalLabels {\n approveButton?: string\n dismissButton?: string\n approvedStatus?: string\n dismissedStatus?: string\n opportunityCreated?: string\n confirmPrompt?: string\n dismissPrompt?: string\n feedbackPrompt?: string\n /** Label shown while the approve action is in progress (e.g. \"Creating Opportunity...\"). */\n creatingStatus?: string\n}\n\nconst DEFAULT_LABELS: Required<SignalApprovalLabels> = {\n approveButton: \"Approve action\",\n dismissButton: \"Not Helpful\",\n approvedStatus: \"Action Approved\",\n dismissedStatus: \"Action Dismissed\",\n opportunityCreated: \"Opportunity Created\",\n confirmPrompt: \"This will approve this action for\",\n dismissPrompt: \"What\\u2019s the issue with this action?\",\n feedbackPrompt: \"Quick feedback \\u2014 what made this action useful?\",\n creatingStatus: \"Creating\\u2026\",\n}\n\ninterface SignalApprovalContextValue {\n approvalState: ApprovalState\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n labels: Required<SignalApprovalLabels>\n hideApproveButton?: boolean\n approveButtonIconUrl?: string\n opportunityPreview?: OpportunityPreview\n requestingApproval: boolean\n approve: (draft?: OpportunityDraft) => void\n submitApproveFeedback: (reasons: string[], detail: string) => void\n skipApproveFeedback: () => void\n dismiss: (reasons: string[], detail: string, subReason?: string) => void\n requestApproval: () => void\n requestDismiss: () => void\n cancel: () => void\n}\n\nconst SignalApprovalCtx = React.createContext<SignalApprovalContextValue | null>(null)\n\nexport function useSignalApproval() {\n const ctx = React.useContext(SignalApprovalCtx)\n if (!ctx) throw new Error(\"SignalApproval components must be used within SignalApproval.Root\")\n return ctx\n}\n\ninterface RootProps {\n children: React.ReactNode\n companyName: string\n opportunityUrl?: string\n scheduledTime?: string\n initialApprovalState?: ApprovalState\n labels?: SignalApprovalLabels\n /** When true, the approve/create-opportunity button is hidden but the dismiss button remains. */\n hideApproveButton?: boolean\n /** Optional icon URL for the approve button. Renders an img instead of CirclePlus when provided. */\n approveButtonIconUrl?: string\n /** Optional structured preview data shown in the confirmation dialog. */\n opportunityPreview?: OpportunityPreview\n /**\n * Async callback fired when the user clicks the approve button, BEFORE\n * transitioning to the \"confirming\" state. While the promise is pending,\n * the button shows a loading spinner. On resolve, transitions to \"confirming\".\n * On reject, stays in \"pending\".\n */\n onRequestApproval?: () => Promise<void>\n /**\n * Called when the user confirms the approval action.\n *\n * - If the callback returns `void` (or `undefined`), the component transitions\n * directly to the feedback step (backward-compatible behavior).\n * - If the callback returns a `Promise<boolean>`, the component shows a\n * \"creating\" loading state while the promise is pending. On `true` it\n * transitions to the feedback step; on `false` it reverts to \"pending\".\n */\n onApprove?: (draft?: OpportunityDraft) => void | Promise<boolean>\n onApproveFeedback?: (reasons: string[], detail: string) => void\n onDismiss?: (reasons: string[], detail: string, subReason?: string) => void\n}\n\nfunction Root({ children, companyName, opportunityUrl, scheduledTime, initialApprovalState, labels: labelOverrides, hideApproveButton, approveButtonIconUrl, opportunityPreview, onRequestApproval, onApprove, onApproveFeedback, onDismiss }: RootProps) {\n const labels = React.useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides])\n const [approvalState, setApprovalState] = React.useState<ApprovalState>(initialApprovalState ?? \"pending\")\n const [requestingApproval, setRequestingApproval] = React.useState(false)\n\n // Guard against state updates after unmount (e.g. user navigates away while\n // an async onApprove promise is still in flight).\n const mountedRef = React.useRef(true)\n React.useEffect(() => {\n mountedRef.current = true\n return () => { mountedRef.current = false }\n }, [])\n\n const requestApproval = React.useCallback(() => {\n if (onRequestApproval) {\n setRequestingApproval(true)\n onRequestApproval()\n .then(() => {\n if (mountedRef.current) {\n setRequestingApproval(false)\n setApprovalState(\"confirming\")\n }\n })\n .catch(() => {\n if (mountedRef.current) {\n setRequestingApproval(false)\n }\n })\n } else {\n setApprovalState(\"confirming\")\n }\n }, [onRequestApproval])\n\n const requestDismiss = React.useCallback(() => {\n setApprovalState(\"dismissing\")\n }, [])\n\n const cancel = React.useCallback(() => {\n setApprovalState(\"pending\")\n }, [])\n\n const approve = React.useCallback((draft?: OpportunityDraft) => {\n const result = onApprove?.(draft)\n // If the callback returns a Promise, show a loading state and wait for it.\n if (result && typeof (result as Promise<boolean>).then === \"function\") {\n setApprovalState(\"creating\")\n ;(result as Promise<boolean>).then((success) => {\n if (mountedRef.current) {\n setApprovalState(success ? \"approving-feedback\" : \"pending\")\n }\n }).catch(() => {\n if (mountedRef.current) {\n setApprovalState(\"pending\")\n }\n })\n } else {\n // Synchronous / void — transition immediately (backward-compatible).\n setApprovalState(\"approving-feedback\")\n }\n }, [onApprove])\n\n const submitApproveFeedback = React.useCallback(\n (reasons: string[], detail: string) => {\n setApprovalState(\"approved\")\n onApproveFeedback?.(reasons, detail)\n },\n [onApproveFeedback]\n )\n\n const skipApproveFeedback = React.useCallback(() => {\n setApprovalState(\"approved\")\n }, [])\n\n const dismiss = React.useCallback(\n (reasons: string[], detail: string, subReason?: string) => {\n setApprovalState(\"dismissed\")\n onDismiss?.(reasons, detail, subReason)\n },\n [onDismiss]\n )\n\n return (\n <SignalApprovalCtx.Provider\n value={{ approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel }}\n >\n {children}\n </SignalApprovalCtx.Provider>\n )\n}\n\n/** Shared dismiss reason picker used in both the \"editing\" and \"initial dismiss\" paths. */\nfunction DismissReasonPicker({\n selectedTopReason,\n selectedSubReason,\n selectTopReason,\n selectSubReason,\n detailText,\n setDetailText,\n needsText,\n canSubmitDismiss,\n handleDismissSubmit,\n topNode,\n submitLabel,\n onCancel,\n}: {\n selectedTopReason: string | null\n selectedSubReason: string | null\n selectTopReason: (label: string) => void\n selectSubReason: (label: string) => void\n detailText: string\n setDetailText: (value: string) => void\n needsText: boolean\n canSubmitDismiss: boolean\n handleDismissSubmit: () => void\n topNode: DismissReasonNode | undefined\n submitLabel: string\n onCancel: () => void\n}) {\n return (\n <>\n <div className=\"flex flex-wrap gap-1.5\">\n {dismissReasonTree.map((node) => {\n const selected = selectedTopReason === node.label\n return (\n <button\n key={node.label}\n type=\"button\"\n onClick={() => selectTopReason(node.label)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-red-200 bg-red-100 text-red-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {node.label}\n </button>\n )\n })}\n </div>\n\n {topNode?.subOptions && (\n <div className=\"ml-3 border-l-2 border-muted pl-3\">\n <div className=\"flex flex-wrap gap-1.5\">\n {topNode.subOptions.map((sub) => {\n const selected = selectedSubReason === sub\n return (\n <button\n key={sub}\n type=\"button\"\n onClick={() => selectSubReason(sub)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-red-200 bg-red-100 text-red-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {sub}\n </button>\n )\n })}\n </div>\n </div>\n )}\n\n {selectedTopReason && (\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && canSubmitDismiss) handleDismissSubmit()\n }}\n placeholder={needsText ? \"Please describe (required)\" : \"Add context (optional)\"}\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleDismissSubmit}\n disabled={!canSubmitDismiss}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${\n canSubmitDismiss\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"cursor-not-allowed bg-muted text-muted-foreground\"\n }`}\n >\n {submitLabel}\n </button>\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n </>\n )\n}\n\nfunction SubmittedFeedback({\n reasons,\n detail,\n subReason,\n variant,\n onEdit,\n}: {\n reasons: string[]\n detail: string\n subReason?: string\n variant: \"approve\" | \"dismiss\"\n onEdit: () => void\n}) {\n if (reasons.length === 0 && !detail) return null\n const pillClass =\n variant === \"approve\"\n ? \"border-emerald-200/60 bg-emerald-50/50 text-emerald-700/70\"\n : \"border-red-200/60 bg-red-50/50 text-red-700/70\"\n\n return (\n <button\n type=\"button\"\n onClick={onEdit}\n className=\"w-full text-left space-y-1.5 group cursor-pointer\"\n >\n {reasons.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {reasons.map((r) => (\n <span\n key={r}\n className={`rounded-full border px-2 py-0.5 text-[10px] font-medium transition-colors group-hover:opacity-80 ${pillClass}`}\n >\n {r}\n </span>\n ))}\n {subReason && (\n <span\n className={`rounded-full border px-2 py-0.5 text-[10px] font-medium transition-colors group-hover:opacity-80 ${pillClass}`}\n >\n {subReason}\n </span>\n )}\n </div>\n )}\n {detail && (\n <p className=\"text-[11px] text-muted-foreground/70 leading-snug group-hover:text-muted-foreground transition-colors\">{detail}</p>\n )}\n </button>\n )\n}\n\nfunction optionValue(option: string | OpportunityPreviewOption): string {\n return typeof option === \"string\" ? option : option.value\n}\n\nfunction optionLabel(option: string | OpportunityPreviewOption): string {\n return typeof option === \"string\" ? option : option.label\n}\n\nfunction formatAmountDraftValue(value: string | number | null | undefined): string {\n if (value == null || value === \"\") return \"\"\n if (typeof value === \"number\") {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n maximumFractionDigits: 0,\n }).format(value)\n }\n return value\n}\n\nfunction buildOpportunityDraft(preview?: OpportunityPreview): OpportunityDraft {\n return {\n closeDate: preview?.closeDateValue ?? preview?.closeDate ?? \"\",\n amount: preview?.amountValue === undefined\n ? preview?.amount ?? \"\"\n : formatAmountDraftValue(preview.amountValue),\n description: preview?.description ?? \"\",\n churnType: preview?.churnType ?? \"\",\n }\n}\n\nfunction hasEditableOpportunityPreview(preview?: OpportunityPreview): boolean {\n return !!preview && isValidDateInput(preview.closeDateValue ?? preview.closeDate)\n}\n\nfunction isValidDateInput(value: string): boolean {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value)\n if (!match) return false\n const parsed = new Date(`${value}T00:00:00Z`)\n if (Number.isNaN(parsed.getTime())) return false\n return parsed.toISOString().slice(0, 10) === value\n}\n\nfunction Actions() {\n const { approvalState, companyName, opportunityUrl, scheduledTime, labels, hideApproveButton, approveButtonIconUrl, opportunityPreview, requestingApproval, approve, submitApproveFeedback, skipApproveFeedback, dismiss, requestApproval, requestDismiss, cancel } =\n useSignalApproval()\n const [selectedTopReason, setSelectedTopReason] = React.useState<string | null>(null)\n const [selectedSubReason, setSelectedSubReason] = React.useState<string | null>(null)\n const [selectedReasons, setSelectedReasons] = React.useState<string[]>([])\n const [detailText, setDetailText] = React.useState(\"\")\n const [submittedFeedback, setSubmittedFeedback] = React.useState<{ reasons: string[]; detail: string; subReason?: string } | null>(null)\n const [isEditing, setIsEditing] = React.useState(false)\n const [opportunityDraft, setOpportunityDraft] = React.useState<OpportunityDraft>(() => buildOpportunityDraft(opportunityPreview))\n\n React.useEffect(() => {\n if (approvalState === \"confirming\") {\n setOpportunityDraft(buildOpportunityDraft(opportunityPreview))\n }\n }, [approvalState, opportunityPreview])\n\n const churnTypeOptions = opportunityPreview?.churnTypeOptions ?? []\n const hasChurnTypeOptions = churnTypeOptions.length > 0\n\n const topNode = dismissReasonTree.find((n) => n.label === selectedTopReason)\n const hasSubOptions = !!(topNode?.subOptions && topNode.subOptions.length > 0)\n const isTopOther = selectedTopReason === \"Other\" && !hasSubOptions\n const isSubOther = selectedSubReason === \"Other\"\n const needsText = isTopOther || isSubOther\n const canSubmitDismiss =\n selectedTopReason !== null &&\n (!hasSubOptions || selectedSubReason !== null) &&\n (!needsText || detailText.trim().length > 0)\n\n const canSubmitApprove = selectedReasons.length > 0 || detailText.trim().length > 0\n const isEditableOpportunityPreview = hasEditableOpportunityPreview(opportunityPreview)\n const canConfirmOpportunity = !isEditableOpportunityPreview || isValidDateInput(opportunityDraft.closeDate)\n\n const selectTopReason = (label: string) => {\n if (selectedTopReason === label) {\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setDetailText(\"\")\n } else {\n setSelectedTopReason(label)\n setSelectedSubReason(null)\n setDetailText(\"\")\n }\n }\n\n const selectSubReason = (label: string) => {\n setSelectedSubReason(selectedSubReason === label ? null : label)\n }\n\n const toggleReason = (reason: string) => {\n setSelectedReasons((prev) =>\n prev.includes(reason) ? prev.filter((r) => r !== reason) : [...prev, reason]\n )\n }\n\n const startEditing = () => {\n if (submittedFeedback) {\n setSelectedTopReason(submittedFeedback.reasons[0] ?? null)\n setSelectedSubReason(submittedFeedback.subReason ?? null)\n // Note: selectedReasons is only used by the approve editing path.\n // For dismiss feedback this is harmless but unused — the dismiss path\n // reads selectedTopReason/selectedSubReason instead.\n setSelectedReasons([...submittedFeedback.reasons])\n setDetailText(submittedFeedback.detail)\n }\n setIsEditing(true)\n }\n\n const handleDismissSubmit = () => {\n if (!canSubmitDismiss || !selectedTopReason) return\n const fb = { reasons: [selectedTopReason], detail: detailText.trim(), subReason: selectedSubReason ?? undefined }\n setSubmittedFeedback(fb)\n dismiss([selectedTopReason], detailText.trim(), selectedSubReason ?? undefined)\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleApproveSubmit = () => {\n const fb = { reasons: [...selectedReasons], detail: detailText.trim() }\n setSubmittedFeedback(fb)\n submitApproveFeedback(selectedReasons, detailText.trim())\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleEditCancel = () => {\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setSelectedReasons([])\n setDetailText(\"\")\n setIsEditing(false)\n }\n\n const handleCancel = () => {\n cancel()\n setSelectedTopReason(null)\n setSelectedSubReason(null)\n setSelectedReasons([])\n setDetailText(\"\")\n }\n\n if (approvalState === \"creating\") {\n return (\n <div className=\"flex items-center gap-2 text-xs font-medium text-muted-foreground\">\n <svg className=\"h-3.5 w-3.5 animate-spin\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n <span>{labels.creatingStatus}</span>\n </div>\n )\n }\n\n if (approvalState === \"approved\") {\n if (isEditing) {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600 mb-2\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a href={opportunityUrl} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\">\n {labels.approvedStatus} <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.approvedStatus}</span>\n )}\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">Edit your feedback</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {approveReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button key={reason} type=\"button\" onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected ? \"border-emerald-200 bg-emerald-100 text-emerald-700\" : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}>{reason}</button>\n )\n })}\n </div>\n <input type=\"text\" value={detailText} onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => { if (e.key === \"Enter\" && canSubmitApprove) handleApproveSubmit() }}\n placeholder=\"Tell us more (optional)\"\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\" />\n <div className=\"flex items-center gap-2\">\n <button type=\"button\" onClick={handleApproveSubmit} disabled={!canSubmitApprove}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${canSubmitApprove ? \"bg-foreground text-background hover:bg-foreground/90\" : \"cursor-not-allowed bg-muted text-muted-foreground\"}`}>\n Save\n </button>\n <button type=\"button\" onClick={handleEditCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\">\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a\n href={opportunityUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\"\n >\n {labels.opportunityCreated}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.opportunityCreated}</span>\n )}\n </div>\n {submittedFeedback && (\n <SubmittedFeedback\n reasons={submittedFeedback.reasons}\n detail={submittedFeedback.detail}\n variant=\"approve\"\n onEdit={startEditing}\n />\n )}\n </div>\n )\n }\n\n if (approvalState === \"auto-approved\") {\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600\">\n <Check className=\"h-3.5 w-3.5\" />\n <span>{labels.approvedStatus}</span>\n </div>\n {scheduledTime && (\n <p className=\"text-[11px] text-muted-foreground\">Scheduled: {scheduledTime}</p>\n )}\n </div>\n )\n }\n\n if (approvalState === \"approving-feedback\") {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium text-emerald-600 mb-2\">\n <Check className=\"h-3.5 w-3.5\" />\n {opportunityUrl ? (\n <a\n href={opportunityUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 hover:underline underline-offset-2\"\n >\n {labels.opportunityCreated}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n ) : (\n <span>{labels.opportunityCreated}</span>\n )}\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">{labels.feedbackPrompt}</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {approveReasons.map((reason) => {\n const selected = selectedReasons.includes(reason)\n return (\n <button\n key={reason}\n type=\"button\"\n onClick={() => toggleReason(reason)}\n className={`rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${\n selected\n ? \"border-emerald-200 bg-emerald-100 text-emerald-700\"\n : \"border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground\"\n }`}\n >\n {reason}\n </button>\n )\n })}\n </div>\n\n <input\n type=\"text\"\n value={detailText}\n onChange={(e) => setDetailText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && canSubmitApprove) handleApproveSubmit()\n }}\n placeholder=\"Tell us more (optional)\"\n className=\"h-7 w-full rounded-md border border-border bg-muted/20 px-2.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleApproveSubmit}\n disabled={!canSubmitApprove}\n className={`inline-flex h-7 items-center gap-1.5 rounded-md px-3 text-xs font-semibold transition-colors ${\n canSubmitApprove\n ? \"bg-foreground text-background hover:bg-foreground/90\"\n : \"cursor-not-allowed bg-muted text-muted-foreground\"\n }`}\n >\n Submit\n </button>\n <button\n type=\"button\"\n onClick={skipApproveFeedback}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Skip\n </button>\n </div>\n </div>\n )\n }\n\n if (approvalState === \"dismissed\") {\n if (isEditing) {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground mb-2\">\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n <span>{labels.dismissedStatus}</span>\n </div>\n <p className=\"text-xs font-medium text-muted-foreground\">Edit your feedback</p>\n <DismissReasonPicker\n selectedTopReason={selectedTopReason}\n selectedSubReason={selectedSubReason}\n selectTopReason={selectTopReason}\n selectSubReason={selectSubReason}\n detailText={detailText}\n setDetailText={setDetailText}\n needsText={needsText}\n canSubmitDismiss={canSubmitDismiss}\n handleDismissSubmit={handleDismissSubmit}\n topNode={topNode}\n submitLabel=\"Save\"\n onCancel={handleEditCancel}\n />\n </div>\n )\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n <span>{labels.dismissedStatus}</span>\n </div>\n {submittedFeedback && (\n <SubmittedFeedback\n reasons={submittedFeedback.reasons}\n detail={submittedFeedback.detail}\n subReason={submittedFeedback.subReason}\n variant=\"dismiss\"\n onEdit={startEditing}\n />\n )}\n </div>\n )\n }\n\n if (approvalState === \"confirming\") {\n return (\n <div className=\"space-y-3\">\n <div className=\"rounded-md border border-border bg-muted/30 p-3\">\n <p className=\"text-sm text-foreground\">\n {labels.confirmPrompt} <strong>{companyName}</strong>. Confirm?\n </p>\n {opportunityPreview && !isEditableOpportunityPreview && (\n <div className=\"mt-3 space-y-2 border-t border-border/50 pt-3\">\n {[\n { label: \"Opportunity\", value: opportunityPreview.name },\n { label: \"Account\", value: opportunityPreview.accountName },\n { label: \"Stage\", value: opportunityPreview.stage },\n { label: \"Close Date\", value: opportunityPreview.closeDate },\n { label: \"Amount\", value: opportunityPreview.amount },\n ].map(({ label, value }) => (\n <div key={label} className=\"flex items-center justify-between gap-3 text-xs\">\n <span className=\"text-muted-foreground\">{label}</span>\n <span className=\"text-right font-medium text-foreground\">{value}</span>\n </div>\n ))}\n </div>\n )}\n {opportunityPreview && isEditableOpportunityPreview && (\n <div className=\"mt-3 space-y-3 border-t border-border/50 pt-3\">\n {[\n { label: \"Opportunity\", value: opportunityPreview.name },\n { label: \"Account\", value: opportunityPreview.accountName },\n { label: \"Stage\", value: opportunityPreview.stage },\n ].map(({ label, value }) => (\n <div key={label} className=\"flex items-center justify-between gap-3 text-xs\">\n <span className=\"text-muted-foreground\">{label}</span>\n <span className=\"text-right font-medium text-foreground\">{value}</span>\n </div>\n ))}\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Close Date</span>\n <input\n type=\"date\"\n value={opportunityDraft.closeDate}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, closeDate: event.target.value }))}\n aria-invalid={!canConfirmOpportunity}\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n {!canConfirmOpportunity && (\n <span className=\"text-[11px] text-red-600\">Enter a valid close date.</span>\n )}\n </label>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Amount</span>\n <input\n type=\"text\"\n inputMode=\"decimal\"\n value={opportunityDraft.amount}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, amount: event.target.value }))}\n placeholder={opportunityPreview.amount}\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </label>\n </div>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Churn Type</span>\n {hasChurnTypeOptions ? (\n <select\n value={opportunityDraft.churnType}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, churnType: event.target.value }))}\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n >\n <option value=\"\">No churn type</option>\n {churnTypeOptions.map((option) => (\n <option key={optionValue(option)} value={optionValue(option)}>\n {optionLabel(option)}\n </option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n value={opportunityDraft.churnType}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, churnType: event.target.value }))}\n placeholder=\"No churn type\"\n className=\"h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n )}\n </label>\n\n <label className=\"space-y-1 text-xs\">\n <span className=\"font-medium text-muted-foreground\">Description</span>\n <textarea\n value={opportunityDraft.description}\n onChange={(event) => setOpportunityDraft((draft) => ({ ...draft, description: event.target.value }))}\n rows={3}\n placeholder=\"Add a short description\"\n className=\"w-full resize-none rounded-md border border-border bg-background px-2 py-1.5 text-xs text-foreground placeholder:text-muted-foreground/60 focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </label>\n </div>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n if (!opportunityPreview) {\n approve()\n return\n }\n approve(isEditableOpportunityPreview ? opportunityDraft : undefined)\n }}\n disabled={!canConfirmOpportunity}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-semibold text-background transition-colors hover:bg-foreground/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground\"\n >\n <Check className=\"h-3 w-3\" />\n Confirm\n </button>\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"inline-flex h-7 items-center rounded-md border border-border px-3 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n </div>\n </div>\n )\n }\n\n if (approvalState === \"dismissing\") {\n return (\n <div className=\"space-y-3\">\n <p className=\"text-xs font-medium text-muted-foreground\">{labels.dismissPrompt}</p>\n <DismissReasonPicker\n selectedTopReason={selectedTopReason}\n selectedSubReason={selectedSubReason}\n selectTopReason={selectTopReason}\n selectSubReason={selectSubReason}\n detailText={detailText}\n setDetailText={setDetailText}\n needsText={needsText}\n canSubmitDismiss={canSubmitDismiss}\n handleDismissSubmit={handleDismissSubmit}\n topNode={topNode}\n submitLabel=\"Submit\"\n onCancel={handleCancel}\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex items-center gap-2\">\n {!hideApproveButton && (\n <button\n type=\"button\"\n onClick={requestApproval}\n disabled={requestingApproval}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md border border-border bg-foreground px-3 text-xs font-semibold text-background shadow-none transition-colors hover:bg-foreground/90 disabled:opacity-50\"\n >\n {requestingApproval ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : approveButtonIconUrl ? (\n <img src={approveButtonIconUrl} alt=\"\" className=\"h-3.5 w-3.5 object-contain\" draggable={false} />\n ) : (\n <CirclePlus className=\"h-3.5 w-3.5\" />\n )}\n {labels.approveButton}\n </button>\n )}\n <button\n type=\"button\"\n onClick={requestDismiss}\n className=\"inline-flex h-7 items-center gap-1.5 rounded-md border border-border px-3 text-xs font-medium text-muted-foreground shadow-none transition-colors hover:bg-muted hover:text-foreground\"\n >\n <ThumbsDown className=\"h-3.5 w-3.5\" />\n {labels.dismissButton}\n </button>\n </div>\n )\n}\n\nfunction Gate({ children }: { children: React.ReactNode }) {\n const { approvalState, hideApproveButton } = useSignalApproval()\n // When the approve button is hidden, don't lock content behind approval\n const isLocked = !hideApproveButton &&\n (approvalState === \"pending\" || approvalState === \"confirming\" || approvalState === \"creating\" || approvalState === \"dismissing\")\n\n return (\n <div className=\"relative\">\n {isLocked && (\n <div className=\"pointer-events-none absolute inset-x-0 top-4 z-10 flex justify-center\">\n <div className=\"flex items-center gap-1.5 rounded-full border border-border bg-background px-3 py-1.5 text-xs text-muted-foreground shadow-sm\">\n <Lock className=\"h-3 w-3\" />\n Approve or dismiss the signal above to unlock\n </div>\n </div>\n )}\n <div\n className={`transition-opacity duration-300 ${isLocked ? \"pointer-events-none select-none opacity-40\" : \"opacity-100\"}`}\n >\n {children}\n </div>\n </div>\n )\n}\n\nexport {\n Root as SignalApprovalRoot,\n Actions as SignalApprovalActions,\n Gate as SignalApprovalGate,\n}\nexport const SignalApproval = { Root, Actions, Gate }\nexport type { ApprovalState, OpportunityPreview, OpportunityDraft, SignalApprovalLabels, SignalApprovalContextValue, RootProps as SignalApprovalRootProps }\n"],"mappings":"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","names":["_a"]}
@@ -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, l as SignalPriorityScoreDisplay } from '../signal-priority-popover-DTedstRL.js';
3
+ export { P as PriorityFactor, S as SignalPriorityPopover, k as SignalPriorityPopoverProps } from '../signal-priority-popover-QJngMAj7.js';
4
4
  import './quick-action-sidebar-nav.js';
5
5
  import './quick-action-modal.js';
6
6
  import './score-breakdown.js';
@@ -161,9 +161,7 @@ function SignalPriorityPopover({
161
161
  className,
162
162
  initialFactorFeedback,
163
163
  onFactorFeedback,
164
- initialPriorityFeedback,
165
- scoreDisplay = "number",
166
- formulaLabel = "Priority factors"
164
+ initialPriorityFeedback
167
165
  }) {
168
166
  const urgencyLabel = providedLabel != null ? providedLabel : getUrgencyLevel(score);
169
167
  const scoreRange = getUrgencyRange(urgencyLabel);
@@ -204,24 +202,17 @@ function SignalPriorityPopover({
204
202
  className: "z-50 w-[420px] rounded-lg border border-border bg-background shadow-lg p-0",
205
203
  "data-testid": "priority-popover-content",
206
204
  children: [
207
- /* @__PURE__ */ jsxs("div", { className: "p-4 pb-3", "data-testid": "priority-popover-header", children: [
205
+ /* @__PURE__ */ jsxs("div", { className: "p-4 pb-3", children: [
208
206
  /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
209
207
  /* @__PURE__ */ jsxs("p", { className: "text-sm font-semibold text-foreground", children: [
210
208
  "Why this is ",
211
209
  urgencyLabel.toLowerCase(),
212
210
  " priority"
213
211
  ] }),
214
- scoreDisplay === "number" && /* @__PURE__ */ jsxs(
215
- "span",
216
- {
217
- className: "text-2xl font-bold tabular-nums text-foreground",
218
- "data-testid": "priority-overall-score",
219
- children: [
220
- score,
221
- /* @__PURE__ */ jsx("span", { className: "text-sm font-normal text-muted-foreground", children: "/100" })
222
- ]
223
- }
224
- )
212
+ /* @__PURE__ */ jsxs("span", { className: "text-2xl font-bold tabular-nums text-foreground", children: [
213
+ score,
214
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-normal text-muted-foreground", children: "/100" })
215
+ ] })
225
216
  ] }),
226
217
  /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-1.5 text-[11px] text-muted-foreground", children: [
227
218
  /* @__PURE__ */ jsx(
@@ -244,7 +235,7 @@ function SignalPriorityPopover({
244
235
  /* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold uppercase tracking-wider text-muted-foreground", children: "Contributing factors" }),
245
236
  /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[10px] text-muted-foreground", children: [
246
237
  /* @__PURE__ */ jsx(Info, { className: "h-3 w-3" }),
247
- formulaLabel
238
+ "Score = weighted sum"
248
239
  ] })
249
240
  ] }),
250
241
  /* @__PURE__ */ jsx("div", { className: "divide-y divide-border/40", children: factors.map((factor) => /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/signal-priority-popover.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"radix-ui\"\nimport type { LucideIcon } from \"lucide-react\"\nimport {\n Radar,\n Wallet,\n Link2,\n MessageSquare,\n TrendingDown,\n ArrowUpRight,\n ArrowDownRight,\n Clock,\n Activity,\n Minus,\n ChevronDown,\n ChevronUp,\n Info,\n} from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\nimport { FeedbackFooter, InlineFeedbackControl } from \"./feedback-primitives\"\nimport type { FeedbackChipTree, FeedbackSubmitData, PersistedFeedbackData } from \"./feedback-primitives\"\nimport type { SignalScoreUrgencyLabel } from \"../prototype/prototype-config\"\nimport { SCORE_TONE_CLASSES, URGENCY_SCORE_CLASSES, getUrgencyLevel, getUrgencyRange } from \"./score-semantics\"\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A single contributing factor in the priority popover.\n */\nexport interface PriorityFactor {\n key: string\n label: string\n /** Lucide icon name (e.g. \"radar\", \"wallet\", \"link-2\", \"message-square\"). */\n icon: string\n /** Drives icon background tint. */\n tone: \"alert\" | \"warn\" | \"info\"\n /** Explicit semantic label - NOT inferred from score+weight. */\n direction: \"raises\" | \"lowers\" | \"neutral\"\n /** Optional display label for the direction text. Keeps semantic direction icon/color unchanged. */\n directionLabel?: string\n /** 0-100 */\n score: number\n /** Optional display label rendered instead of the numeric score cell. */\n displayValueLabel?: string\n /** Evidence text (e.g. \"$3.4M moved in 8h - current treasury balance $0.00\"). */\n rationale: string\n}\n\nexport type SignalPriorityScoreDisplay = \"label\" | \"number\"\n\nexport interface SignalPriorityPopoverProps {\n score: number\n /** Controls whether the overall score number is shown in the popover header. @default \"number\" */\n scoreDisplay?: SignalPriorityScoreDisplay\n /** Short formula/context label shown beside the contributing factors heading. @default \"Priority factors\" */\n formulaLabel?: string\n urgencyLabel?: SignalScoreUrgencyLabel\n /** Synthesis sentence displayed in the popover head. */\n urgencyExplanation?: string\n factors: PriorityFactor[]\n /** e.g. \"Updated 4m ago - model v3.2\" */\n metaText?: string\n /** Negative feedback issue tree. */\n feedbackChips?: FeedbackChipTree[]\n onFeedbackSubmit?: (data: FeedbackSubmitData) => void\n className?: string\n /** Persisted factor-level feedback (keyed by factor key). */\n initialFactorFeedback?: Record<string, { type: \"up\" | \"down\"; detail: string; ownershipLabel?: string }>\n /** Callback when user submits factor-level feedback. */\n onFactorFeedback?: (factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n /** Persisted priority-level feedback for the footer. */\n initialPriorityFeedback?: PersistedFeedbackData | null\n}\n\n// ---------------------------------------------------------------------------\n// Static class maps (required for Tailwind v4 source scanning)\n// ---------------------------------------------------------------------------\n\nconst URGENCY_TRIGGER_DEFAULT: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.trigger,\n High: URGENCY_SCORE_CLASSES.High.trigger,\n Medium: URGENCY_SCORE_CLASSES.Medium.trigger,\n Low: URGENCY_SCORE_CLASSES.Low.trigger,\n}\n\nconst URGENCY_TRIGGER_HOVER: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.hover,\n High: URGENCY_SCORE_CLASSES.High.hover,\n Medium: URGENCY_SCORE_CLASSES.Medium.hover,\n Low: URGENCY_SCORE_CLASSES.Low.hover,\n}\n\nconst URGENCY_TRIGGER_OPEN: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.open,\n High: URGENCY_SCORE_CLASSES.High.open,\n Medium: URGENCY_SCORE_CLASSES.Medium.open,\n Low: URGENCY_SCORE_CLASSES.Low.open,\n}\n\n/** Re-use shared tone classes from score-semantics. */\nconst TONE_ICON_CLASSES: Record<PriorityFactor[\"tone\"], string> = SCORE_TONE_CLASSES as Record<PriorityFactor[\"tone\"], string>\n\nconst DIRECTION_CLASSES: Record<PriorityFactor[\"direction\"], string> = {\n raises: \"text-red-600\",\n lowers: \"text-emerald-600\",\n neutral: \"text-muted-foreground\",\n}\n\n// ---------------------------------------------------------------------------\n// Icon lookup\n// ---------------------------------------------------------------------------\n\nconst FACTOR_ICONS: Record<string, LucideIcon> = {\n radar: Radar,\n wallet: Wallet,\n \"link-2\": Link2,\n \"message-square\": MessageSquare,\n \"trending-down\": TrendingDown,\n \"arrow-up-right\": ArrowUpRight,\n clock: Clock,\n activity: Activity,\n}\n\n// ---------------------------------------------------------------------------\n// Urgency dot color (static map)\n// ---------------------------------------------------------------------------\n\nconst URGENCY_DOT_CLASSES: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.dot,\n High: URGENCY_SCORE_CLASSES.High.dot,\n Medium: URGENCY_SCORE_CLASSES.Medium.dot,\n Low: URGENCY_SCORE_CLASSES.Low.dot,\n}\n\n// ---------------------------------------------------------------------------\n// Default feedback chips\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_PRIORITY_FEEDBACK_CHIPS: FeedbackChipTree[] = [\n { label: \"Wrong factor weighting\" },\n { label: \"Missing context\" },\n { label: \"Inaccurate data\" },\n { label: \"Stale\" },\n { label: \"Other\" },\n]\n\n// ---------------------------------------------------------------------------\n// Direction icon component\n// ---------------------------------------------------------------------------\n\nfunction DirectionIcon({ direction }: { direction: PriorityFactor[\"direction\"] }) {\n const cls = \"h-2.5 w-2.5\"\n switch (direction) {\n case \"raises\":\n return <ArrowUpRight className={cls} />\n case \"lowers\":\n return <ArrowDownRight className={cls} />\n case \"neutral\":\n return <Minus className={cls} />\n }\n}\n\n// ---------------------------------------------------------------------------\n// PriorityFactorRow\n// ---------------------------------------------------------------------------\n\ninterface PriorityFactorRowProps {\n factor: PriorityFactor\n initialFeedback?: { type: \"up\" | \"down\"; detail: string; ownershipLabel?: string }\n onFactorFeedback?: (factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n}\n\nfunction PriorityFactorRow({ factor, initialFeedback, onFactorFeedback }: PriorityFactorRowProps) {\n const IconComponent = FACTOR_ICONS[factor.icon] ?? Activity\n const toneClasses = TONE_ICON_CLASSES[factor.tone]\n const directionClasses = DIRECTION_CLASSES[factor.direction]\n const directionLabel = factor.directionLabel ?? (\n factor.direction === \"raises\"\n ? \"Raises\"\n : factor.direction === \"lowers\"\n ? \"Lowers\"\n : \"Neutral\"\n )\n\n return (\n <div\n className=\"grid grid-cols-[20px_1fr_auto] gap-x-3 gap-y-1 px-4 py-3\"\n data-testid={`factor-row-${factor.key}`}\n >\n {/* Icon */}\n <div\n className={cn(\n \"flex h-5 w-5 items-center justify-center rounded\",\n toneClasses,\n )}\n >\n <IconComponent className=\"h-3 w-3\" />\n </div>\n\n {/* Label + direction tag */}\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[13px] font-semibold text-foreground\">\n {factor.label}\n </span>\n <span\n className={cn(\n \"inline-flex items-center gap-0.5 text-[10px] font-medium\",\n directionClasses,\n )}\n >\n <DirectionIcon direction={factor.direction} />\n {directionLabel}\n </span>\n </div>\n\n {/* Score number / display label */}\n <div className=\"flex items-center text-right\">\n {factor.displayValueLabel ? (\n <span className=\"text-xs font-semibold text-foreground\">{factor.displayValueLabel}</span>\n ) : (\n <>\n <span className=\"text-sm font-bold tabular-nums\">{factor.score}</span>\n <span className=\"text-xs font-normal text-muted-foreground\">/100</span>\n </>\n )}\n </div>\n\n {/* empty grid cell under icon column */}\n <div />\n\n {/* Rationale */}\n <p className=\"text-xs leading-relaxed text-muted-foreground\">\n {factor.rationale}\n </p>\n\n {/* empty grid cell under score column */}\n <div />\n\n {/* empty grid cell under icon column */}\n <div />\n\n {/* Score track */}\n <div className=\"mt-1 h-0.5 rounded-full bg-muted\">\n <div\n className=\"h-full rounded-full bg-foreground/20\"\n style={{ width: `${Math.min(100, Math.max(0, factor.score))}%` }}\n />\n </div>\n\n {/* empty grid cell under score column */}\n <div />\n\n {/* Factor-level feedback row (spans icon + content columns) */}\n {onFactorFeedback && (\n <>\n <div />\n <div className=\"col-span-2 mt-1\">\n <InlineFeedbackControl\n feedbackKey={factor.key}\n initialFeedback={initialFeedback}\n onFeedback={onFactorFeedback}\n testIdPrefix=\"factor\"\n />\n </div>\n </>\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SignalPriorityPopover\n// ---------------------------------------------------------------------------\n\nexport function SignalPriorityPopover({\n score,\n urgencyLabel: providedLabel,\n urgencyExplanation,\n factors,\n metaText,\n feedbackChips,\n onFeedbackSubmit,\n className,\n initialFactorFeedback,\n onFactorFeedback,\n initialPriorityFeedback,\n scoreDisplay = \"number\",\n formulaLabel = \"Priority factors\",\n}: SignalPriorityPopoverProps) {\n const urgencyLabel = providedLabel ?? getUrgencyLevel(score)\n const scoreRange = getUrgencyRange(urgencyLabel)\n\n const [open, setOpen] = React.useState(false)\n const [feedback, setFeedback] = React.useState<\"positive\" | \"negative\" | null>(null)\n\n const triggerDefault = URGENCY_TRIGGER_DEFAULT[urgencyLabel]\n const triggerHover = URGENCY_TRIGGER_HOVER[urgencyLabel]\n const triggerOpen = URGENCY_TRIGGER_OPEN[urgencyLabel]\n\n // Derive a stable feedbackKey for the footer from score + urgencyLabel\n const footerFeedbackKey = `priority-${score}-${urgencyLabel}`\n\n return (\n <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n <PopoverPrimitive.Trigger asChild>\n <button\n type=\"button\"\n className={cn(\n \"inline-flex items-center gap-1 rounded-md border px-2.5 py-1 text-xs font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n triggerDefault,\n triggerHover,\n open && triggerOpen,\n open && \"outline-2 outline-foreground outline-offset-2\",\n className,\n )}\n data-testid=\"priority-popover-trigger\"\n >\n {urgencyLabel} Priority\n {open ? (\n <ChevronUp className=\"h-3 w-3\" />\n ) : (\n <ChevronDown className=\"h-3 w-3\" />\n )}\n </button>\n </PopoverPrimitive.Trigger>\n\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n side=\"bottom\"\n align=\"start\"\n sideOffset={8}\n onOpenAutoFocus={(e) => e.preventDefault()}\n className=\"z-50 w-[420px] rounded-lg border border-border bg-background shadow-lg p-0\"\n data-testid=\"priority-popover-content\"\n >\n {/* Head section */}\n <div className=\"p-4 pb-3\" data-testid=\"priority-popover-header\">\n <div className=\"flex items-start justify-between gap-3\">\n <p className=\"text-sm font-semibold text-foreground\">\n Why this is {urgencyLabel.toLowerCase()} priority\n </p>\n {scoreDisplay === \"number\" && (\n <span\n className=\"text-2xl font-bold tabular-nums text-foreground\"\n data-testid=\"priority-overall-score\"\n >\n {score}\n <span className=\"text-sm font-normal text-muted-foreground\">/100</span>\n </span>\n )}\n </div>\n\n {/* Band indicator */}\n <div className=\"mt-1 flex items-center gap-1.5 text-[11px] text-muted-foreground\">\n <span\n className={cn(\n \"inline-block h-2 w-2 rounded-full\",\n URGENCY_DOT_CLASSES[urgencyLabel],\n )}\n />\n {urgencyLabel} range: {scoreRange}\n </div>\n\n {/* Synthesis sentence */}\n {urgencyExplanation && (\n <p className=\"mt-2 text-xs leading-relaxed text-muted-foreground\">\n {urgencyExplanation}\n </p>\n )}\n </div>\n\n {/* Section label */}\n {factors.length > 0 && (\n <>\n <div className=\"flex items-center justify-between border-t border-border px-4 py-2\">\n <span className=\"text-[10px] font-bold uppercase tracking-wider text-muted-foreground\">\n Contributing factors\n </span>\n <span className=\"flex items-center gap-1 text-[10px] text-muted-foreground\">\n <Info className=\"h-3 w-3\" />\n {formulaLabel}\n </span>\n </div>\n\n {/* Factor rows */}\n <div className=\"divide-y divide-border/40\">\n {factors.map((factor) => (\n <PriorityFactorRow\n key={factor.key}\n factor={factor}\n initialFeedback={initialFactorFeedback?.[factor.key]}\n onFactorFeedback={onFactorFeedback}\n />\n ))}\n </div>\n </>\n )}\n\n {/* Feedback footer */}\n {onFeedbackSubmit && (\n <div className=\"border-t border-border\">\n <FeedbackFooter\n feedback={feedback}\n onFeedbackChange={setFeedback}\n onSubmit={onFeedbackSubmit}\n metaText={metaText}\n negativeChips={feedbackChips ?? DEFAULT_PRIORITY_FEEDBACK_CHIPS}\n positivePrompt=\"Thanks. Anything to keep about this score?\"\n className=\"px-4 py-3\"\n initialFeedback={initialPriorityFeedback}\n feedbackKey={footerFeedbackKey}\n />\n </div>\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n )\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/signal-priority-popover.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"radix-ui\"\nimport type { LucideIcon } from \"lucide-react\"\nimport {\n Radar,\n Wallet,\n Link2,\n MessageSquare,\n TrendingDown,\n ArrowUpRight,\n ArrowDownRight,\n Clock,\n Activity,\n Minus,\n ChevronDown,\n ChevronUp,\n Info,\n} from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\nimport { FeedbackFooter, InlineFeedbackControl } from \"./feedback-primitives\"\nimport type { FeedbackChipTree, FeedbackSubmitData, PersistedFeedbackData } from \"./feedback-primitives\"\nimport type { SignalScoreUrgencyLabel } from \"../prototype/prototype-config\"\nimport { SCORE_TONE_CLASSES, URGENCY_SCORE_CLASSES, getUrgencyLevel, getUrgencyRange } from \"./score-semantics\"\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A single contributing factor in the priority popover.\n */\nexport interface PriorityFactor {\n key: string\n label: string\n /** Lucide icon name (e.g. \"radar\", \"wallet\", \"link-2\", \"message-square\"). */\n icon: string\n /** Drives icon background tint. */\n tone: \"alert\" | \"warn\" | \"info\"\n /** Explicit semantic label - NOT inferred from score+weight. */\n direction: \"raises\" | \"lowers\" | \"neutral\"\n /** Optional display label for the direction text. Keeps semantic direction icon/color unchanged. */\n directionLabel?: string\n /** 0-100 */\n score: number\n /** Optional display label rendered instead of the numeric score cell. */\n displayValueLabel?: string\n /** Evidence text (e.g. \"$3.4M moved in 8h - current treasury balance $0.00\"). */\n rationale: string\n}\n\nexport interface SignalPriorityPopoverProps {\n score: number\n urgencyLabel?: SignalScoreUrgencyLabel\n /** Synthesis sentence displayed in the popover head. */\n urgencyExplanation?: string\n factors: PriorityFactor[]\n /** e.g. \"Updated 4m ago - model v3.2\" */\n metaText?: string\n /** Negative feedback issue tree. */\n feedbackChips?: FeedbackChipTree[]\n onFeedbackSubmit?: (data: FeedbackSubmitData) => void\n className?: string\n /** Persisted factor-level feedback (keyed by factor key). */\n initialFactorFeedback?: Record<string, { type: \"up\" | \"down\"; detail: string; ownershipLabel?: string }>\n /** Callback when user submits factor-level feedback. */\n onFactorFeedback?: (factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n /** Persisted priority-level feedback for the footer. */\n initialPriorityFeedback?: PersistedFeedbackData | null\n}\n\n// ---------------------------------------------------------------------------\n// Static class maps (required for Tailwind v4 source scanning)\n// ---------------------------------------------------------------------------\n\nconst URGENCY_TRIGGER_DEFAULT: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.trigger,\n High: URGENCY_SCORE_CLASSES.High.trigger,\n Medium: URGENCY_SCORE_CLASSES.Medium.trigger,\n Low: URGENCY_SCORE_CLASSES.Low.trigger,\n}\n\nconst URGENCY_TRIGGER_HOVER: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.hover,\n High: URGENCY_SCORE_CLASSES.High.hover,\n Medium: URGENCY_SCORE_CLASSES.Medium.hover,\n Low: URGENCY_SCORE_CLASSES.Low.hover,\n}\n\nconst URGENCY_TRIGGER_OPEN: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.open,\n High: URGENCY_SCORE_CLASSES.High.open,\n Medium: URGENCY_SCORE_CLASSES.Medium.open,\n Low: URGENCY_SCORE_CLASSES.Low.open,\n}\n\n/** Re-use shared tone classes from score-semantics. */\nconst TONE_ICON_CLASSES: Record<PriorityFactor[\"tone\"], string> = SCORE_TONE_CLASSES as Record<PriorityFactor[\"tone\"], string>\n\nconst DIRECTION_CLASSES: Record<PriorityFactor[\"direction\"], string> = {\n raises: \"text-red-600\",\n lowers: \"text-emerald-600\",\n neutral: \"text-muted-foreground\",\n}\n\n// ---------------------------------------------------------------------------\n// Icon lookup\n// ---------------------------------------------------------------------------\n\nconst FACTOR_ICONS: Record<string, LucideIcon> = {\n radar: Radar,\n wallet: Wallet,\n \"link-2\": Link2,\n \"message-square\": MessageSquare,\n \"trending-down\": TrendingDown,\n \"arrow-up-right\": ArrowUpRight,\n clock: Clock,\n activity: Activity,\n}\n\n// ---------------------------------------------------------------------------\n// Urgency dot color (static map)\n// ---------------------------------------------------------------------------\n\nconst URGENCY_DOT_CLASSES: Record<SignalScoreUrgencyLabel, string> = {\n Urgent: URGENCY_SCORE_CLASSES.Urgent.dot,\n High: URGENCY_SCORE_CLASSES.High.dot,\n Medium: URGENCY_SCORE_CLASSES.Medium.dot,\n Low: URGENCY_SCORE_CLASSES.Low.dot,\n}\n\n// ---------------------------------------------------------------------------\n// Default feedback chips\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_PRIORITY_FEEDBACK_CHIPS: FeedbackChipTree[] = [\n { label: \"Wrong factor weighting\" },\n { label: \"Missing context\" },\n { label: \"Inaccurate data\" },\n { label: \"Stale\" },\n { label: \"Other\" },\n]\n\n// ---------------------------------------------------------------------------\n// Direction icon component\n// ---------------------------------------------------------------------------\n\nfunction DirectionIcon({ direction }: { direction: PriorityFactor[\"direction\"] }) {\n const cls = \"h-2.5 w-2.5\"\n switch (direction) {\n case \"raises\":\n return <ArrowUpRight className={cls} />\n case \"lowers\":\n return <ArrowDownRight className={cls} />\n case \"neutral\":\n return <Minus className={cls} />\n }\n}\n\n// ---------------------------------------------------------------------------\n// PriorityFactorRow\n// ---------------------------------------------------------------------------\n\ninterface PriorityFactorRowProps {\n factor: PriorityFactor\n initialFeedback?: { type: \"up\" | \"down\"; detail: string; ownershipLabel?: string }\n onFactorFeedback?: (factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n}\n\nfunction PriorityFactorRow({ factor, initialFeedback, onFactorFeedback }: PriorityFactorRowProps) {\n const IconComponent = FACTOR_ICONS[factor.icon] ?? Activity\n const toneClasses = TONE_ICON_CLASSES[factor.tone]\n const directionClasses = DIRECTION_CLASSES[factor.direction]\n const directionLabel = factor.directionLabel ?? (\n factor.direction === \"raises\"\n ? \"Raises\"\n : factor.direction === \"lowers\"\n ? \"Lowers\"\n : \"Neutral\"\n )\n\n return (\n <div\n className=\"grid grid-cols-[20px_1fr_auto] gap-x-3 gap-y-1 px-4 py-3\"\n data-testid={`factor-row-${factor.key}`}\n >\n {/* Icon */}\n <div\n className={cn(\n \"flex h-5 w-5 items-center justify-center rounded\",\n toneClasses,\n )}\n >\n <IconComponent className=\"h-3 w-3\" />\n </div>\n\n {/* Label + direction tag */}\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[13px] font-semibold text-foreground\">\n {factor.label}\n </span>\n <span\n className={cn(\n \"inline-flex items-center gap-0.5 text-[10px] font-medium\",\n directionClasses,\n )}\n >\n <DirectionIcon direction={factor.direction} />\n {directionLabel}\n </span>\n </div>\n\n {/* Score number / display label */}\n <div className=\"flex items-center text-right\">\n {factor.displayValueLabel ? (\n <span className=\"text-xs font-semibold text-foreground\">{factor.displayValueLabel}</span>\n ) : (\n <>\n <span className=\"text-sm font-bold tabular-nums\">{factor.score}</span>\n <span className=\"text-xs font-normal text-muted-foreground\">/100</span>\n </>\n )}\n </div>\n\n {/* empty grid cell under icon column */}\n <div />\n\n {/* Rationale */}\n <p className=\"text-xs leading-relaxed text-muted-foreground\">\n {factor.rationale}\n </p>\n\n {/* empty grid cell under score column */}\n <div />\n\n {/* empty grid cell under icon column */}\n <div />\n\n {/* Score track */}\n <div className=\"mt-1 h-0.5 rounded-full bg-muted\">\n <div\n className=\"h-full rounded-full bg-foreground/20\"\n style={{ width: `${Math.min(100, Math.max(0, factor.score))}%` }}\n />\n </div>\n\n {/* empty grid cell under score column */}\n <div />\n\n {/* Factor-level feedback row (spans icon + content columns) */}\n {onFactorFeedback && (\n <>\n <div />\n <div className=\"col-span-2 mt-1\">\n <InlineFeedbackControl\n feedbackKey={factor.key}\n initialFeedback={initialFeedback}\n onFeedback={onFactorFeedback}\n testIdPrefix=\"factor\"\n />\n </div>\n </>\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SignalPriorityPopover\n// ---------------------------------------------------------------------------\n\nexport function SignalPriorityPopover({\n score,\n urgencyLabel: providedLabel,\n urgencyExplanation,\n factors,\n metaText,\n feedbackChips,\n onFeedbackSubmit,\n className,\n initialFactorFeedback,\n onFactorFeedback,\n initialPriorityFeedback,\n}: SignalPriorityPopoverProps) {\n const urgencyLabel = providedLabel ?? getUrgencyLevel(score)\n const scoreRange = getUrgencyRange(urgencyLabel)\n\n const [open, setOpen] = React.useState(false)\n const [feedback, setFeedback] = React.useState<\"positive\" | \"negative\" | null>(null)\n\n const triggerDefault = URGENCY_TRIGGER_DEFAULT[urgencyLabel]\n const triggerHover = URGENCY_TRIGGER_HOVER[urgencyLabel]\n const triggerOpen = URGENCY_TRIGGER_OPEN[urgencyLabel]\n\n // Derive a stable feedbackKey for the footer from score + urgencyLabel\n const footerFeedbackKey = `priority-${score}-${urgencyLabel}`\n\n return (\n <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n <PopoverPrimitive.Trigger asChild>\n <button\n type=\"button\"\n className={cn(\n \"inline-flex items-center gap-1 rounded-md border px-2.5 py-1 text-xs font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n triggerDefault,\n triggerHover,\n open && triggerOpen,\n open && \"outline-2 outline-foreground outline-offset-2\",\n className,\n )}\n data-testid=\"priority-popover-trigger\"\n >\n {urgencyLabel} Priority\n {open ? (\n <ChevronUp className=\"h-3 w-3\" />\n ) : (\n <ChevronDown className=\"h-3 w-3\" />\n )}\n </button>\n </PopoverPrimitive.Trigger>\n\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n side=\"bottom\"\n align=\"start\"\n sideOffset={8}\n onOpenAutoFocus={(e) => e.preventDefault()}\n className=\"z-50 w-[420px] rounded-lg border border-border bg-background shadow-lg p-0\"\n data-testid=\"priority-popover-content\"\n >\n {/* Head section */}\n <div className=\"p-4 pb-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <p className=\"text-sm font-semibold text-foreground\">\n Why this is {urgencyLabel.toLowerCase()} priority\n </p>\n <span className=\"text-2xl font-bold tabular-nums text-foreground\">\n {score}\n <span className=\"text-sm font-normal text-muted-foreground\">/100</span>\n </span>\n </div>\n\n {/* Band indicator */}\n <div className=\"mt-1 flex items-center gap-1.5 text-[11px] text-muted-foreground\">\n <span\n className={cn(\n \"inline-block h-2 w-2 rounded-full\",\n URGENCY_DOT_CLASSES[urgencyLabel],\n )}\n />\n {urgencyLabel} range: {scoreRange}\n </div>\n\n {/* Synthesis sentence */}\n {urgencyExplanation && (\n <p className=\"mt-2 text-xs leading-relaxed text-muted-foreground\">\n {urgencyExplanation}\n </p>\n )}\n </div>\n\n {/* Section label */}\n {factors.length > 0 && (\n <>\n <div className=\"flex items-center justify-between border-t border-border px-4 py-2\">\n <span className=\"text-[10px] font-bold uppercase tracking-wider text-muted-foreground\">\n Contributing factors\n </span>\n <span className=\"flex items-center gap-1 text-[10px] text-muted-foreground\">\n <Info className=\"h-3 w-3\" />\n Score = weighted sum\n </span>\n </div>\n\n {/* Factor rows */}\n <div className=\"divide-y divide-border/40\">\n {factors.map((factor) => (\n <PriorityFactorRow\n key={factor.key}\n factor={factor}\n initialFeedback={initialFactorFeedback?.[factor.key]}\n onFactorFeedback={onFactorFeedback}\n />\n ))}\n </div>\n </>\n )}\n\n {/* Feedback footer */}\n {onFeedbackSubmit && (\n <div className=\"border-t border-border\">\n <FeedbackFooter\n feedback={feedback}\n onFeedbackChange={setFeedback}\n onSubmit={onFeedbackSubmit}\n metaText={metaText}\n negativeChips={feedbackChips ?? DEFAULT_PRIORITY_FEEDBACK_CHIPS}\n positivePrompt=\"Thanks. Anything to keep about this score?\"\n className=\"px-4 py-3\"\n initialFeedback={initialPriorityFeedback}\n feedbackKey={footerFeedbackKey}\n />\n </div>\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n )\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import { Tabs as Tabs$1 } from 'radix-ui';
5
5
 
6
6
  declare function Tabs({ className, orientation, ...props }: React.ComponentProps<typeof Tabs$1.Root>): React.JSX.Element;
7
7
  declare const tabsListVariants: (props?: ({
8
- variant?: "line" | "default" | null | undefined;
8
+ variant?: "default" | "line" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  declare function TabsList({ className, variant, ...props }: React.ComponentProps<typeof Tabs$1.List> & VariantProps<typeof tabsListVariants>): React.JSX.Element;
11
11
  declare function TabsTrigger({ className, ...props }: React.ComponentProps<typeof Tabs$1.Trigger>): React.JSX.Element;
package/dist/index.d.ts CHANGED
@@ -27,7 +27,7 @@ export { CheckInsCard, RecentlyCompletedCard, TopTasksCard, UpcomingMeetingsCard
27
27
  export { DataRow, DataTable, DataTableProps } from './components/data-table.js';
28
28
  export { ConditionFieldDef, ConditionFieldOption, ConditionFilterValue, ConditionOperator, ConditionOptionObject, DEFAULT_OPERATORS, DataTableConditionFilter, DataTableConditionFilterProps, OPERATOR_LABELS, generateConditionId, getOperators, shouldShowOptionSearch } from './components/data-table-condition-filter.js';
29
29
  export { DataTableDisplay, DataTableDisplayColumn } from './components/data-table-display.js';
30
- export { DataTableFilter, DataTableFilterCategory, DataTableFilterProps, FilterOption } from './components/data-table-filter.js';
30
+ export { DataTableFilter, DataTableFilterCategory, DataTableFilterProps, DataTableOptionFilterCategory, DataTableTextFilterCategory, FilterOption } from './components/data-table-filter.js';
31
31
  export { DataTableQuickViewValue, DataTableQuickViews } from './components/data-table-quick-views.js';
32
32
  export { DataTableToolbar } from './components/data-table-toolbar.js';
33
33
  export { Citation, DetailViewHeader, DetailViewSummary, DetailViewThread, SourceDef, SourceList, ThreadMessage } from './components/detail-view.js';
@@ -38,7 +38,7 @@ export { EmptyState, EmptyStateProps } from './components/empty-state.js';
38
38
  export { ActivityItem, ConnectedApps, EntityActivityItem, EntityDetails, EntityMetadataField, EntityMetadataGrid, EntityPanel, EntityPanelBrandIcons, EntityPanelHeader, EntityPanelTabs, EntitySection, PanelMode, PotentialContacts, RecentActivity, SystemActivity, useEntityPanel } from './components/entity-panel.js';
39
39
  export { RelatedRecordActionCard, RelatedRecordActionCardKind, RelatedRecordActionCardProps, RelatedRecordActionIcon } from './components/related-record-action-card.js';
40
40
  export { FeedbackActions, FeedbackActionsProps, FeedbackChipGroup, FeedbackChipGroupProps, FeedbackChipTree, FeedbackFooter, FeedbackFooterProps, FeedbackInput, FeedbackInputProps, FeedbackSubmitData, InlineFeedbackControl, InlineFeedbackControlProps, PersistedFeedbackData } from './components/feedback-primitives.js';
41
- 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 SignalPriorityScoreDisplay, m as SignalScoreData, n as SignalScoreExplanationBucket, o as SignalScoreExplanationSignal, p as SignalScoreUrgencyLabel, T as TimelineSystemEventsConfig, W as WorkQueueViewConfig } from './signal-priority-popover-DTedstRL.js';
41
+ 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-QJngMAj7.js';
42
42
  export { FilterChip, FilterChipProps } from './components/filter-chip.js';
43
43
  export { InboxGroupHeader, InboxRow, InboxRowProps } from './components/inbox-row.js';
44
44
  export { AssigneeFilter, InboxFilterCategory, InboxToolbar, InboxToolbarProps } from './components/inbox-toolbar.js';
@@ -77,7 +77,7 @@ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScro
77
77
  export { Separator } from './components/separator.js';
78
78
  export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from './components/sheet.js';
79
79
  export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar } from './components/sidebar.js';
80
- export { ApprovalState, OpportunityPreview, SignalApproval, SignalApprovalActions, SignalApprovalContextValue, SignalApprovalGate, SignalApprovalLabels, SignalApprovalRoot, SignalApprovalRootProps, useSignalApproval } from './components/signal-feedback-inline.js';
80
+ export { ApprovalState, OpportunityDraft, OpportunityPreview, SignalApproval, SignalApprovalActions, SignalApprovalContextValue, SignalApprovalGate, SignalApprovalLabels, SignalApprovalRoot, SignalApprovalRootProps, useSignalApproval } from './components/signal-feedback-inline.js';
81
81
  export { SimpleDataTable, SimpleDataTableProps } from './components/simple-data-table.js';
82
82
  export { Skeleton } from './components/skeleton.js';
83
83
  export { StatusBadge, StatusBadgeProps, StatusType } from './components/status-badge.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @handled-ai/design-system\n * UI components and utilities (shadcn-style, New York)\n */\n\n// Utilities\nexport { cn } from \"./lib/utils\"\nexport { BRAND_ICONS, BRAND_GRAPHICS } from \"./lib/icons\"\nexport { displayName, getInitials, shortName, type ProfileLike } from \"./lib/user-display\"\n\n// Hooks\nexport { useIsMobile } from \"./hooks/use-mobile\"\n\n// Components (light — no recharts/nivo/three transitive deps)\nexport * from \"./components/activity-detail\"\nexport * from \"./components/activity-log\"\nexport * from \"./components/agent-popover\"\nexport * from \"./components/agent-widget\"\nexport * from \"./components/avatar\"\nexport * from \"./components/badge\"\nexport * from \"./components/button\"\nexport * from \"./components/card\"\nexport * from \"./components/case-panel-email-composer\"\nexport * from \"./components/email-composer-row\"\nexport * from \"./components/email-preview-card\"\nexport * from \"./components/email-recipient-field\"\nexport * from \"./components/email-send-bar\"\nexport * from \"./components/case-panel-activity-timeline\"\nexport * from \"./components/case-panel-detail\"\nexport * from \"./components/case-panel-why\"\nexport { CollapsibleSection, type CollapsibleSectionProps } from \"./components/collapsible-section\"\nexport * from \"./components/compliance-badge\"\nexport * from \"./components/contact-chip\"\nexport * from \"./components/contact-list\"\nexport * from \"./components/contextual-quick-action-launcher\"\nexport * from \"./components/dashboard-cards\"\nexport * from \"./components/data-table\"\nexport * from \"./components/data-table-condition-filter\"\nexport * from \"./components/data-table-display\"\nexport * from \"./components/data-table-filter\"\nexport * from \"./components/data-table-quick-views\"\nexport * from \"./components/data-table-toolbar\"\nexport * from \"./components/detail-view\"\nexport * from \"./components/detail-drawer\"\nexport * from \"./components/dialog\"\nexport * from \"./components/dropdown-menu\"\nexport * from \"./components/empty-state\"\nexport * from \"./components/entity-panel\"\nexport * from \"./components/related-record-action-card\"\nexport { FeedbackFooter, FeedbackChipGroup, FeedbackInput, FeedbackActions, InlineFeedbackControl } from \"./components/feedback-primitives\"\nexport type { FeedbackFooterProps, FeedbackChipTree, FeedbackChipGroupProps, FeedbackInputProps, FeedbackActionsProps, FeedbackSubmitData, PersistedFeedbackData, InlineFeedbackControlProps } from \"./components/feedback-primitives\"\nexport { SignalPriorityPopover } from \"./components/signal-priority-popover\"\nexport type { SignalPriorityPopoverProps, SignalPriorityScoreDisplay, PriorityFactor } from \"./components/signal-priority-popover\"\nexport * from \"./components/filter-chip\"\nexport * from \"./components/inbox-row\"\nexport * from \"./components/inbox-toolbar\"\nexport * from \"./components/inline-banner\"\nexport * from \"./components/input\"\nexport * from \"./components/insights-filter-bar\"\nexport * from \"./components/days-open-cell\"\nexport * from \"./components/linked-entity-cell\"\nexport * from \"./components/item-list\"\nexport * from \"./components/item-list-display\"\nexport * from \"./components/item-list-filter\"\nexport * from \"./components/item-list-toolbar\"\nexport * from \"./components/kbd-hint\"\nexport * from \"./components/label\"\nexport * from \"./components/message\"\nexport * from \"./components/metric-card\"\nexport * from \"./components/performance-metrics-table\"\nexport * from \"./components/pill\"\nexport * from \"./components/preview-list\"\nexport * from \"./components/progress\"\nexport * from \"./components/quick-action-chat-area\"\nexport * from \"./components/quick-segment\"\nexport {\n QuickActionModal,\n type QuickActionPriority,\n type QuickActionTaskDraft,\n type QuickActionTemplate,\n} from \"./components/quick-action-modal\"\nexport * from \"./components/quick-action-sidebar-nav\"\nexport * from \"./components/recommended-actions-section\"\nexport * from \"./components/report-card\"\nexport * from \"./components/rich-text-toolbar\"\nexport * from \"./components/score-analysis-modal\"\nexport * from \"./components/score-breakdown\"\nexport * from \"./components/score-feedback\"\nexport * from \"./components/score-semantics\"\nexport * from \"./components/score-why-chips\"\nexport * from \"./components/score-ring\"\nexport * from \"./components/scroll-area\"\nexport * from \"./components/select\"\nexport * from \"./components/separator\"\nexport * from \"./components/sheet\"\nexport * from \"./components/sidebar\"\nexport * from \"./components/signal-feedback-inline\"\nexport * from \"./components/simple-data-table\"\nexport * from \"./components/skeleton\"\nexport * from \"./components/status-badge\"\nexport * from \"./components/step-timeline\"\nexport * from \"./components/sticky-action-bar\"\nexport * from \"./components/styled-bar-list\"\nexport { DraftFeedbackInline } from \"./components/draft-feedback-inline\"\nexport type { DraftFeedbackInlineProps } from \"./components/draft-feedback-inline\"\nexport { AccountContactsPopover, BrandIcon } from \"./components/account-contacts-popover\"\nexport type { AccountContactsPopoverProps } from \"./components/account-contacts-popover\"\nexport * from \"./components/suggested-actions\"\nexport * from \"./components/switch\"\nexport * from \"./components/table\"\nexport * from \"./components/tabs\"\nexport * from \"./components/textarea\"\nexport * from \"./components/timeline-activity\"\nexport * from \"./components/tooltip\"\nexport * from \"./components/user-display\"\nexport * from \"./components/variable-autocomplete\"\nexport * from \"./components/view-mode-toggle\"\nexport * from \"./components/virtualized-data-table\"\nexport type { ColumnSizingState } from \"@tanstack/react-table\"\n\n// Charts (re-exported for backward compatibility with root imports)\nexport * from \"./charts/index\"\n\n// Prototype template system (re-exported for backward compatibility)\nexport * from \"./prototype/prototype-config\"\nexport * from \"./prototype/prototype-shell\"\nexport * from \"./prototype/prototype-inbox-view\"\nexport * from \"./prototype/prototype-insights-view\"\nexport * from \"./prototype/prototype-accounts-view\"\nexport * from \"./prototype/prototype-admin-view\"\nexport * from \"./prototype/prototype-work-queue-view\"\n"],"mappings":"AAMA,SAAS,UAAU;AACnB,SAAS,aAAa,sBAAsB;AAC5C,SAAS,aAAa,aAAa,iBAAmC;AAGtE,SAAS,mBAAmB;AAG5B,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,0BAAwD;AACjE,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,gBAAgB,mBAAmB,eAAe,iBAAiB,6BAA6B;AAEzG,SAAS,6BAA6B;AAEtC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd;AAAA,EACE;AAAA,OAIK;AACP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,2BAA2B;AAEpC,SAAS,wBAAwB,iBAAiB;AAElD,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAId,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @handled-ai/design-system\n * UI components and utilities (shadcn-style, New York)\n */\n\n// Utilities\nexport { cn } from \"./lib/utils\"\nexport { BRAND_ICONS, BRAND_GRAPHICS } from \"./lib/icons\"\nexport { displayName, getInitials, shortName, type ProfileLike } from \"./lib/user-display\"\n\n// Hooks\nexport { useIsMobile } from \"./hooks/use-mobile\"\n\n// Components (light — no recharts/nivo/three transitive deps)\nexport * from \"./components/activity-detail\"\nexport * from \"./components/activity-log\"\nexport * from \"./components/agent-popover\"\nexport * from \"./components/agent-widget\"\nexport * from \"./components/avatar\"\nexport * from \"./components/badge\"\nexport * from \"./components/button\"\nexport * from \"./components/card\"\nexport * from \"./components/case-panel-email-composer\"\nexport * from \"./components/email-composer-row\"\nexport * from \"./components/email-preview-card\"\nexport * from \"./components/email-recipient-field\"\nexport * from \"./components/email-send-bar\"\nexport * from \"./components/case-panel-activity-timeline\"\nexport * from \"./components/case-panel-detail\"\nexport * from \"./components/case-panel-why\"\nexport { CollapsibleSection, type CollapsibleSectionProps } from \"./components/collapsible-section\"\nexport * from \"./components/compliance-badge\"\nexport * from \"./components/contact-chip\"\nexport * from \"./components/contact-list\"\nexport * from \"./components/contextual-quick-action-launcher\"\nexport * from \"./components/dashboard-cards\"\nexport * from \"./components/data-table\"\nexport * from \"./components/data-table-condition-filter\"\nexport * from \"./components/data-table-display\"\nexport * from \"./components/data-table-filter\"\nexport * from \"./components/data-table-quick-views\"\nexport * from \"./components/data-table-toolbar\"\nexport * from \"./components/detail-view\"\nexport * from \"./components/detail-drawer\"\nexport * from \"./components/dialog\"\nexport * from \"./components/dropdown-menu\"\nexport * from \"./components/empty-state\"\nexport * from \"./components/entity-panel\"\nexport * from \"./components/related-record-action-card\"\nexport { FeedbackFooter, FeedbackChipGroup, FeedbackInput, FeedbackActions, InlineFeedbackControl } from \"./components/feedback-primitives\"\nexport type { FeedbackFooterProps, FeedbackChipTree, FeedbackChipGroupProps, FeedbackInputProps, FeedbackActionsProps, FeedbackSubmitData, PersistedFeedbackData, InlineFeedbackControlProps } from \"./components/feedback-primitives\"\nexport { SignalPriorityPopover } from \"./components/signal-priority-popover\"\nexport type { SignalPriorityPopoverProps, PriorityFactor } from \"./components/signal-priority-popover\"\nexport * from \"./components/filter-chip\"\nexport * from \"./components/inbox-row\"\nexport * from \"./components/inbox-toolbar\"\nexport * from \"./components/inline-banner\"\nexport * from \"./components/input\"\nexport * from \"./components/insights-filter-bar\"\nexport * from \"./components/days-open-cell\"\nexport * from \"./components/linked-entity-cell\"\nexport * from \"./components/item-list\"\nexport * from \"./components/item-list-display\"\nexport * from \"./components/item-list-filter\"\nexport * from \"./components/item-list-toolbar\"\nexport * from \"./components/kbd-hint\"\nexport * from \"./components/label\"\nexport * from \"./components/message\"\nexport * from \"./components/metric-card\"\nexport * from \"./components/performance-metrics-table\"\nexport * from \"./components/pill\"\nexport * from \"./components/preview-list\"\nexport * from \"./components/progress\"\nexport * from \"./components/quick-action-chat-area\"\nexport * from \"./components/quick-segment\"\nexport {\n QuickActionModal,\n type QuickActionPriority,\n type QuickActionTaskDraft,\n type QuickActionTemplate,\n} from \"./components/quick-action-modal\"\nexport * from \"./components/quick-action-sidebar-nav\"\nexport * from \"./components/recommended-actions-section\"\nexport * from \"./components/report-card\"\nexport * from \"./components/rich-text-toolbar\"\nexport * from \"./components/score-analysis-modal\"\nexport * from \"./components/score-breakdown\"\nexport * from \"./components/score-feedback\"\nexport * from \"./components/score-semantics\"\nexport * from \"./components/score-why-chips\"\nexport * from \"./components/score-ring\"\nexport * from \"./components/scroll-area\"\nexport * from \"./components/select\"\nexport * from \"./components/separator\"\nexport * from \"./components/sheet\"\nexport * from \"./components/sidebar\"\nexport * from \"./components/signal-feedback-inline\"\nexport * from \"./components/simple-data-table\"\nexport * from \"./components/skeleton\"\nexport * from \"./components/status-badge\"\nexport * from \"./components/step-timeline\"\nexport * from \"./components/sticky-action-bar\"\nexport * from \"./components/styled-bar-list\"\nexport { DraftFeedbackInline } from \"./components/draft-feedback-inline\"\nexport type { DraftFeedbackInlineProps } from \"./components/draft-feedback-inline\"\nexport { AccountContactsPopover, BrandIcon } from \"./components/account-contacts-popover\"\nexport type { AccountContactsPopoverProps } from \"./components/account-contacts-popover\"\nexport * from \"./components/suggested-actions\"\nexport * from \"./components/switch\"\nexport * from \"./components/table\"\nexport * from \"./components/tabs\"\nexport * from \"./components/textarea\"\nexport * from \"./components/timeline-activity\"\nexport * from \"./components/tooltip\"\nexport * from \"./components/user-display\"\nexport * from \"./components/variable-autocomplete\"\nexport * from \"./components/view-mode-toggle\"\nexport * from \"./components/virtualized-data-table\"\nexport type { ColumnSizingState } from \"@tanstack/react-table\"\n\n// Charts (re-exported for backward compatibility with root imports)\nexport * from \"./charts/index\"\n\n// Prototype template system (re-exported for backward compatibility)\nexport * from \"./prototype/prototype-config\"\nexport * from \"./prototype/prototype-shell\"\nexport * from \"./prototype/prototype-inbox-view\"\nexport * from \"./prototype/prototype-insights-view\"\nexport * from \"./prototype/prototype-accounts-view\"\nexport * from \"./prototype/prototype-admin-view\"\nexport * from \"./prototype/prototype-work-queue-view\"\n"],"mappings":"AAMA,SAAS,UAAU;AACnB,SAAS,aAAa,sBAAsB;AAC5C,SAAS,aAAa,aAAa,iBAAmC;AAGtE,SAAS,mBAAmB;AAG5B,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,0BAAwD;AACjE,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,gBAAgB,mBAAmB,eAAe,iBAAiB,6BAA6B;AAEzG,SAAS,6BAA6B;AAEtC,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd;AAAA,EACE;AAAA,OAIK;AACP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAAS,2BAA2B;AAEpC,SAAS,wBAAwB,iBAAiB;AAElD,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAId,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -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, m as SignalScoreData, n as SignalScoreExplanationBucket, o as SignalScoreExplanationSignal, p as SignalScoreUrgencyLabel, T as TimelineSystemEventsConfig, W as WorkQueueViewConfig } from '../signal-priority-popover-DTedstRL.js';
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-QJngMAj7.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-DTedstRL.js';
2
+ import { a as AccountsViewConfig } from '../signal-priority-popover-QJngMAj7.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-DTedstRL.js';
2
+ import { c as AdminViewConfig } from '../signal-priority-popover-QJngMAj7.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, m as SignalScoreData, n as SignalScoreExplanationBucket, o as SignalScoreExplanationSignal, p as SignalScoreUrgencyLabel, T as TimelineSystemEventsConfig, W as WorkQueueViewConfig } from '../signal-priority-popover-DTedstRL.js';
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-QJngMAj7.js';
15
15
  import '../components/feedback-primitives.js';
16
16
  import '../components/quick-action-modal.js';
17
17
  import '../components/score-semantics.js';
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
- import { ApprovalState, OpportunityPreview } from '../components/signal-feedback-inline.js';
2
+ import { OpportunityDraft, ApprovalState, OpportunityPreview } from '../components/signal-feedback-inline.js';
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, m as SignalScoreData, f as InboxViewConfig, B as BriefStyleVariant, T as TimelineSystemEventsConfig } from '../signal-priority-popover-DTedstRL.js';
6
+ import { Q as QueueItem, I as InboxDetailSections, l as SignalScoreData, f as InboxViewConfig, B as BriefStyleVariant, T as TimelineSystemEventsConfig } from '../signal-priority-popover-QJngMAj7.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';
@@ -41,7 +41,7 @@ interface DetailViewProps {
41
41
  onSuggestedActionFeedback?: (actionId: number | string, feedback: string, actionTitle?: string) => void;
42
42
  /** @deprecated The compact score UX no longer renders score-level thumbs by default. */
43
43
  onScoreFeedback?: (type: "up" | "down", pills: string[], detail: string) => void;
44
- onSignalApprove?: (item: QueueItem) => void | Promise<boolean>;
44
+ onSignalApprove?: (item: QueueItem, draft?: OpportunityDraft) => void | Promise<boolean>;
45
45
  getSignalApprovalState?: (item: QueueItem) => ApprovalState | undefined;
46
46
  signalLabels?: InboxViewConfig["signalLabels"];
47
47
  hideApproveButton?: boolean;