open detail drawer at Measures section on row click

This commit is contained in:
Khalim Conn-Kowlessar 2026-05-05 12:10:08 +00:00
parent 75c0cde009
commit 0fe8dd0ac9
2 changed files with 44 additions and 5 deletions

View file

@ -22,7 +22,7 @@ import DocumentTable from "./DocumentTable";
import MeasuresTable from "./MeasuresTable";
import type { HubspotDeal } from "./types";
import PropertyDrawer from "./PropertyDrawer";
import PropertyDetailDrawer from "./PropertyDetailDrawer";
import PropertyDetailDrawer, { type DrawerSection } from "./PropertyDetailDrawer";
import AnalyticsView from "./AnalyticsView";
import type {
LiveTrackerProps,
@ -77,6 +77,19 @@ export default function LiveTracker({
// ── Property detail drawer ───────────────────────────────────────────
const [detailDeal, setDetailDeal] = useState<ClassifiedDeal | null>(null);
const [detailFocusSection, setDetailFocusSection] = useState<
DrawerSection | undefined
>(undefined);
const openDetailDrawer = (deal: ClassifiedDeal, section?: DrawerSection) => {
setDetailFocusSection(section);
setDetailDeal(deal);
};
const closeDetailDrawer = () => {
setDetailDeal(null);
setDetailFocusSection(undefined);
};
const handleOpenTable = (
stage: string,
@ -230,7 +243,7 @@ export default function LiveTracker({
<PropertyTable
data={currentProject?.allDeals ?? []}
onOpenDrawer={handleOpenDrawer}
onOpenDetail={setDetailDeal}
onOpenDetail={(deal) => openDetailDrawer(deal)}
docStatusMap={docStatusMap}
removalStatusByDeal={removalStatusByDeal}
/>
@ -310,6 +323,7 @@ export default function LiveTracker({
userCapability={userCapability}
approvalsByDeal={approvalsByDeal}
portfolioId={portfolioId}
onOpenDetail={(deal) => openDetailDrawer(deal, "measures")}
/>
</div>
</TabsContent>
@ -427,11 +441,12 @@ export default function LiveTracker({
{/* ── Property detail drawer ─────────────────────────────────────── */}
<PropertyDetailDrawer
deal={detailDeal}
onClose={() => setDetailDeal(null)}
onClose={closeDetailDrawer}
portfolioId={portfolioId}
userRole={userRole}
userCapability={userCapability}
userEmail={userEmail}
focusSection={detailFocusSection}
/>
</div>
);

View file

@ -35,6 +35,12 @@ type Props = {
userCapability: PortfolioCapabilityType;
approvalsByDeal: ApprovalsByDeal;
portfolioId: string;
/**
* Called when a measures row is clicked. The host (LiveTracker) opens the
* PropertyDetailDrawer focused on the Measures section. Optional so the
* table is still usable in isolation.
*/
onOpenDetail?: (deal: ClassifiedDeal) => void;
};
function ApprovalStatus({
@ -155,6 +161,7 @@ export default function MeasuresTable({
userCapability,
approvalsByDeal,
portfolioId,
onOpenDetail,
}: Props) {
const [search, setSearch] = useState("");
// pendingChanges: dealId -> desired Set<measureName> (the full intended approved set)
@ -338,15 +345,31 @@ export default function MeasuresTable({
const hasPending = pendingChanges[deal.dealId] !== undefined;
const isExpanded = expandedRows.has(deal.dealId);
const handleRowClick = () => {
if (onOpenDetail) onOpenDetail(deal);
};
const handleRowKeyDown = (e: React.KeyboardEvent<HTMLTableRowElement>) => {
if (!onOpenDetail) return;
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
onOpenDetail(deal);
}
};
return (
<React.Fragment key={deal.dealId}>
<TableRow
className={`border-b border-gray-50 hover:bg-gray-50/50 transition-colors ${hasPending ? "bg-amber-50/30" : ""}`}
data-testid="measures-row"
onClick={onOpenDetail ? handleRowClick : undefined}
onKeyDown={onOpenDetail ? handleRowKeyDown : undefined}
tabIndex={onOpenDetail ? 0 : undefined}
role={onOpenDetail ? "button" : undefined}
className={`border-b border-gray-50 hover:bg-gray-50/50 transition-colors ${hasPending ? "bg-amber-50/30" : ""} ${onOpenDetail ? "cursor-pointer" : ""}`}
>
{/* Expand toggle */}
<TableCell className="py-3 pl-3 pr-0 w-6">
<button
onClick={() => toggleRowExpand(deal.dealId)}
onClick={(e) => { e.stopPropagation(); toggleRowExpand(deal.dealId); }}
className="text-gray-400 hover:text-brandblue transition-colors"
aria-label={isExpanded ? "Collapse activity" : "Expand activity"}
>
@ -389,6 +412,7 @@ export default function MeasuresTable({
return (
<label
key={measure}
onClick={(e) => e.stopPropagation()}
className={`flex items-center gap-1.5 cursor-pointer px-2 py-1 rounded-full text-xs border transition-colors ${
isApproved
? "bg-emerald-50 border-emerald-200 text-emerald-700"