@handled-ai/design-system 0.20.33 → 0.21.0

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.
@@ -41,6 +41,7 @@ import {
41
41
  useReactTable
42
42
  } from "@tanstack/react-table";
43
43
  import { cn } from "../lib/utils.js";
44
+ import { getEntityColor } from "../lib/entity-color.js";
44
45
  import { Badge } from "./badge.js";
45
46
  import {
46
47
  DataTableQuickViews
@@ -398,21 +399,6 @@ const DEFAULT_COLUMN_VISIBILITY = {
398
399
  owner: false,
399
400
  opportunityCount: false
400
401
  };
401
- function getEntityColor(name) {
402
- const colors = [
403
- "bg-muted text-muted-foreground",
404
- "bg-gray-100 text-gray-600",
405
- "bg-zinc-100 text-zinc-600",
406
- "bg-blue-50 text-blue-600",
407
- "bg-indigo-50 text-indigo-600",
408
- "bg-violet-50 text-violet-600"
409
- ];
410
- let hash = 0;
411
- for (let i = 0; i < name.length; i += 1) {
412
- hash = name.charCodeAt(i) + ((hash << 5) - hash);
413
- }
414
- return colors[Math.abs(hash) % colors.length];
415
- }
416
402
  function getIndustryColor(industry) {
417
403
  var _a;
418
404
  const colors = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n Briefcase,\n Calendar,\n DollarSign,\n History,\n Link as LinkIcon,\n SearchX,\n TrendingUp,\n User,\n Users,\n} from \"lucide-react\"\nimport {\n createColumnHelper,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n type SortingState,\n type VisibilityState,\n} from \"@tanstack/react-table\"\n\nimport { cn } from \"../lib/utils\"\nimport { Badge } from \"./badge\"\nimport {\n DataTableQuickViews,\n type DataTableQuickViewValue,\n} from \"./data-table-quick-views\"\nimport { DataTableToolbar } from \"./data-table-toolbar\"\nimport { type DataTableFilterCategory } from \"./data-table-filter\"\nimport { ScoreAnalysisModal } from \"./score-analysis-modal\"\nimport type { ScoreFactor } from \"./score-breakdown\"\nimport { Citation, type SourceDef } from \"./detail-view\"\n\nexport type DataRow = {\n id: string\n name: string\n industry: string[]\n accountRisks: string[]\n riskScore: number\n expansionScore: number\n growthIndicators: string[]\n lastInteraction: string\n lastInteractionDays: number\n createdAt: string\n revenue: string\n headcount: string\n lastFunding: string\n owner: string\n ownerEmail?: string\n opportunityCount: number\n productAdoptionScore: number\n sourceSystem?: string\n sourceRef?: string\n}\n\nconst QUICK_VIEWS = [\n \"Balance Flight Detected\",\n \"Not Touched in 30+ Days\",\n \"Open Opportunity, Stalled\",\n \"Growth Signal Detected\",\n \"Low Product Adoption\",\n]\n\nconst MORE_QUICK_VIEWS = [\n \"Missed meeting this week\",\n \"High churn risk score\",\n \"Key contact departed\",\n \"Recent large inflow\",\n \"Dormant (no payments)\",\n \"Support tickets elevated\",\n]\n\nconst FILTER_CATEGORIES: DataTableFilterCategory[] = [\n {\n id: \"industry\",\n label: \"Industry\",\n icon: Briefcase,\n options: [\n \"Software\",\n \"E-commerce\",\n \"Financial Technology\",\n \"Workforce Management\",\n \"Artificial Intelligence\",\n \"Health Technology\",\n \"Design\",\n ],\n },\n {\n id: \"lastInteraction\",\n label: \"Last interaction\",\n icon: History,\n options: [\"1 day ago\", \"3 days ago\", \"1 week ago\", \"1 month ago\", \"2 months ago\"],\n },\n {\n id: \"createdAt\",\n label: \"Created at\",\n icon: Calendar,\n options: [\"Last 30 days\", \"Last 90 days\", \"This year\", \"Last year\"],\n },\n {\n id: \"revenue\",\n label: \"Revenue\",\n icon: DollarSign,\n options: [\"$0 - $1M\", \"$1M - $10M\", \"$10M - $50M\", \"$50M+\"],\n },\n {\n id: \"headcount\",\n label: \"Headcount\",\n icon: Users,\n options: [\"11-50\", \"51-200\", \"201-500\", \"500-1000\", \"1000+\"],\n },\n {\n id: \"lastFunding\",\n label: \"Last funding\",\n icon: TrendingUp,\n options: [\"Seed\", \"Series A\", \"Series B\", \"Series C+\", \"Undisclosed\"],\n },\n {\n id: \"owner\",\n label: \"Owner\",\n icon: User,\n options: [\"Sam Lee\", \"Alex Morgan\", \"Jordan Case\", \"Taylor Reed\"],\n },\n {\n id: \"opportunityCount\",\n label: \"Opportunity count\",\n icon: LinkIcon,\n options: [\"0\", \"1\", \"2\", \"3+\"],\n },\n]\n\nconst ROWS: DataRow[] = [\n {\n id: \"rappi\",\n name: \"Rappi\",\n industry: [\"E-commerce\", \"Food Delivery\", \"Financial Technology\"],\n accountRisks: [\"Flight Risk\", \"Low Engagement\"],\n riskScore: 65,\n expansionScore: 45,\n growthIndicators: [\"Job Openings\", \"Recent Funding\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 7,\n createdAt: \"This year\",\n revenue: \"$10M - $50M\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 2,\n productAdoptionScore: 62,\n },\n {\n id: \"codeshot\",\n name: \"Codeshot\",\n industry: [\"Software\"],\n accountRisks: [\"Flight Risk\", \"Low Engagement\"],\n riskScore: 85,\n expansionScore: 20,\n growthIndicators: [],\n lastInteraction: \"2 months ago\",\n lastInteractionDays: 64,\n createdAt: \"Last year\",\n revenue: \"$1M - $10M\",\n headcount: \"201-500\",\n lastFunding: \"Series A\",\n owner: \"Alex Morgan\",\n opportunityCount: 1,\n productAdoptionScore: 31,\n },\n {\n id: \"lovi\",\n name: \"Lovi\",\n industry: [\"Artificial Intelligence\", \"Health Technology\"],\n accountRisks: [\"Low Engagement\", \"Key Contact Departure\"],\n riskScore: 55,\n expansionScore: 75,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 month ago\",\n lastInteractionDays: 36,\n createdAt: \"This year\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Jordan Case\",\n opportunityCount: 3,\n productAdoptionScore: 38,\n },\n {\n id: \"anthropic\",\n name: \"Anthropic\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 25,\n expansionScore: 68,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"3 days ago\",\n lastInteractionDays: 3,\n createdAt: \"Last 90 days\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 2,\n productAdoptionScore: 86,\n },\n {\n id: \"buildbear\",\n name: \"BuildBear\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 35,\n expansionScore: 92,\n growthIndicators: [\"Recent Funding\", \"Revenue Growth\"],\n lastInteraction: \"1 day ago\",\n lastInteractionDays: 1,\n createdAt: \"Last 30 days\",\n revenue: \"$1M - $10M\",\n headcount: \"51-200\",\n lastFunding: \"Seed\",\n owner: \"Taylor Reed\",\n opportunityCount: 2,\n productAdoptionScore: 91,\n },\n {\n id: \"content-mobbin\",\n name: \"Content-mobbin\",\n industry: [\"Workforce Management\"],\n accountRisks: [],\n riskScore: 28,\n expansionScore: 85,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 9,\n createdAt: \"Last 30 days\",\n revenue: \"$0 - $1M\",\n headcount: \"11-50\",\n lastFunding: \"Seed\",\n owner: \"Taylor Reed\",\n opportunityCount: 2,\n productAdoptionScore: 77,\n },\n {\n id: \"figma\",\n name: \"Figma\",\n industry: [\"Design\", \"Software\"],\n accountRisks: [],\n riskScore: 15,\n expansionScore: 88,\n growthIndicators: [\"Headcount Expansion\", \"Job Openings\"],\n lastInteraction: \"3 days ago\",\n lastInteractionDays: 3,\n createdAt: \"This year\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Alex Morgan\",\n opportunityCount: 1,\n productAdoptionScore: 94,\n },\n {\n id: \"loom\",\n name: \"Loom\",\n industry: [\"Software\"],\n accountRisks: [\"Key Contact Departure\"],\n riskScore: 35,\n expansionScore: 68,\n growthIndicators: [\"Headcount Expansion\", \"Job Openings\"],\n lastInteraction: \"1 month ago\",\n lastInteractionDays: 33,\n createdAt: \"Last year\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Jordan Case\",\n opportunityCount: 1,\n productAdoptionScore: 58,\n },\n {\n id: \"miro\",\n name: \"Miro\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 32,\n expansionScore: 55,\n growthIndicators: [],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 8,\n createdAt: \"This year\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 0,\n productAdoptionScore: 64,\n },\n {\n id: \"webflow\",\n name: \"Webflow\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 25,\n expansionScore: 72,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 10,\n createdAt: \"Last 90 days\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Alex Morgan\",\n opportunityCount: 2,\n productAdoptionScore: 71,\n },\n]\n\ntype ScoreAnalysisData = {\n title: string\n description: string\n whyNow: string\n evidence: React.ReactNode[]\n factors: ScoreFactor[]\n}\n\nconst RISK_SOURCES: SourceDef[] = [\n { id: 1, summary: \"Weekly active users declined 12% over the past 30 days with no recovery trend.\", meta: \"Product telemetry \\u00b7 2h ago\" },\n { id: 2, summary: \"Critical support ticket #4821 has been unresolved for over 48 hours.\", meta: \"Zendesk \\u00b7 6h ago\" },\n { id: 3, summary: \"Competitor mentions detected in recent Slack conversations from the finance team.\", meta: \"Slack signal \\u00b7 1d ago\" },\n]\n\nconst EXPANSION_SOURCES: SourceDef[] = [\n { id: 1, summary: \"Treasury feature utilization is above the 85th percentile compared to peer accounts.\", meta: \"Product telemetry \\u00b7 3h ago\" },\n { id: 2, summary: \"Multiple feature requests submitted for advanced reporting and API access.\", meta: \"Zendesk \\u00b7 1d ago\" },\n { id: 3, summary: \"Finance department headcount grew from 8 to 14 in the last quarter.\", meta: \"LinkedIn signal \\u00b7 2d ago\" },\n]\n\nconst SCORE_ANALYSIS: Record<string, (row: DataRow) => ScoreAnalysisData> = {\n Risk: (row) => ({\n title: \"Risk Score Analysis\",\n description:\n \"Estimated probability of churn within the next 90 days based on activity and support signals\",\n whyNow:\n row.riskScore >= 60\n ? \"Critical risk factors detected requiring immediate intervention to prevent churn.\"\n : \"Account health is stable, but monitoring recent support interactions is recommended.\",\n evidence: [\n <>Recent decline in <span className=\"font-medium text-foreground\">weekly active users (-12%)</span> with no recovery trend<Citation number={1} source={RISK_SOURCES[0]} /></>,\n <>Unresolved <span className=\"font-medium text-foreground\">critical support ticket</span> open for over 48 hours<Citation number={2} source={RISK_SOURCES[1]} /></>,\n <>Competitor presence detected in recent conversations from finance team<Citation number={3} source={RISK_SOURCES[2]} /></>,\n ],\n factors: [\n { key: \"engagement\", label: \"Engagement drop\", score: Math.min(row.riskScore + 10, 100), why: \"Weekly active users declined 12% over past 30 days\" },\n { key: \"support\", label: \"Support load\", score: Math.min(row.riskScore + 5, 100), why: \"Unresolved critical ticket open for >48h\" },\n { key: \"competitive\", label: \"Competitive risk\", score: null, risk: row.riskScore >= 60 ? \"High\" as const : \"Low\" as const, why: \"Competitor mentions detected in recent conversations\" },\n { key: \"usage\", label: \"Product usage\", score: Math.max(100 - row.riskScore, 10), why: \"Core feature adoption remains consistent\" },\n ],\n }),\n Expansion: (row) => ({\n title: \"Expansion Score Analysis\",\n description:\n \"Likelihood of successful upsell and cross-sell opportunities based on usage and engagement\",\n whyNow:\n row.expansionScore >= 70\n ? \"Usage patterns and growth signals indicate readiness for additional product adoption.\"\n : \"Moderate expansion potential; consider targeted engagement to increase adoption.\",\n evidence: [\n <>Treasury utilization above <span className=\"font-medium text-foreground\">85th percentile</span> vs peer accounts<Citation number={1} source={EXPANSION_SOURCES[0]} /></>,\n <>Frequent <span className=\"font-medium text-foreground\">feature requests</span> for advanced reporting and API access<Citation number={2} source={EXPANSION_SOURCES[1]} /></>,\n <>Recent <span className=\"font-medium text-foreground\">team expansion</span> in finance department (8 &rarr; 14)<Citation number={3} source={EXPANSION_SOURCES[2]} /></>,\n ],\n factors: [\n { key: \"usage-depth\", label: \"Usage depth\", score: Math.min(row.expansionScore + 8, 100), why: \"Active usage across 4+ core product features\" },\n { key: \"growth\", label: \"Growth signals\", score: row.expansionScore, why: row.growthIndicators.length > 0 ? row.growthIndicators.join(\", \") + \" detected\" : \"No active growth signals\" },\n { key: \"fit\", label: \"Product fit\", score: Math.min(row.expansionScore + 12, 100), why: \"Company profile matches high-expansion ICP\" },\n { key: \"timing\", label: \"Timing\", score: null, risk: row.expansionScore >= 70 ? \"Low\" as const : \"Medium\" as const, why: \"Within typical evaluation window for upsell\" },\n ],\n }),\n}\n\nconst QUICK_VIEW_FILTERS: Record<string, (row: DataRow) => boolean> = {\n \"Balance Flight Detected\": (row) => row.riskScore >= 60,\n \"Not Touched in 30+ Days\": (row) => row.lastInteractionDays >= 30,\n \"Open Opportunity, Stalled\": (row) =>\n row.opportunityCount > 0 && row.lastInteractionDays >= 21,\n \"Growth Signal Detected\": (row) => row.expansionScore >= 70,\n \"Low Product Adoption\": (row) => row.productAdoptionScore <= 40,\n \"Missed meeting this week\": (row) => row.lastInteractionDays >= 6,\n \"High churn risk score\": (row) => row.riskScore >= 75,\n \"Key contact departed\": (row) =>\n row.accountRisks.some((risk) => risk.toLowerCase().includes(\"contact\")),\n \"Recent large inflow\": (row) => row.expansionScore >= 85,\n \"Dormant (no payments)\": (row) => row.opportunityCount === 0,\n \"Support tickets elevated\": (row) =>\n row.accountRisks.some((risk) => risk.toLowerCase().includes(\"engagement\")),\n}\n\nconst columnHelper = createColumnHelper<DataRow>()\n\nconst DEFAULT_COLUMN_VISIBILITY: VisibilityState = {\n industry: false,\n lastInteraction: false,\n revenue: false,\n headcount: false,\n lastFunding: false,\n owner: false,\n opportunityCount: false,\n}\n\nfunction getEntityColor(name: string) {\n const colors = [\n \"bg-muted text-muted-foreground\",\n \"bg-gray-100 text-gray-600\",\n \"bg-zinc-100 text-zinc-600\",\n \"bg-blue-50 text-blue-600\",\n \"bg-indigo-50 text-indigo-600\",\n \"bg-violet-50 text-violet-600\",\n ]\n\n let hash = 0\n for (let i = 0; i < name.length; i += 1) {\n hash = name.charCodeAt(i) + ((hash << 5) - hash)\n }\n return colors[Math.abs(hash) % colors.length]\n}\n\nfunction getIndustryColor(industry: string) {\n const colors: Record<string, string> = {\n \"E-commerce\": \"bg-emerald-50 text-emerald-700 border-emerald-100\",\n \"Food Delivery\": \"bg-blue-50 text-blue-700 border-blue-100\",\n \"Financial Technology\": \"bg-amber-50 text-amber-700 border-amber-100\",\n \"Workforce Management\": \"bg-violet-50 text-violet-700 border-violet-100\",\n \"Artificial Intelligence\": \"bg-rose-50 text-rose-700 border-rose-100\",\n \"Health Technology\": \"bg-orange-50 text-orange-700 border-orange-100\",\n Software: \"bg-muted text-muted-foreground border-border\",\n }\n\n return colors[industry] ?? \"bg-muted text-muted-foreground border-border\"\n}\n\nfunction toggleFilterValue(\n current: Record<string, string[]>,\n categoryId: string,\n option: string\n) {\n const currentValues = current[categoryId] ?? []\n const isActive = currentValues.includes(option)\n const nextValues = isActive\n ? currentValues.filter((value) => value !== option)\n : [...currentValues, option]\n\n return {\n ...current,\n [categoryId]: nextValues,\n }\n}\n\nfunction isRowMatchingCategoryFilter(\n row: DataRow,\n categoryId: string,\n options: string[]\n) {\n if (options.length === 0) {\n return true\n }\n\n switch (categoryId) {\n case \"industry\":\n return options.some((option) => row.industry.includes(option))\n case \"lastInteraction\":\n return options.includes(row.lastInteraction)\n case \"createdAt\":\n return options.includes(row.createdAt)\n case \"revenue\":\n return options.includes(row.revenue)\n case \"headcount\":\n return options.includes(row.headcount)\n case \"lastFunding\":\n return options.includes(row.lastFunding)\n case \"owner\":\n return options.includes(row.ownerEmail ?? row.owner)\n case \"opportunityCount\":\n return options.some((option) => {\n if (option === \"3+\") {\n return row.opportunityCount >= 3\n }\n return row.opportunityCount === Number(option)\n })\n default:\n return true\n }\n}\n\nexport interface DataTableProps {\n onRowClick?: (row: DataRow) => void\n rows?: DataRow[]\n filterCategories?: DataTableFilterCategory[]\n quickViews?: string[]\n moreQuickViews?: string[]\n quickViewFilters?: Record<string, (row: DataRow) => boolean>\n iconMap?: { salesforce?: string }\n entityUrlBuilder?: (row: DataRow) => string\n onScoreFactorFeedback?: (account: string, scoreType: string, factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n onScoreApproveFeedback?: (account: string, scoreType: string, reasons: string[], detail: string) => void\n onScoreDismissFeedback?: (account: string, scoreType: string, reasons: string[], detail: string) => void\n}\n\nexport function DataTable({\n onRowClick,\n rows: rowsProp,\n filterCategories: filterCategoriesProp,\n quickViews: quickViewsProp,\n moreQuickViews: moreQuickViewsProp,\n quickViewFilters: quickViewFiltersProp,\n iconMap,\n entityUrlBuilder,\n onScoreFactorFeedback,\n onScoreApproveFeedback,\n onScoreDismissFeedback,\n}: DataTableProps = {}) {\n const resolvedRows = rowsProp ?? ROWS\n const resolvedFilterCategories = filterCategoriesProp ?? FILTER_CATEGORIES\n const resolvedQuickViews = quickViewsProp ?? QUICK_VIEWS\n const resolvedMoreQuickViews = moreQuickViewsProp ?? MORE_QUICK_VIEWS\n const resolvedQuickViewFilters = quickViewFiltersProp ?? QUICK_VIEW_FILTERS\n\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(\n DEFAULT_COLUMN_VISIBILITY\n )\n const [selectedFilters, setSelectedFilters] = React.useState<Record<string, string[]>>(\n {}\n )\n const [activeQuickView, setActiveQuickView] =\n React.useState<DataTableQuickViewValue>(null)\n const [scoreModal, setScoreModal] = React.useState<{\n row: DataRow\n type: \"Risk\" | \"Expansion\"\n } | null>(null)\n\n React.useEffect(() => {\n if (!activeQuickView) {\n return\n }\n\n setColumnVisibility((previous) => {\n const next = { ...previous }\n if (activeQuickView.includes(\"Touched\")) {\n next.lastInteraction = true\n }\n if (activeQuickView.includes(\"Growth\")) {\n next.expansionScore = true\n }\n if (activeQuickView.includes(\"risk\") || activeQuickView.includes(\"Risk\")) {\n next.riskScore = true\n }\n return next\n })\n }, [activeQuickView])\n\n const filteredRows = React.useMemo(() => {\n return resolvedRows.filter((row) => {\n const quickViewMatches = activeQuickView\n ? (resolvedQuickViewFilters[activeQuickView]?.(row) ?? true)\n : true\n\n if (!quickViewMatches) {\n return false\n }\n\n return Object.entries(selectedFilters).every(([categoryId, options]) =>\n isRowMatchingCategoryFilter(row, categoryId, options)\n )\n })\n }, [activeQuickView, selectedFilters, resolvedRows, resolvedQuickViewFilters])\n\n const columns = React.useMemo(\n () => [\n columnHelper.accessor(\"name\", {\n header: \"Entity\",\n cell: (info) => {\n const row = info.row.original\n const sfUrl = entityUrlBuilder?.(row)\n return (\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n \"flex h-6 w-6 shrink-0 items-center justify-center rounded text-[10px] font-bold\",\n getEntityColor(row.name)\n )}\n >\n {row.name.slice(0, 1)}\n </div>\n <span className=\"text-sm font-medium text-foreground\">\n {row.name}\n </span>\n {iconMap?.salesforce && (\n <a\n href={sfUrl ?? \"#\"}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"shrink-0 text-muted-foreground hover:text-foreground transition-colors\"\n >\n <img src={iconMap.salesforce} alt=\"Salesforce\" className=\"w-4 h-4 object-contain\" />\n </a>\n )}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"accountRisks\", {\n header: \"Risk Signals\",\n cell: (info) => {\n const risks = info.getValue()\n if (!risks.length) {\n return <span className=\"text-xs text-muted-foreground\">None</span>\n }\n\n return (\n <div className=\"flex items-center gap-1.5\">\n {risks.slice(0, 2).map((risk) => (\n <Badge\n key={risk}\n variant=\"outline\"\n className=\"rounded-md border-red-200 bg-red-50 px-2 py-0.5 text-xs font-normal text-red-700\"\n >\n {risk}\n </Badge>\n ))}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"riskScore\", {\n id: \"riskScore\",\n header: \"Risk Score\",\n cell: (info) => (\n <div\n className=\"inline-flex cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation()\n setScoreModal({ row: info.row.original, type: \"Risk\" })\n }}\n >\n <Badge\n variant=\"outline\"\n className={cn(\n \"px-2 py-0.5 text-xs font-medium hover:underline decoration-dotted underline-offset-2\",\n info.getValue() >= 60\n ? \"border-red-200 bg-red-50 text-red-700\"\n : \"border-border bg-muted/50 text-foreground\"\n )}\n >\n {info.getValue()}%\n </Badge>\n </div>\n ),\n }),\n columnHelper.accessor(\"expansionScore\", {\n id: \"expansionScore\",\n header: \"Expansion Score\",\n cell: (info) => (\n <div\n className=\"inline-flex cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation()\n setScoreModal({ row: info.row.original, type: \"Expansion\" })\n }}\n >\n <Badge\n variant=\"outline\"\n className={cn(\n \"px-2 py-0.5 text-xs font-medium hover:underline decoration-dotted underline-offset-2\",\n info.getValue() >= 70\n ? \"border-blue-200 bg-blue-50 text-blue-700\"\n : \"border-border bg-muted/50 text-foreground\"\n )}\n >\n {info.getValue()}%\n </Badge>\n </div>\n ),\n }),\n columnHelper.accessor(\"growthIndicators\", {\n header: \"Growth Signals\",\n cell: (info) => {\n const indicators = info.getValue()\n if (!indicators.length) {\n return <span className=\"text-xs text-muted-foreground\">None</span>\n }\n return (\n <div className=\"flex items-center gap-1.5\">\n {indicators.slice(0, 2).map((indicator) => (\n <Badge\n key={indicator}\n variant=\"outline\"\n className=\"rounded-md border-blue-200 bg-blue-50 px-2 py-0.5 text-xs font-normal text-blue-700\"\n >\n {indicator}\n </Badge>\n ))}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"industry\", {\n header: \"Industry\",\n cell: (info) => (\n <div className=\"flex items-center gap-1.5\">\n {info.getValue().slice(0, 2).map((industry) => (\n <Badge\n key={industry}\n variant=\"outline\"\n className={cn(\n \"rounded-md px-2 py-0.5 text-xs font-normal\",\n getIndustryColor(industry)\n )}\n >\n {industry}\n </Badge>\n ))}\n </div>\n ),\n }),\n columnHelper.accessor(\"lastInteraction\", {\n header: \"Last interaction\",\n cell: (info) => <span className=\"text-sm\">{info.getValue()}</span>,\n }),\n columnHelper.accessor(\"revenue\", {\n header: \"Revenue\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"headcount\", {\n header: \"Headcount\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"lastFunding\", {\n header: \"Last funding\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"owner\", {\n header: \"Owner\",\n cell: (info) => <span className=\"text-sm\">{info.getValue()}</span>,\n }),\n columnHelper.accessor(\"opportunityCount\", {\n header: \"Opportunity count\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n ],\n [iconMap, entityUrlBuilder]\n )\n\n const table = useReactTable({\n data: filteredRows,\n columns,\n state: {\n sorting,\n columnVisibility,\n },\n onSortingChange: setSorting,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n })\n\n const displayColumns = table.getAllLeafColumns().map((column) => {\n const header = column.columnDef.header\n const label = typeof header === \"string\" ? header : column.id\n\n return {\n id: column.id,\n label,\n visible: column.getIsVisible(),\n canHide: column.getCanHide(),\n }\n })\n\n const toggleCategoryFilter = (categoryId: string, option: string) => {\n setSelectedFilters((previous) => toggleFilterValue(previous, categoryId, option))\n }\n\n return (\n <div className=\"relative flex h-full min-h-[560px] flex-col bg-background\">\n <DataTableToolbar\n categories={resolvedFilterCategories}\n selectedFilters={selectedFilters}\n onToggleFilter={toggleCategoryFilter}\n sorting={sorting}\n onSortingChange={setSorting}\n displayColumns={displayColumns}\n onToggleColumn={(columnId) => table.getColumn(columnId)?.toggleVisibility()}\n onResetDisplay={() => setColumnVisibility(DEFAULT_COLUMN_VISIBILITY)}\n />\n\n <DataTableQuickViews\n quickViews={resolvedQuickViews}\n moreViews={resolvedMoreQuickViews}\n activeView={activeQuickView}\n onViewChange={setActiveQuickView}\n />\n\n <div className=\"relative min-h-0 flex-1 overflow-auto border-t border-border\">\n <table className=\"w-max min-w-full border-collapse text-sm\">\n <thead className=\"sticky top-0 z-10 bg-background\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id} className=\"border-b border-border\">\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"h-10 border-r border-border px-4 text-left text-xs font-medium text-muted-foreground/80 last:border-r-0\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.length > 0 ? (\n <>\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n onClick={() => onRowClick?.(row.original)}\n className={cn(\n \"group border-b border-border/50 transition-colors hover:bg-muted/30\",\n onRowClick && \"cursor-pointer\",\n )}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n className=\"border-r border-border/40 px-4 py-2.5 align-middle last:border-r-0\"\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </tr>\n ))}\n <tr>\n <td\n className=\"px-4 py-2 text-xs text-muted-foreground\"\n colSpan={columns.length}\n >\n {table.getRowModel().rows.length} rows\n </td>\n </tr>\n </>\n ) : (\n <tr>\n <td colSpan={columns.length} className=\"h-52 px-4 text-center\">\n <div className=\"flex flex-col items-center gap-1 text-muted-foreground\">\n <SearchX className=\"h-7 w-7 opacity-40\" />\n <p className=\"text-sm font-medium\">No rows found</p>\n <p className=\"text-xs\">Try adjusting your filters or quick views</p>\n </div>\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n\n {scoreModal && (() => {\n const data = SCORE_ANALYSIS[scoreModal.type](scoreModal.row)\n return (\n <ScoreAnalysisModal\n open\n onOpenChange={(open) => { if (!open) setScoreModal(null) }}\n title={data.title}\n description={data.description}\n score={scoreModal.type === \"Risk\" ? scoreModal.row.riskScore : scoreModal.row.expansionScore}\n scoreIntent={scoreModal.type === \"Risk\" ? \"risk\" : \"positive\"}\n whyNow={data.whyNow}\n evidence={data.evidence}\n factors={data.factors}\n onFactorFeedback={onScoreFactorFeedback\n ? (key, type, detail) => onScoreFactorFeedback(scoreModal.row.name, scoreModal.type, key, type, detail)\n : (key, type, detail) => console.log(\"Factor feedback:\", { account: scoreModal.row.name, factor: key, type, detail })\n }\n companyName={scoreModal.row.name}\n opportunityUrl={`https://acme.lightning.force.com/lightning/r/Opportunity/006${scoreModal.row.id}/view`}\n onApprove={() => console.log(\"Approved signal — creating opportunity:\", { account: scoreModal.row.name, type: scoreModal.type })}\n onApproveFeedback={onScoreApproveFeedback\n ? (reasons, detail) => onScoreApproveFeedback(scoreModal.row.name, scoreModal.type, reasons, detail)\n : (reasons, detail) => console.log(\"Approval feedback:\", { account: scoreModal.row.name, reasons, detail })\n }\n onDismiss={onScoreDismissFeedback\n ? (reasons, detail) => onScoreDismissFeedback(scoreModal.row.name, scoreModal.type, reasons, detail)\n : (reasons, detail) => console.log(\"Dismissed signal:\", { account: scoreModal.row.name, reasons, detail })\n }\n />\n )\n })()}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/data-table.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n Briefcase,\n Calendar,\n DollarSign,\n History,\n Link as LinkIcon,\n SearchX,\n TrendingUp,\n User,\n Users,\n} from \"lucide-react\"\nimport {\n createColumnHelper,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n type SortingState,\n type VisibilityState,\n} from \"@tanstack/react-table\"\n\nimport { cn } from \"../lib/utils\"\nimport { getEntityColor } from \"../lib/entity-color\"\nimport { Badge } from \"./badge\"\nimport {\n DataTableQuickViews,\n type DataTableQuickViewValue,\n} from \"./data-table-quick-views\"\nimport { DataTableToolbar } from \"./data-table-toolbar\"\nimport { type DataTableFilterCategory } from \"./data-table-filter\"\nimport { ScoreAnalysisModal } from \"./score-analysis-modal\"\nimport type { ScoreFactor } from \"./score-breakdown\"\nimport { Citation, type SourceDef } from \"./detail-view\"\n\nexport type DataRow = {\n id: string\n name: string\n industry: string[]\n accountRisks: string[]\n riskScore: number\n expansionScore: number\n growthIndicators: string[]\n lastInteraction: string\n lastInteractionDays: number\n createdAt: string\n revenue: string\n headcount: string\n lastFunding: string\n owner: string\n ownerEmail?: string\n opportunityCount: number\n productAdoptionScore: number\n sourceSystem?: string\n sourceRef?: string\n}\n\nconst QUICK_VIEWS = [\n \"Balance Flight Detected\",\n \"Not Touched in 30+ Days\",\n \"Open Opportunity, Stalled\",\n \"Growth Signal Detected\",\n \"Low Product Adoption\",\n]\n\nconst MORE_QUICK_VIEWS = [\n \"Missed meeting this week\",\n \"High churn risk score\",\n \"Key contact departed\",\n \"Recent large inflow\",\n \"Dormant (no payments)\",\n \"Support tickets elevated\",\n]\n\nconst FILTER_CATEGORIES: DataTableFilterCategory[] = [\n {\n id: \"industry\",\n label: \"Industry\",\n icon: Briefcase,\n options: [\n \"Software\",\n \"E-commerce\",\n \"Financial Technology\",\n \"Workforce Management\",\n \"Artificial Intelligence\",\n \"Health Technology\",\n \"Design\",\n ],\n },\n {\n id: \"lastInteraction\",\n label: \"Last interaction\",\n icon: History,\n options: [\"1 day ago\", \"3 days ago\", \"1 week ago\", \"1 month ago\", \"2 months ago\"],\n },\n {\n id: \"createdAt\",\n label: \"Created at\",\n icon: Calendar,\n options: [\"Last 30 days\", \"Last 90 days\", \"This year\", \"Last year\"],\n },\n {\n id: \"revenue\",\n label: \"Revenue\",\n icon: DollarSign,\n options: [\"$0 - $1M\", \"$1M - $10M\", \"$10M - $50M\", \"$50M+\"],\n },\n {\n id: \"headcount\",\n label: \"Headcount\",\n icon: Users,\n options: [\"11-50\", \"51-200\", \"201-500\", \"500-1000\", \"1000+\"],\n },\n {\n id: \"lastFunding\",\n label: \"Last funding\",\n icon: TrendingUp,\n options: [\"Seed\", \"Series A\", \"Series B\", \"Series C+\", \"Undisclosed\"],\n },\n {\n id: \"owner\",\n label: \"Owner\",\n icon: User,\n options: [\"Sam Lee\", \"Alex Morgan\", \"Jordan Case\", \"Taylor Reed\"],\n },\n {\n id: \"opportunityCount\",\n label: \"Opportunity count\",\n icon: LinkIcon,\n options: [\"0\", \"1\", \"2\", \"3+\"],\n },\n]\n\nconst ROWS: DataRow[] = [\n {\n id: \"rappi\",\n name: \"Rappi\",\n industry: [\"E-commerce\", \"Food Delivery\", \"Financial Technology\"],\n accountRisks: [\"Flight Risk\", \"Low Engagement\"],\n riskScore: 65,\n expansionScore: 45,\n growthIndicators: [\"Job Openings\", \"Recent Funding\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 7,\n createdAt: \"This year\",\n revenue: \"$10M - $50M\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 2,\n productAdoptionScore: 62,\n },\n {\n id: \"codeshot\",\n name: \"Codeshot\",\n industry: [\"Software\"],\n accountRisks: [\"Flight Risk\", \"Low Engagement\"],\n riskScore: 85,\n expansionScore: 20,\n growthIndicators: [],\n lastInteraction: \"2 months ago\",\n lastInteractionDays: 64,\n createdAt: \"Last year\",\n revenue: \"$1M - $10M\",\n headcount: \"201-500\",\n lastFunding: \"Series A\",\n owner: \"Alex Morgan\",\n opportunityCount: 1,\n productAdoptionScore: 31,\n },\n {\n id: \"lovi\",\n name: \"Lovi\",\n industry: [\"Artificial Intelligence\", \"Health Technology\"],\n accountRisks: [\"Low Engagement\", \"Key Contact Departure\"],\n riskScore: 55,\n expansionScore: 75,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 month ago\",\n lastInteractionDays: 36,\n createdAt: \"This year\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Jordan Case\",\n opportunityCount: 3,\n productAdoptionScore: 38,\n },\n {\n id: \"anthropic\",\n name: \"Anthropic\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 25,\n expansionScore: 68,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"3 days ago\",\n lastInteractionDays: 3,\n createdAt: \"Last 90 days\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 2,\n productAdoptionScore: 86,\n },\n {\n id: \"buildbear\",\n name: \"BuildBear\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 35,\n expansionScore: 92,\n growthIndicators: [\"Recent Funding\", \"Revenue Growth\"],\n lastInteraction: \"1 day ago\",\n lastInteractionDays: 1,\n createdAt: \"Last 30 days\",\n revenue: \"$1M - $10M\",\n headcount: \"51-200\",\n lastFunding: \"Seed\",\n owner: \"Taylor Reed\",\n opportunityCount: 2,\n productAdoptionScore: 91,\n },\n {\n id: \"content-mobbin\",\n name: \"Content-mobbin\",\n industry: [\"Workforce Management\"],\n accountRisks: [],\n riskScore: 28,\n expansionScore: 85,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 9,\n createdAt: \"Last 30 days\",\n revenue: \"$0 - $1M\",\n headcount: \"11-50\",\n lastFunding: \"Seed\",\n owner: \"Taylor Reed\",\n opportunityCount: 2,\n productAdoptionScore: 77,\n },\n {\n id: \"figma\",\n name: \"Figma\",\n industry: [\"Design\", \"Software\"],\n accountRisks: [],\n riskScore: 15,\n expansionScore: 88,\n growthIndicators: [\"Headcount Expansion\", \"Job Openings\"],\n lastInteraction: \"3 days ago\",\n lastInteractionDays: 3,\n createdAt: \"This year\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Alex Morgan\",\n opportunityCount: 1,\n productAdoptionScore: 94,\n },\n {\n id: \"loom\",\n name: \"Loom\",\n industry: [\"Software\"],\n accountRisks: [\"Key Contact Departure\"],\n riskScore: 35,\n expansionScore: 68,\n growthIndicators: [\"Headcount Expansion\", \"Job Openings\"],\n lastInteraction: \"1 month ago\",\n lastInteractionDays: 33,\n createdAt: \"Last year\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Jordan Case\",\n opportunityCount: 1,\n productAdoptionScore: 58,\n },\n {\n id: \"miro\",\n name: \"Miro\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 32,\n expansionScore: 55,\n growthIndicators: [],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 8,\n createdAt: \"This year\",\n revenue: \"$50M+\",\n headcount: \"1000+\",\n lastFunding: \"Series C+\",\n owner: \"Sam Lee\",\n opportunityCount: 0,\n productAdoptionScore: 64,\n },\n {\n id: \"webflow\",\n name: \"Webflow\",\n industry: [\"Software\"],\n accountRisks: [],\n riskScore: 25,\n expansionScore: 72,\n growthIndicators: [\"Recent Funding\", \"Headcount Expansion\"],\n lastInteraction: \"1 week ago\",\n lastInteractionDays: 10,\n createdAt: \"Last 90 days\",\n revenue: \"$10M - $50M\",\n headcount: \"500-1000\",\n lastFunding: \"Series B\",\n owner: \"Alex Morgan\",\n opportunityCount: 2,\n productAdoptionScore: 71,\n },\n]\n\ntype ScoreAnalysisData = {\n title: string\n description: string\n whyNow: string\n evidence: React.ReactNode[]\n factors: ScoreFactor[]\n}\n\nconst RISK_SOURCES: SourceDef[] = [\n { id: 1, summary: \"Weekly active users declined 12% over the past 30 days with no recovery trend.\", meta: \"Product telemetry \\u00b7 2h ago\" },\n { id: 2, summary: \"Critical support ticket #4821 has been unresolved for over 48 hours.\", meta: \"Zendesk \\u00b7 6h ago\" },\n { id: 3, summary: \"Competitor mentions detected in recent Slack conversations from the finance team.\", meta: \"Slack signal \\u00b7 1d ago\" },\n]\n\nconst EXPANSION_SOURCES: SourceDef[] = [\n { id: 1, summary: \"Treasury feature utilization is above the 85th percentile compared to peer accounts.\", meta: \"Product telemetry \\u00b7 3h ago\" },\n { id: 2, summary: \"Multiple feature requests submitted for advanced reporting and API access.\", meta: \"Zendesk \\u00b7 1d ago\" },\n { id: 3, summary: \"Finance department headcount grew from 8 to 14 in the last quarter.\", meta: \"LinkedIn signal \\u00b7 2d ago\" },\n]\n\nconst SCORE_ANALYSIS: Record<string, (row: DataRow) => ScoreAnalysisData> = {\n Risk: (row) => ({\n title: \"Risk Score Analysis\",\n description:\n \"Estimated probability of churn within the next 90 days based on activity and support signals\",\n whyNow:\n row.riskScore >= 60\n ? \"Critical risk factors detected requiring immediate intervention to prevent churn.\"\n : \"Account health is stable, but monitoring recent support interactions is recommended.\",\n evidence: [\n <>Recent decline in <span className=\"font-medium text-foreground\">weekly active users (-12%)</span> with no recovery trend<Citation number={1} source={RISK_SOURCES[0]} /></>,\n <>Unresolved <span className=\"font-medium text-foreground\">critical support ticket</span> open for over 48 hours<Citation number={2} source={RISK_SOURCES[1]} /></>,\n <>Competitor presence detected in recent conversations from finance team<Citation number={3} source={RISK_SOURCES[2]} /></>,\n ],\n factors: [\n { key: \"engagement\", label: \"Engagement drop\", score: Math.min(row.riskScore + 10, 100), why: \"Weekly active users declined 12% over past 30 days\" },\n { key: \"support\", label: \"Support load\", score: Math.min(row.riskScore + 5, 100), why: \"Unresolved critical ticket open for >48h\" },\n { key: \"competitive\", label: \"Competitive risk\", score: null, risk: row.riskScore >= 60 ? \"High\" as const : \"Low\" as const, why: \"Competitor mentions detected in recent conversations\" },\n { key: \"usage\", label: \"Product usage\", score: Math.max(100 - row.riskScore, 10), why: \"Core feature adoption remains consistent\" },\n ],\n }),\n Expansion: (row) => ({\n title: \"Expansion Score Analysis\",\n description:\n \"Likelihood of successful upsell and cross-sell opportunities based on usage and engagement\",\n whyNow:\n row.expansionScore >= 70\n ? \"Usage patterns and growth signals indicate readiness for additional product adoption.\"\n : \"Moderate expansion potential; consider targeted engagement to increase adoption.\",\n evidence: [\n <>Treasury utilization above <span className=\"font-medium text-foreground\">85th percentile</span> vs peer accounts<Citation number={1} source={EXPANSION_SOURCES[0]} /></>,\n <>Frequent <span className=\"font-medium text-foreground\">feature requests</span> for advanced reporting and API access<Citation number={2} source={EXPANSION_SOURCES[1]} /></>,\n <>Recent <span className=\"font-medium text-foreground\">team expansion</span> in finance department (8 &rarr; 14)<Citation number={3} source={EXPANSION_SOURCES[2]} /></>,\n ],\n factors: [\n { key: \"usage-depth\", label: \"Usage depth\", score: Math.min(row.expansionScore + 8, 100), why: \"Active usage across 4+ core product features\" },\n { key: \"growth\", label: \"Growth signals\", score: row.expansionScore, why: row.growthIndicators.length > 0 ? row.growthIndicators.join(\", \") + \" detected\" : \"No active growth signals\" },\n { key: \"fit\", label: \"Product fit\", score: Math.min(row.expansionScore + 12, 100), why: \"Company profile matches high-expansion ICP\" },\n { key: \"timing\", label: \"Timing\", score: null, risk: row.expansionScore >= 70 ? \"Low\" as const : \"Medium\" as const, why: \"Within typical evaluation window for upsell\" },\n ],\n }),\n}\n\nconst QUICK_VIEW_FILTERS: Record<string, (row: DataRow) => boolean> = {\n \"Balance Flight Detected\": (row) => row.riskScore >= 60,\n \"Not Touched in 30+ Days\": (row) => row.lastInteractionDays >= 30,\n \"Open Opportunity, Stalled\": (row) =>\n row.opportunityCount > 0 && row.lastInteractionDays >= 21,\n \"Growth Signal Detected\": (row) => row.expansionScore >= 70,\n \"Low Product Adoption\": (row) => row.productAdoptionScore <= 40,\n \"Missed meeting this week\": (row) => row.lastInteractionDays >= 6,\n \"High churn risk score\": (row) => row.riskScore >= 75,\n \"Key contact departed\": (row) =>\n row.accountRisks.some((risk) => risk.toLowerCase().includes(\"contact\")),\n \"Recent large inflow\": (row) => row.expansionScore >= 85,\n \"Dormant (no payments)\": (row) => row.opportunityCount === 0,\n \"Support tickets elevated\": (row) =>\n row.accountRisks.some((risk) => risk.toLowerCase().includes(\"engagement\")),\n}\n\nconst columnHelper = createColumnHelper<DataRow>()\n\nconst DEFAULT_COLUMN_VISIBILITY: VisibilityState = {\n industry: false,\n lastInteraction: false,\n revenue: false,\n headcount: false,\n lastFunding: false,\n owner: false,\n opportunityCount: false,\n}\n\nfunction getIndustryColor(industry: string) {\n const colors: Record<string, string> = {\n \"E-commerce\": \"bg-emerald-50 text-emerald-700 border-emerald-100\",\n \"Food Delivery\": \"bg-blue-50 text-blue-700 border-blue-100\",\n \"Financial Technology\": \"bg-amber-50 text-amber-700 border-amber-100\",\n \"Workforce Management\": \"bg-violet-50 text-violet-700 border-violet-100\",\n \"Artificial Intelligence\": \"bg-rose-50 text-rose-700 border-rose-100\",\n \"Health Technology\": \"bg-orange-50 text-orange-700 border-orange-100\",\n Software: \"bg-muted text-muted-foreground border-border\",\n }\n\n return colors[industry] ?? \"bg-muted text-muted-foreground border-border\"\n}\n\nfunction toggleFilterValue(\n current: Record<string, string[]>,\n categoryId: string,\n option: string\n) {\n const currentValues = current[categoryId] ?? []\n const isActive = currentValues.includes(option)\n const nextValues = isActive\n ? currentValues.filter((value) => value !== option)\n : [...currentValues, option]\n\n return {\n ...current,\n [categoryId]: nextValues,\n }\n}\n\nfunction isRowMatchingCategoryFilter(\n row: DataRow,\n categoryId: string,\n options: string[]\n) {\n if (options.length === 0) {\n return true\n }\n\n switch (categoryId) {\n case \"industry\":\n return options.some((option) => row.industry.includes(option))\n case \"lastInteraction\":\n return options.includes(row.lastInteraction)\n case \"createdAt\":\n return options.includes(row.createdAt)\n case \"revenue\":\n return options.includes(row.revenue)\n case \"headcount\":\n return options.includes(row.headcount)\n case \"lastFunding\":\n return options.includes(row.lastFunding)\n case \"owner\":\n return options.includes(row.ownerEmail ?? row.owner)\n case \"opportunityCount\":\n return options.some((option) => {\n if (option === \"3+\") {\n return row.opportunityCount >= 3\n }\n return row.opportunityCount === Number(option)\n })\n default:\n return true\n }\n}\n\nexport interface DataTableProps {\n onRowClick?: (row: DataRow) => void\n rows?: DataRow[]\n filterCategories?: DataTableFilterCategory[]\n quickViews?: string[]\n moreQuickViews?: string[]\n quickViewFilters?: Record<string, (row: DataRow) => boolean>\n iconMap?: { salesforce?: string }\n entityUrlBuilder?: (row: DataRow) => string\n onScoreFactorFeedback?: (account: string, scoreType: string, factorKey: string, type: \"up\" | \"down\" | null, detail?: string) => void\n onScoreApproveFeedback?: (account: string, scoreType: string, reasons: string[], detail: string) => void\n onScoreDismissFeedback?: (account: string, scoreType: string, reasons: string[], detail: string) => void\n}\n\nexport function DataTable({\n onRowClick,\n rows: rowsProp,\n filterCategories: filterCategoriesProp,\n quickViews: quickViewsProp,\n moreQuickViews: moreQuickViewsProp,\n quickViewFilters: quickViewFiltersProp,\n iconMap,\n entityUrlBuilder,\n onScoreFactorFeedback,\n onScoreApproveFeedback,\n onScoreDismissFeedback,\n}: DataTableProps = {}) {\n const resolvedRows = rowsProp ?? ROWS\n const resolvedFilterCategories = filterCategoriesProp ?? FILTER_CATEGORIES\n const resolvedQuickViews = quickViewsProp ?? QUICK_VIEWS\n const resolvedMoreQuickViews = moreQuickViewsProp ?? MORE_QUICK_VIEWS\n const resolvedQuickViewFilters = quickViewFiltersProp ?? QUICK_VIEW_FILTERS\n\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(\n DEFAULT_COLUMN_VISIBILITY\n )\n const [selectedFilters, setSelectedFilters] = React.useState<Record<string, string[]>>(\n {}\n )\n const [activeQuickView, setActiveQuickView] =\n React.useState<DataTableQuickViewValue>(null)\n const [scoreModal, setScoreModal] = React.useState<{\n row: DataRow\n type: \"Risk\" | \"Expansion\"\n } | null>(null)\n\n React.useEffect(() => {\n if (!activeQuickView) {\n return\n }\n\n setColumnVisibility((previous) => {\n const next = { ...previous }\n if (activeQuickView.includes(\"Touched\")) {\n next.lastInteraction = true\n }\n if (activeQuickView.includes(\"Growth\")) {\n next.expansionScore = true\n }\n if (activeQuickView.includes(\"risk\") || activeQuickView.includes(\"Risk\")) {\n next.riskScore = true\n }\n return next\n })\n }, [activeQuickView])\n\n const filteredRows = React.useMemo(() => {\n return resolvedRows.filter((row) => {\n const quickViewMatches = activeQuickView\n ? (resolvedQuickViewFilters[activeQuickView]?.(row) ?? true)\n : true\n\n if (!quickViewMatches) {\n return false\n }\n\n return Object.entries(selectedFilters).every(([categoryId, options]) =>\n isRowMatchingCategoryFilter(row, categoryId, options)\n )\n })\n }, [activeQuickView, selectedFilters, resolvedRows, resolvedQuickViewFilters])\n\n const columns = React.useMemo(\n () => [\n columnHelper.accessor(\"name\", {\n header: \"Entity\",\n cell: (info) => {\n const row = info.row.original\n const sfUrl = entityUrlBuilder?.(row)\n return (\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n \"flex h-6 w-6 shrink-0 items-center justify-center rounded text-[10px] font-bold\",\n getEntityColor(row.name)\n )}\n >\n {row.name.slice(0, 1)}\n </div>\n <span className=\"text-sm font-medium text-foreground\">\n {row.name}\n </span>\n {iconMap?.salesforce && (\n <a\n href={sfUrl ?? \"#\"}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"shrink-0 text-muted-foreground hover:text-foreground transition-colors\"\n >\n <img src={iconMap.salesforce} alt=\"Salesforce\" className=\"w-4 h-4 object-contain\" />\n </a>\n )}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"accountRisks\", {\n header: \"Risk Signals\",\n cell: (info) => {\n const risks = info.getValue()\n if (!risks.length) {\n return <span className=\"text-xs text-muted-foreground\">None</span>\n }\n\n return (\n <div className=\"flex items-center gap-1.5\">\n {risks.slice(0, 2).map((risk) => (\n <Badge\n key={risk}\n variant=\"outline\"\n className=\"rounded-md border-red-200 bg-red-50 px-2 py-0.5 text-xs font-normal text-red-700\"\n >\n {risk}\n </Badge>\n ))}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"riskScore\", {\n id: \"riskScore\",\n header: \"Risk Score\",\n cell: (info) => (\n <div\n className=\"inline-flex cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation()\n setScoreModal({ row: info.row.original, type: \"Risk\" })\n }}\n >\n <Badge\n variant=\"outline\"\n className={cn(\n \"px-2 py-0.5 text-xs font-medium hover:underline decoration-dotted underline-offset-2\",\n info.getValue() >= 60\n ? \"border-red-200 bg-red-50 text-red-700\"\n : \"border-border bg-muted/50 text-foreground\"\n )}\n >\n {info.getValue()}%\n </Badge>\n </div>\n ),\n }),\n columnHelper.accessor(\"expansionScore\", {\n id: \"expansionScore\",\n header: \"Expansion Score\",\n cell: (info) => (\n <div\n className=\"inline-flex cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation()\n setScoreModal({ row: info.row.original, type: \"Expansion\" })\n }}\n >\n <Badge\n variant=\"outline\"\n className={cn(\n \"px-2 py-0.5 text-xs font-medium hover:underline decoration-dotted underline-offset-2\",\n info.getValue() >= 70\n ? \"border-blue-200 bg-blue-50 text-blue-700\"\n : \"border-border bg-muted/50 text-foreground\"\n )}\n >\n {info.getValue()}%\n </Badge>\n </div>\n ),\n }),\n columnHelper.accessor(\"growthIndicators\", {\n header: \"Growth Signals\",\n cell: (info) => {\n const indicators = info.getValue()\n if (!indicators.length) {\n return <span className=\"text-xs text-muted-foreground\">None</span>\n }\n return (\n <div className=\"flex items-center gap-1.5\">\n {indicators.slice(0, 2).map((indicator) => (\n <Badge\n key={indicator}\n variant=\"outline\"\n className=\"rounded-md border-blue-200 bg-blue-50 px-2 py-0.5 text-xs font-normal text-blue-700\"\n >\n {indicator}\n </Badge>\n ))}\n </div>\n )\n },\n }),\n columnHelper.accessor(\"industry\", {\n header: \"Industry\",\n cell: (info) => (\n <div className=\"flex items-center gap-1.5\">\n {info.getValue().slice(0, 2).map((industry) => (\n <Badge\n key={industry}\n variant=\"outline\"\n className={cn(\n \"rounded-md px-2 py-0.5 text-xs font-normal\",\n getIndustryColor(industry)\n )}\n >\n {industry}\n </Badge>\n ))}\n </div>\n ),\n }),\n columnHelper.accessor(\"lastInteraction\", {\n header: \"Last interaction\",\n cell: (info) => <span className=\"text-sm\">{info.getValue()}</span>,\n }),\n columnHelper.accessor(\"revenue\", {\n header: \"Revenue\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"headcount\", {\n header: \"Headcount\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"lastFunding\", {\n header: \"Last funding\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n columnHelper.accessor(\"owner\", {\n header: \"Owner\",\n cell: (info) => <span className=\"text-sm\">{info.getValue()}</span>,\n }),\n columnHelper.accessor(\"opportunityCount\", {\n header: \"Opportunity count\",\n cell: (info) => (\n <span className=\"rounded-md bg-muted/50 px-2 py-0.5 text-xs font-medium\">\n {info.getValue()}\n </span>\n ),\n }),\n ],\n [iconMap, entityUrlBuilder]\n )\n\n const table = useReactTable({\n data: filteredRows,\n columns,\n state: {\n sorting,\n columnVisibility,\n },\n onSortingChange: setSorting,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n })\n\n const displayColumns = table.getAllLeafColumns().map((column) => {\n const header = column.columnDef.header\n const label = typeof header === \"string\" ? header : column.id\n\n return {\n id: column.id,\n label,\n visible: column.getIsVisible(),\n canHide: column.getCanHide(),\n }\n })\n\n const toggleCategoryFilter = (categoryId: string, option: string) => {\n setSelectedFilters((previous) => toggleFilterValue(previous, categoryId, option))\n }\n\n return (\n <div className=\"relative flex h-full min-h-[560px] flex-col bg-background\">\n <DataTableToolbar\n categories={resolvedFilterCategories}\n selectedFilters={selectedFilters}\n onToggleFilter={toggleCategoryFilter}\n sorting={sorting}\n onSortingChange={setSorting}\n displayColumns={displayColumns}\n onToggleColumn={(columnId) => table.getColumn(columnId)?.toggleVisibility()}\n onResetDisplay={() => setColumnVisibility(DEFAULT_COLUMN_VISIBILITY)}\n />\n\n <DataTableQuickViews\n quickViews={resolvedQuickViews}\n moreViews={resolvedMoreQuickViews}\n activeView={activeQuickView}\n onViewChange={setActiveQuickView}\n />\n\n <div className=\"relative min-h-0 flex-1 overflow-auto border-t border-border\">\n <table className=\"w-max min-w-full border-collapse text-sm\">\n <thead className=\"sticky top-0 z-10 bg-background\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id} className=\"border-b border-border\">\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"h-10 border-r border-border px-4 text-left text-xs font-medium text-muted-foreground/80 last:border-r-0\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows.length > 0 ? (\n <>\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n onClick={() => onRowClick?.(row.original)}\n className={cn(\n \"group border-b border-border/50 transition-colors hover:bg-muted/30\",\n onRowClick && \"cursor-pointer\",\n )}\n >\n {row.getVisibleCells().map((cell) => (\n <td\n key={cell.id}\n className=\"border-r border-border/40 px-4 py-2.5 align-middle last:border-r-0\"\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </tr>\n ))}\n <tr>\n <td\n className=\"px-4 py-2 text-xs text-muted-foreground\"\n colSpan={columns.length}\n >\n {table.getRowModel().rows.length} rows\n </td>\n </tr>\n </>\n ) : (\n <tr>\n <td colSpan={columns.length} className=\"h-52 px-4 text-center\">\n <div className=\"flex flex-col items-center gap-1 text-muted-foreground\">\n <SearchX className=\"h-7 w-7 opacity-40\" />\n <p className=\"text-sm font-medium\">No rows found</p>\n <p className=\"text-xs\">Try adjusting your filters or quick views</p>\n </div>\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n\n {scoreModal && (() => {\n const data = SCORE_ANALYSIS[scoreModal.type](scoreModal.row)\n return (\n <ScoreAnalysisModal\n open\n onOpenChange={(open) => { if (!open) setScoreModal(null) }}\n title={data.title}\n description={data.description}\n score={scoreModal.type === \"Risk\" ? scoreModal.row.riskScore : scoreModal.row.expansionScore}\n scoreIntent={scoreModal.type === \"Risk\" ? \"risk\" : \"positive\"}\n whyNow={data.whyNow}\n evidence={data.evidence}\n factors={data.factors}\n onFactorFeedback={onScoreFactorFeedback\n ? (key, type, detail) => onScoreFactorFeedback(scoreModal.row.name, scoreModal.type, key, type, detail)\n : (key, type, detail) => console.log(\"Factor feedback:\", { account: scoreModal.row.name, factor: key, type, detail })\n }\n companyName={scoreModal.row.name}\n opportunityUrl={`https://acme.lightning.force.com/lightning/r/Opportunity/006${scoreModal.row.id}/view`}\n onApprove={() => console.log(\"Approved signal — creating opportunity:\", { account: scoreModal.row.name, type: scoreModal.type })}\n onApproveFeedback={onScoreApproveFeedback\n ? (reasons, detail) => onScoreApproveFeedback(scoreModal.row.name, scoreModal.type, reasons, detail)\n : (reasons, detail) => console.log(\"Approval feedback:\", { account: scoreModal.row.name, reasons, detail })\n }\n onDismiss={onScoreDismissFeedback\n ? (reasons, detail) => onScoreDismissFeedback(scoreModal.row.name, scoreModal.type, reasons, detail)\n : (reasons, detail) => console.log(\"Dismissed signal:\", { account: scoreModal.row.name, reasons, detail })\n }\n />\n )\n })()}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
@@ -8,7 +8,22 @@ interface LinkedEntityCellProps extends React.HTMLAttributes<HTMLDivElement> {
8
8
  icon?: React.ReactNode;
9
9
  external?: boolean;
10
10
  onNavigate?: () => void;
11
+ /**
12
+ * When provided, renders a small colored rounded initial badge before the
13
+ * name. The full string is used as the color seed; the displayed letter is
14
+ * the first character. Omit to render no badge.
15
+ */
16
+ avatarLabel?: string;
17
+ /**
18
+ * Optional node rendered after the name (a trailing slot), e.g. a separate
19
+ * action link. Does not affect the name's own `href`.
20
+ */
21
+ trailingAction?: React.ReactNode;
22
+ /**
23
+ * Escape-hatch class merged onto the name span/link. Defaults to `text-sm`.
24
+ */
25
+ nameClassName?: string;
11
26
  }
12
- declare function LinkedEntityCell({ name, href, subtitle, meta, icon, external, onNavigate, className, ...props }: LinkedEntityCellProps): React.JSX.Element;
27
+ declare function LinkedEntityCell({ name, href, subtitle, meta, icon, external, onNavigate, avatarLabel, trailingAction, nameClassName, className, ...props }: LinkedEntityCellProps): React.JSX.Element;
13
28
 
14
29
  export { LinkedEntityCell, type LinkedEntityCellProps };
@@ -35,6 +35,7 @@ var __objRest = (source, exclude) => {
35
35
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
36
36
  import { ExternalLink } from "lucide-react";
37
37
  import { cn } from "../lib/utils.js";
38
+ import { getEntityColor } from "../lib/entity-color.js";
38
39
  function LinkedEntityCell(_a) {
39
40
  var _b = _a, {
40
41
  name,
@@ -44,6 +45,9 @@ function LinkedEntityCell(_a) {
44
45
  icon,
45
46
  external = false,
46
47
  onNavigate,
48
+ avatarLabel,
49
+ trailingAction,
50
+ nameClassName,
47
51
  className
48
52
  } = _b, props = __objRest(_b, [
49
53
  "name",
@@ -53,6 +57,9 @@ function LinkedEntityCell(_a) {
53
57
  "icon",
54
58
  "external",
55
59
  "onNavigate",
60
+ "avatarLabel",
61
+ "trailingAction",
62
+ "nameClassName",
56
63
  "className"
57
64
  ]);
58
65
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -66,6 +73,18 @@ function LinkedEntityCell(_a) {
66
73
  className: cn("flex min-w-0 items-center gap-2", className)
67
74
  }, props), {
68
75
  children: [
76
+ avatarLabel ? /* @__PURE__ */ jsx(
77
+ "span",
78
+ {
79
+ "data-slot": "linked-entity-cell-avatar",
80
+ "aria-hidden": "true",
81
+ className: cn(
82
+ "flex h-6 w-6 shrink-0 items-center justify-center rounded text-[10px] font-bold",
83
+ getEntityColor(avatarLabel)
84
+ ),
85
+ children: avatarLabel.slice(0, 1)
86
+ }
87
+ ) : null,
69
88
  icon ? /* @__PURE__ */ jsx("span", { "data-slot": "linked-entity-cell-icon", className: "shrink-0 text-muted-foreground", children: icon }) : null,
70
89
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
71
90
  href ? /* @__PURE__ */ jsx(
@@ -76,16 +95,27 @@ function LinkedEntityCell(_a) {
76
95
  target: external ? "_blank" : void 0,
77
96
  rel: external ? "noreferrer" : void 0,
78
97
  onClick: onNavigate,
79
- className: "inline-flex max-w-full items-center gap-1 truncate font-medium text-foreground underline-offset-4 hover:text-primary hover:underline",
98
+ className: cn(
99
+ "inline-flex max-w-full items-center gap-1 truncate text-sm font-medium text-foreground underline-offset-4 hover:text-primary hover:underline",
100
+ nameClassName
101
+ ),
80
102
  children: content
81
103
  }
82
- ) : /* @__PURE__ */ jsx("span", { "data-slot": "linked-entity-cell-name", className: "block truncate font-medium text-foreground", children: name }),
104
+ ) : /* @__PURE__ */ jsx(
105
+ "span",
106
+ {
107
+ "data-slot": "linked-entity-cell-name",
108
+ className: cn("block truncate text-sm font-medium text-foreground", nameClassName),
109
+ children: name
110
+ }
111
+ ),
83
112
  subtitle || meta ? /* @__PURE__ */ jsxs("div", { "data-slot": "linked-entity-cell-meta", className: "mt-0.5 truncate text-xs text-muted-foreground", children: [
84
113
  subtitle,
85
114
  subtitle && meta ? /* @__PURE__ */ jsx("span", { className: "px-1", children: "\xB7" }) : null,
86
115
  meta
87
116
  ] }) : null
88
- ] })
117
+ ] }),
118
+ trailingAction ? /* @__PURE__ */ jsx("span", { "data-slot": "linked-entity-cell-trailing", className: "shrink-0", children: trailingAction }) : null
89
119
  ]
90
120
  })
91
121
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/linked-entity-cell.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { ExternalLink } from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\n\nexport interface LinkedEntityCellProps extends React.HTMLAttributes<HTMLDivElement> {\n name: React.ReactNode\n href?: string\n subtitle?: React.ReactNode\n meta?: React.ReactNode\n icon?: React.ReactNode\n external?: boolean\n onNavigate?: () => void\n}\n\nexport function LinkedEntityCell({\n name,\n href,\n subtitle,\n meta,\n icon,\n external = false,\n onNavigate,\n className,\n ...props\n}: LinkedEntityCellProps) {\n const content = (\n <>\n <span className=\"truncate\">{name}</span>\n {external ? <ExternalLink className=\"h-3 w-3 shrink-0 opacity-60\" aria-hidden=\"true\" /> : null}\n </>\n )\n\n return (\n <div\n data-slot=\"linked-entity-cell\"\n className={cn(\"flex min-w-0 items-center gap-2\", className)}\n {...props}\n >\n {icon ? (\n <span data-slot=\"linked-entity-cell-icon\" className=\"shrink-0 text-muted-foreground\">\n {icon}\n </span>\n ) : null}\n <div className=\"min-w-0 flex-1\">\n {href ? (\n <a\n data-slot=\"linked-entity-cell-link\"\n href={href}\n target={external ? \"_blank\" : undefined}\n rel={external ? \"noreferrer\" : undefined}\n onClick={onNavigate}\n className=\"inline-flex max-w-full items-center gap-1 truncate font-medium text-foreground underline-offset-4 hover:text-primary hover:underline\"\n >\n {content}\n </a>\n ) : (\n <span data-slot=\"linked-entity-cell-name\" className=\"block truncate font-medium text-foreground\">\n {name}\n </span>\n )}\n {subtitle || meta ? (\n <div data-slot=\"linked-entity-cell-meta\" className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {subtitle}\n {subtitle && meta ? <span className=\"px-1\">·</span> : null}\n {meta}\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BI,mBACE,KADF;AA1BJ,SAAS,oBAAoB;AAE7B,SAAS,UAAU;AAYZ,SAAS,iBAAiB,IAUP;AAVO,eAC/B;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,EAzBF,IAiBiC,IAS5B,kBAT4B,IAS5B;AAAA,IARH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAM,UACJ,iCACE;AAAA,wBAAC,UAAK,WAAU,YAAY,gBAAK;AAAA,IAChC,WAAW,oBAAC,gBAAa,WAAU,+BAA8B,eAAY,QAAO,IAAK;AAAA,KAC5F;AAGF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,mCAAmC,SAAS;AAAA,OACtD,QAHL;AAAA,MAKE;AAAA,eACC,oBAAC,UAAK,aAAU,2BAA0B,WAAU,kCACjD,gBACH,IACE;AAAA,QACJ,qBAAC,SAAI,WAAU,kBACZ;AAAA,iBACC;AAAA,YAAC;AAAA;AAAA,cACC,aAAU;AAAA,cACV;AAAA,cACA,QAAQ,WAAW,WAAW;AAAA,cAC9B,KAAK,WAAW,eAAe;AAAA,cAC/B,SAAS;AAAA,cACT,WAAU;AAAA,cAET;AAAA;AAAA,UACH,IAEA,oBAAC,UAAK,aAAU,2BAA0B,WAAU,8CACjD,gBACH;AAAA,UAED,YAAY,OACX,qBAAC,SAAI,aAAU,2BAA0B,WAAU,iDAChD;AAAA;AAAA,YACA,YAAY,OAAO,oBAAC,UAAK,WAAU,QAAO,kBAAC,IAAU;AAAA,YACrD;AAAA,aACH,IACE;AAAA,WACN;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/linked-entity-cell.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { ExternalLink } from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { getEntityColor } from \"../lib/entity-color\"\n\nexport interface LinkedEntityCellProps extends React.HTMLAttributes<HTMLDivElement> {\n name: React.ReactNode\n href?: string\n subtitle?: React.ReactNode\n meta?: React.ReactNode\n icon?: React.ReactNode\n external?: boolean\n onNavigate?: () => void\n /**\n * When provided, renders a small colored rounded initial badge before the\n * name. The full string is used as the color seed; the displayed letter is\n * the first character. Omit to render no badge.\n */\n avatarLabel?: string\n /**\n * Optional node rendered after the name (a trailing slot), e.g. a separate\n * action link. Does not affect the name's own `href`.\n */\n trailingAction?: React.ReactNode\n /**\n * Escape-hatch class merged onto the name span/link. Defaults to `text-sm`.\n */\n nameClassName?: string\n}\n\nexport function LinkedEntityCell({\n name,\n href,\n subtitle,\n meta,\n icon,\n external = false,\n onNavigate,\n avatarLabel,\n trailingAction,\n nameClassName,\n className,\n ...props\n}: LinkedEntityCellProps) {\n const content = (\n <>\n <span className=\"truncate\">{name}</span>\n {external ? <ExternalLink className=\"h-3 w-3 shrink-0 opacity-60\" aria-hidden=\"true\" /> : null}\n </>\n )\n\n return (\n <div\n data-slot=\"linked-entity-cell\"\n className={cn(\"flex min-w-0 items-center gap-2\", className)}\n {...props}\n >\n {avatarLabel ? (\n <span\n data-slot=\"linked-entity-cell-avatar\"\n aria-hidden=\"true\"\n className={cn(\n \"flex h-6 w-6 shrink-0 items-center justify-center rounded text-[10px] font-bold\",\n getEntityColor(avatarLabel),\n )}\n >\n {avatarLabel.slice(0, 1)}\n </span>\n ) : null}\n {icon ? (\n <span data-slot=\"linked-entity-cell-icon\" className=\"shrink-0 text-muted-foreground\">\n {icon}\n </span>\n ) : null}\n <div className=\"min-w-0 flex-1\">\n {href ? (\n <a\n data-slot=\"linked-entity-cell-link\"\n href={href}\n target={external ? \"_blank\" : undefined}\n rel={external ? \"noreferrer\" : undefined}\n onClick={onNavigate}\n className={cn(\n \"inline-flex max-w-full items-center gap-1 truncate text-sm font-medium text-foreground underline-offset-4 hover:text-primary hover:underline\",\n nameClassName,\n )}\n >\n {content}\n </a>\n ) : (\n <span\n data-slot=\"linked-entity-cell-name\"\n className={cn(\"block truncate text-sm font-medium text-foreground\", nameClassName)}\n >\n {name}\n </span>\n )}\n {subtitle || meta ? (\n <div data-slot=\"linked-entity-cell-meta\" className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {subtitle}\n {subtitle && meta ? <span className=\"px-1\">·</span> : null}\n {meta}\n </div>\n ) : null}\n </div>\n {trailingAction ? (\n <span data-slot=\"linked-entity-cell-trailing\" className=\"shrink-0\">\n {trailingAction}\n </span>\n ) : null}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDI,mBACE,KADF;AA7CJ,SAAS,oBAAoB;AAE7B,SAAS,UAAU;AACnB,SAAS,sBAAsB;AA2BxB,SAAS,iBAAiB,IAaP;AAbO,eAC/B;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EA5CF,IAiCiC,IAY5B,kBAZ4B,IAY5B;AAAA,IAXH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAM,UACJ,iCACE;AAAA,wBAAC,UAAK,WAAU,YAAY,gBAAK;AAAA,IAChC,WAAW,oBAAC,gBAAa,WAAU,+BAA8B,eAAY,QAAO,IAAK;AAAA,KAC5F;AAGF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,mCAAmC,SAAS;AAAA,OACtD,QAHL;AAAA,MAKE;AAAA,sBACC;AAAA,UAAC;AAAA;AAAA,YACC,aAAU;AAAA,YACV,eAAY;AAAA,YACZ,WAAW;AAAA,cACT;AAAA,cACA,eAAe,WAAW;AAAA,YAC5B;AAAA,YAEC,sBAAY,MAAM,GAAG,CAAC;AAAA;AAAA,QACzB,IACE;AAAA,QACH,OACC,oBAAC,UAAK,aAAU,2BAA0B,WAAU,kCACjD,gBACH,IACE;AAAA,QACJ,qBAAC,SAAI,WAAU,kBACZ;AAAA,iBACC;AAAA,YAAC;AAAA;AAAA,cACC,aAAU;AAAA,cACV;AAAA,cACA,QAAQ,WAAW,WAAW;AAAA,cAC9B,KAAK,WAAW,eAAe;AAAA,cAC/B,SAAS;AAAA,cACT,WAAW;AAAA,gBACT;AAAA,gBACA;AAAA,cACF;AAAA,cAEC;AAAA;AAAA,UACH,IAEA;AAAA,YAAC;AAAA;AAAA,cACC,aAAU;AAAA,cACV,WAAW,GAAG,sDAAsD,aAAa;AAAA,cAEhF;AAAA;AAAA,UACH;AAAA,UAED,YAAY,OACX,qBAAC,SAAI,aAAU,2BAA0B,WAAU,iDAChD;AAAA;AAAA,YACA,YAAY,OAAO,oBAAC,UAAK,WAAU,QAAO,kBAAC,IAAU;AAAA,YACrD;AAAA,aACH,IACE;AAAA,WACN;AAAA,QACC,iBACC,oBAAC,UAAK,aAAU,+BAA8B,WAAU,YACrD,0BACH,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;","names":[]}
@@ -71,7 +71,7 @@ function SalesforceMark({ size = 13 }) {
71
71
  );
72
72
  }
73
73
  function OwnerAvatar({ person, size = "sm" }) {
74
- return /* @__PURE__ */ jsxs(Avatar, { size, className: "ring-background ring-1", children: [
74
+ return /* @__PURE__ */ jsxs(Avatar, { size, className: "ring-background ring-2", children: [
75
75
  person.avatarUrl ? /* @__PURE__ */ jsx(AvatarImage, { src: person.avatarUrl, alt: person.name }) : null,
76
76
  /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-muted text-muted-foreground text-[10px] font-medium uppercase", children: getInitials({ name: person.name, email: person.email }) })
77
77
  ] });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/owner-chips.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * owner-chips.tsx — disambiguates the two ownership concepts operators kept\n * confusing on the case panel:\n *\n * 1. SIGNAL OWNER — Handled's OWN assignment. Who owns working this\n * signal/action inside Handled. Editable here (assign / reassign /\n * unassign). Replaces the ambiguous bare \"Unassigned\" chip.\n *\n * 2. ACCOUNT OWNER(S) — read-through from Salesforce. An account can carry\n * more than one (AE + RM). Informational + links out to Salesforce; never\n * assigned from inside Handled. Leads with the Salesforce mark.\n *\n * Account owner chips are read-only dropdowns. A single owner still opens a\n * small Salesforce-sourced details menu; multiple owners show stacked avatars\n * and a ×N badge before listing each owner with optional Salesforce links.\n *\n * Presentational only: data + handlers come from the consumer (the app).\n */\n\nimport * as React from \"react\"\nimport {\n ChevronDown,\n ChevronUp,\n Check,\n UserPlus,\n UserMinus,\n Info,\n ArrowUpRight,\n} from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { getInitials } from \"../lib/user-display\"\nimport { BRAND_ICONS } from \"../lib/icons\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"./avatar\"\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from \"./dropdown-menu\"\n\nexport interface OwnerPerson {\n /** Stable id (profile id for signal owner; SF user id for account owner). */\n id?: string\n name: string\n email?: string\n /** e.g. \"Relationship Manager\", \"Account Executive\". */\n role?: string\n /** Avatar image; falls back to initials when absent. */\n avatarUrl?: string | null\n /** External link (Salesforce) for an account owner. */\n href?: string\n}\n\n/* ── shared bits ─────────────────────────────────────────────────────────── */\n\nfunction SalesforceMark({ size = 13 }: { size?: number }) {\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={BRAND_ICONS.salesforce}\n alt=\"Salesforce\"\n width={size}\n height={size}\n style={{ width: size, height: size, objectFit: \"contain\", display: \"block\" }}\n />\n )\n}\n\nfunction OwnerAvatar({ person, size = \"sm\" }: { person: OwnerPerson; size?: \"sm\" | \"default\" }) {\n return (\n <Avatar size={size} className=\"ring-background ring-1\">\n {person.avatarUrl ? <AvatarImage src={person.avatarUrl} alt={person.name} /> : null}\n <AvatarFallback className=\"bg-muted text-muted-foreground text-[10px] font-medium uppercase\">\n {getInitials({ name: person.name, email: person.email })}\n </AvatarFallback>\n </Avatar>\n )\n}\n\n// Component-owned compact sizing. Set directly here (not via consumer\n// className) because cn()/tailwind-merge can strip conflicting overrides.\nconst chipBase =\n \"inline-flex h-7 items-center gap-1 rounded-md border border-border bg-background px-2 text-[12px] \" +\n \"shadow-[0_1px_1px_rgba(0,0,0,0.03)]\"\n\n/* ── Signal owner (Handled assignment, editable) ─────────────────────────── */\n\nexport interface SignalOwnerChipProps {\n /** Current Handled assignee, or null when unassigned. */\n owner: OwnerPerson | null\n /** Operators the case can be assigned to (preloaded — no fetch on open). */\n assignableOwners?: OwnerPerson[]\n onAssign?: (owner: OwnerPerson) => void\n onUnassign?: () => void\n /** Read-only: render a static chip without the assignment menu. */\n disabled?: boolean\n className?: string\n}\n\nfunction SignalOwnerChip({\n owner,\n assignableOwners = [],\n onAssign,\n onUnassign,\n disabled,\n className,\n}: SignalOwnerChipProps) {\n const [open, setOpen] = React.useState(false)\n\n const value = (\n <>\n {owner ? (\n <OwnerAvatar person={owner} />\n ) : (\n <span className=\"text-muted-foreground inline-flex size-4 items-center justify-center\">\n <UserPlus size={12} />\n </span>\n )}\n <span className=\"text-muted-foreground text-[10px] font-medium tracking-wide uppercase\">\n Signal owner\n </span>\n <span className=\"bg-border/70 mx-0.5 h-3 w-px\" aria-hidden />\n <span className={cn(\"font-medium\", owner ? \"text-foreground\" : \"text-muted-foreground\")}>\n {owner ? owner.name : \"Unassigned\"}\n </span>\n </>\n )\n\n // Read-only or nothing to assign to: static chip.\n if (disabled || (!onAssign && !onUnassign)) {\n return (\n <span\n data-slot=\"signal-owner-chip\"\n data-empty={owner ? undefined : \"true\"}\n className={cn(chipBase, className)}\n title=\"Who owns this signal inside Handled\"\n >\n {value}\n </span>\n )\n }\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"signal-owner-chip\"\n data-empty={owner ? undefined : \"true\"}\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title=\"Who owns this signal inside Handled\"\n >\n {value}\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-64\">\n <DropdownMenuLabel className=\"flex flex-col gap-0.5\">\n <span className=\"text-[13px] font-semibold\">Assign signal owner</span>\n <span className=\"text-muted-foreground text-[11px] font-normal\">\n Who works this inside Handled, separate from the Salesforce account owner.\n </span>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {assignableOwners.map((o) => {\n const active = !!owner && (owner.id ? owner.id === o.id : owner.name === o.name)\n return (\n <DropdownMenuItem\n key={o.id ?? o.name}\n onSelect={() => onAssign?.(o)}\n className=\"gap-2\"\n >\n <OwnerAvatar person={o} size=\"default\" />\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-[13px] font-medium\">{o.name}</span>\n {o.role ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{o.role}</span>\n ) : null}\n </span>\n {active ? <Check size={14} className=\"text-foreground ml-auto\" /> : null}\n </DropdownMenuItem>\n )\n })}\n {owner && onUnassign ? (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onSelect={() => onUnassign()} className=\"text-muted-foreground gap-2\">\n <UserMinus size={13} /> Unassign\n </DropdownMenuItem>\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/* ── Account owner(s) (Salesforce, read-through) ─────────────────────────── */\n\nexport interface AccountOwnerChipProps {\n /** Salesforce account owners (RM, AE, …). Empty -> renders nothing. */\n owners: OwnerPerson[]\n className?: string\n}\n\nfunction AccountOwnerSummary({ person }: { person: OwnerPerson }) {\n return (\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-[13px] font-medium\">{person.name}</span>\n {person.role ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{person.role}</span>\n ) : null}\n {person.email ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{person.email}</span>\n ) : null}\n </span>\n )\n}\n\nfunction AccountOwnerSalesforceLink({ person }: { person: OwnerPerson }) {\n if (!person.href) return null\n\n return (\n <DropdownMenuItem asChild className=\"p-0\">\n <a\n href={person.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-account-owner-salesforce-link=\"true\"\n className=\"text-foreground focus:bg-accent focus:text-accent-foreground flex items-center gap-1.5 rounded-sm px-2 py-1.5 text-[12px] font-medium outline-hidden transition-colors\"\n title={`Open ${person.name} in Salesforce`}\n >\n <ArrowUpRight size={12} className=\"text-muted-foreground\" />\n Open in Salesforce\n </a>\n </DropdownMenuItem>\n )\n}\n\nfunction AccountOwnerRow({ person }: { person: OwnerPerson }) {\n return (\n <>\n <DropdownMenuItem\n disabled\n data-owner-row=\"true\"\n className=\"items-start gap-2 py-1.5 data-[disabled]:opacity-100\"\n >\n <OwnerAvatar person={person} size=\"default\" />\n <AccountOwnerSummary person={person} />\n </DropdownMenuItem>\n <AccountOwnerSalesforceLink person={person} />\n </>\n )\n}\n\nfunction SalesforceReadOnlyHelper() {\n return (\n <div role=\"presentation\" className=\"text-muted-foreground flex items-start gap-1.5 px-2 py-1.5 text-[11px]\">\n <Info size={12} className=\"mt-0.5 shrink-0\" />\n <span>Read-only from Salesforce. Manage owners in Salesforce.</span>\n </div>\n )\n}\n\nfunction AccountOwnerChip({ owners, className }: AccountOwnerChipProps) {\n const [open, setOpen] = React.useState(false)\n if (!owners.length) return null\n const multi = owners.length > 1\n\n if (!multi) {\n const only = owners[0]\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"account-owner-chip\"\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title={`Account owner in Salesforce — ${only.name}`}\n >\n <span className=\"inline-flex shrink-0 items-center\">\n <SalesforceMark />\n </span>\n <OwnerAvatar person={only} />\n <span className=\"text-foreground font-medium\">{only.name}</span>\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-72\">\n <DropdownMenuLabel className=\"flex items-center gap-1.5 text-[13px]\">\n <SalesforceMark />\n Account owner\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <AccountOwnerRow person={only} />\n <DropdownMenuSeparator />\n <SalesforceReadOnlyHelper />\n </DropdownMenuContent>\n </DropdownMenu>\n )\n }\n\n // Multiple owners: stacked avatars + ×N + a menu listing each.\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"account-owner-chip\"\n data-multi=\"true\"\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title=\"Account owners in Salesforce\"\n >\n <span className=\"inline-flex shrink-0 items-center\">\n <SalesforceMark />\n </span>\n <span className=\"flex -space-x-2\">\n {owners.map((o) => (\n <OwnerAvatar key={o.id ?? o.name} person={o} />\n ))}\n </span>\n <span className=\"text-foreground font-medium\">Account owners</span>\n <span className=\"bg-muted text-muted-foreground rounded px-1 text-[10px] font-semibold tabular-nums\">\n ×{owners.length}\n </span>\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-72\">\n <DropdownMenuLabel className=\"flex items-center gap-1.5 text-[13px]\">\n <SalesforceMark />\n {owners.length} account owners\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {owners.map((o) => (\n <AccountOwnerRow key={o.id ?? o.name} person={o} />\n ))}\n <DropdownMenuSeparator />\n <SalesforceReadOnlyHelper />\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/* ── Convenience composite ──────────────────────────────────────────────── */\n\nexport interface OwnerChipsProps extends SignalOwnerChipProps {\n /** Salesforce account owners (read-through). */\n accountOwners?: OwnerPerson[]\n}\n\nfunction OwnerChips({ accountOwners = [], className, ...signal }: OwnerChipsProps) {\n return (\n <>\n <SignalOwnerChip {...signal} className={className} />\n <AccountOwnerChip owners={accountOwners} className={className} />\n </>\n )\n}\n\nexport { SignalOwnerChip, AccountOwnerChip, OwnerChips }\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/owner-chips.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * owner-chips.tsx — disambiguates the two ownership concepts operators kept\n * confusing on the case panel:\n *\n * 1. SIGNAL OWNER — Handled's OWN assignment. Who owns working this\n * signal/action inside Handled. Editable here (assign / reassign /\n * unassign). Replaces the ambiguous bare \"Unassigned\" chip.\n *\n * 2. ACCOUNT OWNER(S) — read-through from Salesforce. An account can carry\n * more than one (AE + RM). Informational + links out to Salesforce; never\n * assigned from inside Handled. Leads with the Salesforce mark.\n *\n * Account owner chips are read-only dropdowns. A single owner still opens a\n * small Salesforce-sourced details menu; multiple owners show stacked avatars\n * and a ×N badge before listing each owner with optional Salesforce links.\n *\n * Presentational only: data + handlers come from the consumer (the app).\n */\n\nimport * as React from \"react\"\nimport {\n ChevronDown,\n ChevronUp,\n Check,\n UserPlus,\n UserMinus,\n Info,\n ArrowUpRight,\n} from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { getInitials } from \"../lib/user-display\"\nimport { BRAND_ICONS } from \"../lib/icons\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"./avatar\"\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from \"./dropdown-menu\"\n\nexport interface OwnerPerson {\n /** Stable id (profile id for signal owner; SF user id for account owner). */\n id?: string\n name: string\n email?: string\n /** e.g. \"Relationship Manager\", \"Account Executive\". */\n role?: string\n /** Avatar image; falls back to initials when absent. */\n avatarUrl?: string | null\n /** External link (Salesforce) for an account owner. */\n href?: string\n}\n\n/* ── shared bits ─────────────────────────────────────────────────────────── */\n\nfunction SalesforceMark({ size = 13 }: { size?: number }) {\n return (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={BRAND_ICONS.salesforce}\n alt=\"Salesforce\"\n width={size}\n height={size}\n style={{ width: size, height: size, objectFit: \"contain\", display: \"block\" }}\n />\n )\n}\n\nfunction OwnerAvatar({ person, size = \"sm\" }: { person: OwnerPerson; size?: \"sm\" | \"default\" }) {\n return (\n <Avatar size={size} className=\"ring-background ring-2\">\n {person.avatarUrl ? <AvatarImage src={person.avatarUrl} alt={person.name} /> : null}\n <AvatarFallback className=\"bg-muted text-muted-foreground text-[10px] font-medium uppercase\">\n {getInitials({ name: person.name, email: person.email })}\n </AvatarFallback>\n </Avatar>\n )\n}\n\n// Component-owned compact sizing. Set directly here (not via consumer\n// className) because cn()/tailwind-merge can strip conflicting overrides.\nconst chipBase =\n \"inline-flex h-7 items-center gap-1 rounded-md border border-border bg-background px-2 text-[12px] \" +\n \"shadow-[0_1px_1px_rgba(0,0,0,0.03)]\"\n\n/* ── Signal owner (Handled assignment, editable) ─────────────────────────── */\n\nexport interface SignalOwnerChipProps {\n /** Current Handled assignee, or null when unassigned. */\n owner: OwnerPerson | null\n /** Operators the case can be assigned to (preloaded — no fetch on open). */\n assignableOwners?: OwnerPerson[]\n onAssign?: (owner: OwnerPerson) => void\n onUnassign?: () => void\n /** Read-only: render a static chip without the assignment menu. */\n disabled?: boolean\n className?: string\n}\n\nfunction SignalOwnerChip({\n owner,\n assignableOwners = [],\n onAssign,\n onUnassign,\n disabled,\n className,\n}: SignalOwnerChipProps) {\n const [open, setOpen] = React.useState(false)\n\n const value = (\n <>\n {owner ? (\n <OwnerAvatar person={owner} />\n ) : (\n <span className=\"text-muted-foreground inline-flex size-4 items-center justify-center\">\n <UserPlus size={12} />\n </span>\n )}\n <span className=\"text-muted-foreground text-[10px] font-medium tracking-wide uppercase\">\n Signal owner\n </span>\n <span className=\"bg-border/70 mx-0.5 h-3 w-px\" aria-hidden />\n <span className={cn(\"font-medium\", owner ? \"text-foreground\" : \"text-muted-foreground\")}>\n {owner ? owner.name : \"Unassigned\"}\n </span>\n </>\n )\n\n // Read-only or nothing to assign to: static chip.\n if (disabled || (!onAssign && !onUnassign)) {\n return (\n <span\n data-slot=\"signal-owner-chip\"\n data-empty={owner ? undefined : \"true\"}\n className={cn(chipBase, className)}\n title=\"Who owns this signal inside Handled\"\n >\n {value}\n </span>\n )\n }\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"signal-owner-chip\"\n data-empty={owner ? undefined : \"true\"}\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title=\"Who owns this signal inside Handled\"\n >\n {value}\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-64\">\n <DropdownMenuLabel className=\"flex flex-col gap-0.5\">\n <span className=\"text-[13px] font-semibold\">Assign signal owner</span>\n <span className=\"text-muted-foreground text-[11px] font-normal\">\n Who works this inside Handled, separate from the Salesforce account owner.\n </span>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {assignableOwners.map((o) => {\n const active = !!owner && (owner.id ? owner.id === o.id : owner.name === o.name)\n return (\n <DropdownMenuItem\n key={o.id ?? o.name}\n onSelect={() => onAssign?.(o)}\n className=\"gap-2\"\n >\n <OwnerAvatar person={o} size=\"default\" />\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-[13px] font-medium\">{o.name}</span>\n {o.role ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{o.role}</span>\n ) : null}\n </span>\n {active ? <Check size={14} className=\"text-foreground ml-auto\" /> : null}\n </DropdownMenuItem>\n )\n })}\n {owner && onUnassign ? (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onSelect={() => onUnassign()} className=\"text-muted-foreground gap-2\">\n <UserMinus size={13} /> Unassign\n </DropdownMenuItem>\n </>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/* ── Account owner(s) (Salesforce, read-through) ─────────────────────────── */\n\nexport interface AccountOwnerChipProps {\n /** Salesforce account owners (RM, AE, …). Empty -> renders nothing. */\n owners: OwnerPerson[]\n className?: string\n}\n\nfunction AccountOwnerSummary({ person }: { person: OwnerPerson }) {\n return (\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-[13px] font-medium\">{person.name}</span>\n {person.role ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{person.role}</span>\n ) : null}\n {person.email ? (\n <span className=\"text-muted-foreground truncate text-[11px]\">{person.email}</span>\n ) : null}\n </span>\n )\n}\n\nfunction AccountOwnerSalesforceLink({ person }: { person: OwnerPerson }) {\n if (!person.href) return null\n\n return (\n <DropdownMenuItem asChild className=\"p-0\">\n <a\n href={person.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-account-owner-salesforce-link=\"true\"\n className=\"text-foreground focus:bg-accent focus:text-accent-foreground flex items-center gap-1.5 rounded-sm px-2 py-1.5 text-[12px] font-medium outline-hidden transition-colors\"\n title={`Open ${person.name} in Salesforce`}\n >\n <ArrowUpRight size={12} className=\"text-muted-foreground\" />\n Open in Salesforce\n </a>\n </DropdownMenuItem>\n )\n}\n\nfunction AccountOwnerRow({ person }: { person: OwnerPerson }) {\n return (\n <>\n <DropdownMenuItem\n disabled\n data-owner-row=\"true\"\n className=\"items-start gap-2 py-1.5 data-[disabled]:opacity-100\"\n >\n <OwnerAvatar person={person} size=\"default\" />\n <AccountOwnerSummary person={person} />\n </DropdownMenuItem>\n <AccountOwnerSalesforceLink person={person} />\n </>\n )\n}\n\nfunction SalesforceReadOnlyHelper() {\n return (\n <div role=\"presentation\" className=\"text-muted-foreground flex items-start gap-1.5 px-2 py-1.5 text-[11px]\">\n <Info size={12} className=\"mt-0.5 shrink-0\" />\n <span>Read-only from Salesforce. Manage owners in Salesforce.</span>\n </div>\n )\n}\n\nfunction AccountOwnerChip({ owners, className }: AccountOwnerChipProps) {\n const [open, setOpen] = React.useState(false)\n if (!owners.length) return null\n const multi = owners.length > 1\n\n if (!multi) {\n const only = owners[0]\n\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"account-owner-chip\"\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title={`Account owner in Salesforce — ${only.name}`}\n >\n <span className=\"inline-flex shrink-0 items-center\">\n <SalesforceMark />\n </span>\n <OwnerAvatar person={only} />\n <span className=\"text-foreground font-medium\">{only.name}</span>\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-72\">\n <DropdownMenuLabel className=\"flex items-center gap-1.5 text-[13px]\">\n <SalesforceMark />\n Account owner\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <AccountOwnerRow person={only} />\n <DropdownMenuSeparator />\n <SalesforceReadOnlyHelper />\n </DropdownMenuContent>\n </DropdownMenu>\n )\n }\n\n // Multiple owners: stacked avatars + ×N + a menu listing each.\n return (\n <DropdownMenu open={open} onOpenChange={setOpen}>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n data-slot=\"account-owner-chip\"\n data-multi=\"true\"\n className={cn(chipBase, \"hover:bg-muted cursor-pointer transition-colors\", className)}\n title=\"Account owners in Salesforce\"\n >\n <span className=\"inline-flex shrink-0 items-center\">\n <SalesforceMark />\n </span>\n <span className=\"flex -space-x-2\">\n {owners.map((o) => (\n <OwnerAvatar key={o.id ?? o.name} person={o} />\n ))}\n </span>\n <span className=\"text-foreground font-medium\">Account owners</span>\n <span className=\"bg-muted text-muted-foreground rounded px-1 text-[10px] font-semibold tabular-nums\">\n ×{owners.length}\n </span>\n <span className=\"text-muted-foreground ml-0.5\">\n {open ? <ChevronUp size={12} /> : <ChevronDown size={12} />}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"w-72\">\n <DropdownMenuLabel className=\"flex items-center gap-1.5 text-[13px]\">\n <SalesforceMark />\n {owners.length} account owners\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n {owners.map((o) => (\n <AccountOwnerRow key={o.id ?? o.name} person={o} />\n ))}\n <DropdownMenuSeparator />\n <SalesforceReadOnlyHelper />\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/* ── Convenience composite ──────────────────────────────────────────────── */\n\nexport interface OwnerChipsProps extends SignalOwnerChipProps {\n /** Salesforce account owners (read-through). */\n accountOwners?: OwnerPerson[]\n}\n\nfunction OwnerChips({ accountOwners = [], className, ...signal }: OwnerChipsProps) {\n return (\n <>\n <SignalOwnerChip {...signal} className={className} />\n <AccountOwnerChip owners={accountOwners} className={className} />\n </>\n )\n}\n\nexport { SignalOwnerChip, AccountOwnerChip, OwnerChips }\n"],"mappings":"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","names":[]}
@@ -178,6 +178,8 @@ function VirtualizedDataTable({
178
178
  const newDir = activeSortColumn === sortKey ? activeSortDirection === "asc" ? "desc" : "asc" : "asc";
179
179
  onColumnSort(sortKey, newDir);
180
180
  } : void 0;
181
+ const headerDef = header.column.columnDef.header;
182
+ const headerTitle = typeof headerDef === "string" ? headerDef : void 0;
181
183
  return /* @__PURE__ */ jsxs(
182
184
  "div",
183
185
  {
@@ -198,10 +200,10 @@ function VirtualizedDataTable({
198
200
  "button",
199
201
  {
200
202
  type: "button",
201
- className: "flex min-w-0 flex-1 items-center gap-1 hover:text-foreground transition-colors",
203
+ className: "flex min-w-0 flex-1 items-center gap-1 text-xs leading-4 hover:text-foreground transition-colors",
202
204
  onClick: handleHeaderClick,
203
205
  children: [
204
- /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: flexRender(header.column.columnDef.header, header.getContext()) }),
206
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-xs leading-4", title: headerTitle, children: flexRender(headerDef, header.getContext()) }),
205
207
  sortIcon
206
208
  ]
207
209
  }
@@ -209,20 +211,14 @@ function VirtualizedDataTable({
209
211
  "button",
210
212
  {
211
213
  type: "button",
212
- className: "flex min-w-0 flex-1 items-center gap-1 hover:text-foreground transition-colors",
214
+ className: "flex min-w-0 flex-1 items-center gap-1 text-xs leading-4 hover:text-foreground transition-colors",
213
215
  onClick: header.column.getToggleSortingHandler(),
214
216
  children: [
215
- /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: flexRender(
216
- header.column.columnDef.header,
217
- header.getContext()
218
- ) }),
217
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-xs leading-4", title: headerTitle, children: flexRender(headerDef, header.getContext()) }),
219
218
  header.column.getIsSorted() === "asc" ? /* @__PURE__ */ jsx(ArrowUp, { className: "w-3 h-3 shrink-0" }) : header.column.getIsSorted() === "desc" ? /* @__PURE__ */ jsx(ArrowDown, { className: "w-3 h-3 shrink-0" }) : /* @__PURE__ */ jsx(ArrowUpDown, { className: "w-3 h-3 shrink-0 opacity-40" })
220
219
  ]
221
220
  }
222
- ) : /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: flexRender(
223
- header.column.columnDef.header,
224
- header.getContext()
225
- ) }),
221
+ ) : /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-xs leading-4", title: headerTitle, children: flexRender(headerDef, header.getContext()) }),
226
222
  (canServerSort || header.column.getCanSort() || header.column.getCanHide()) && /* @__PURE__ */ jsxs(DropdownMenu, { children: [
227
223
  /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
228
224
  "button",