Skip to content

fix(team-view): member popup links to the IC page; Expand details opens the full-metric sheet - #198

Merged
mitasovr merged 1 commit into
mainfrom
fix/1729-heatmap-full-columns
Jul 15, 2026
Merged

fix(team-view): member popup links to the IC page; Expand details opens the full-metric sheet#198
mitasovr merged 1 commit into
mainfrom
fix/1729-heatmap-full-columns

Conversation

@mitasovr

@mitasovr mitasovr commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Problem

Follow-up to #193 / constructorfabric/insight#1729. In the Members × metrics member popup:

  • "Open in IC view" opened the details sheet instead of navigating anywhere, and
  • "Expand details" toggled an inline bullet strip under the row — a third, redundant surface for the same data.

(The first iteration of this PR grew the grid to the full column set; reverted per review — the table keeps its curated 7 columns, the full metric set lives in the details sheet from #193.)

Change

  • "Open in IC view" is now a router <Link> to the member's personal IC page (/ic/$person/personal), styled via the Button render prop.
  • "Expand details" opens the details sheet (full metric set: grid cells + remaining legacy bullets + unified git/ai entries).
  • The inline ExpandedBullets strip, its expansion state, and the now-unused MemberRow plumbing are removed.

Verification

Verified in the browser against the mock stack: the grid renders its usual 7 columns; the popup's "Open in IC view" navigates SPA-style to the member's personal dashboard; "Expand details" opens the sheet with the member's full metric set (60 rows on the mock roster).

Typecheck, ESLint, and the full vitest suite pass; the component test now asserts the link href and opens the sheet through "Expand details".

Related to constructorfabric/insight#1729

🤖 Generated with Claude Code

…c set

The heatmap rendered only the 7 curated columns, so the on-page table
still hid most of a member's metrics after the details-sheet fix
(issue #1729). Columns are now derived at render time: the curated core
first, then a column for every legacy bullet and unified-path (git/ai)
entry present in the roster's data, deduped by metric key and label.
Bullet columns color against the member's department cohort as before;
unified columns reuse the entry's own-cohort status and format their
values through formatMetricValue. Word units gain a separating space.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Roman Mitasov <roman.mitasov@constructor.tech>
@mitasovr
mitasovr requested a review from a team as a code owner July 14, 2026 13:19
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Members heatmap metric expansion

Layer / File(s) Summary
Dynamic metric column model
src/components/widgets/v2/members-heatmap/index.tsx
Replaces the fixed column list with curated, roster-derived, and unified metric columns, including deduplication and formatting metadata.
Metric cells and member sheet
src/components/widgets/v2/members-heatmap/index.tsx
Builds dynamic metric cells and full member detail rows with formatted values, medians, units, and deduplication.
Grid rendering and behavior validation
src/components/widgets/v2/members-heatmap/index.tsx, src/components/widgets/v2/members-heatmap/index.test.tsx
Updates sorting, grid sizing, headers, tooltip formatting, and tests for dynamic columns and collision handling.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RosterData
  participant MembersHeatmap
  participant MemberDetailsSheet
  RosterData->>MembersHeatmap: provide roster bullets and unified metric entries
  MembersHeatmap->>MembersHeatmap: build deduplicated dynamic columns
  MembersHeatmap->>MemberDetailsSheet: provide full formatted metric set
  MemberDetailsSheet-->>MembersHeatmap: render member metric details
Loading

Possibly related PRs

Suggested reviewers: cyberantonz

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: expanding the Members × metrics grid to the full metric set.
Linked Issues check ✅ Passed The dynamic columns and rewritten details sheet address the fixed-7-metric bug in #1729 while keeping unfetched wiki metrics out of scope.
Out of Scope Changes check ✅ Passed The changes stay focused on the Members × metrics grid and its tests, with no obvious unrelated functionality added.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1729-heatmap-full-columns

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed due to a network error.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/components/widgets/v2/members-heatmap/index.test.tsx (1)

271-347: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Good coverage for the core dedup scenario; consider extending to sheet/tooltip formatting.

This test solidly verifies column creation and the two documented dedup cases (exact-key bullet collision, dot-suffix unified collision). It doesn't yet cover the newly added MemberDetailsSheet row formatting (display/medianDisplay via formatMetricValue) or the unitSuffix word-unit spacing path (e.g. "meetings", "files") described in the source comments — both are new, non-trivial formatting branches introduced in this PR.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/widgets/v2/members-heatmap/index.test.tsx` around lines 271 -
347, Extend the heatmap test around MembersHeatmap to verify MemberDetailsSheet
row formatting through formatMetricValue, including display and medianDisplay
values and word-based unitSuffix spacing such as “meetings” or “files.” Assert
the rendered sheet/tooltip text for these branches while preserving the existing
deduplication and column assertions.
src/components/widgets/v2/members-heatmap/index.tsx (1)

518-580: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

LGTM overall — sheet rows correctly thread format through formatMetricValue and dedupe against the dynamic column set.

Minor nit: the local const unitSuffix = b.unit ? \ ${b.unit}` : ""at line 549 shadows the module-levelunitSuffix()helper (lines 200-209) with different spacing semantics (always spaces vs. compact single-char units). Since thisfromBulletsbranch appears effectively unreachable now (every bullet'smetric_key` should already be covered by a dynamic column), it's low priority, but renaming would avoid confusing a future reader who expects the shared helper's behavior here too.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/widgets/v2/members-heatmap/index.tsx` around lines 518 - 580,
Rename the local unit-suffix string inside the fromBullets mapping in sheetRows
so it no longer shadows the module-level unitSuffix() helper. Update its use in
the bullet display and medianDisplay fields while preserving the existing
spacing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/widgets/v2/members-heatmap/index.tsx`:
- Around line 320-371: Limit label-based deduplication in the columns useMemo to
labels from CORE_COLUMNS only. Keep metric-key deduplication for dynamic bullets
and metrics, but stop adding dynamic labels to seenLabels so unrelated later
metrics with the same display label are retained in the grid and details sheet.

---

Nitpick comments:
In `@src/components/widgets/v2/members-heatmap/index.test.tsx`:
- Around line 271-347: Extend the heatmap test around MembersHeatmap to verify
MemberDetailsSheet row formatting through formatMetricValue, including display
and medianDisplay values and word-based unitSuffix spacing such as “meetings” or
“files.” Assert the rendered sheet/tooltip text for these branches while
preserving the existing deduplication and column assertions.

In `@src/components/widgets/v2/members-heatmap/index.tsx`:
- Around line 518-580: Rename the local unit-suffix string inside the
fromBullets mapping in sheetRows so it no longer shadows the module-level
unitSuffix() helper. Update its use in the bullet display and medianDisplay
fields while preserving the existing spacing behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5b58d8d4-ef79-4624-9f44-ac485efb197d

📥 Commits

Reviewing files that changed from the base of the PR and between 54395b2 and 3f1f868.

📒 Files selected for processing (2)
  • src/components/widgets/v2/members-heatmap/index.test.tsx
  • src/components/widgets/v2/members-heatmap/index.tsx

Comment on lines +320 to +371
const columns = useMemo(() => {
const cols: ColumnDef[] = [...CORE_COLUMNS];
const seenKeys = new Set(cols.map(metricKeyForColumn));
const seenLabels = new Set(cols.map((c) => c.label.toLowerCase()));
for (const m of members) {
const bullets = bulletsByPerson?.get(m.person_id.toLowerCase()) ?? [];
for (const b of bullets) {
if (seenKeys.has(b.metric_key)) continue;
seenKeys.add(b.metric_key);
seenLabels.add(b.label.toLowerCase());
cols.push({
key: b.metric_key,
label: b.label,
short: b.label,
unit: b.unit ?? "",
higher_is_better:
byMetricKey(bulletCatalogKey(b))?.higher_is_better ?? true,
mobile: false,
source: "bullet",
metricKey: b.metric_key,
});
}
}
for (const m of members) {
const entries =
metricEntriesByPerson?.get(m.person_id.toLowerCase()) ?? [];
for (const e of entries) {
const suffix = e.key.split(".").pop() ?? e.key;
if (
seenKeys.has(e.key) ||
seenKeys.has(suffix) ||
seenLabels.has(e.label.toLowerCase())
) {
continue;
}
seenKeys.add(e.key);
seenLabels.add(e.label.toLowerCase());
cols.push({
key: e.key,
label: e.label,
short: e.label,
unit: e.unit ?? "",
higher_is_better: e.higherIsBetter,
mobile: false,
source: "metric",
entryKey: e.key,
format: e.format,
});
}
}
return cols;
}, [members, bulletsByPerson, metricEntriesByPerson, byMetricKey]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the target file and nearby symbols first.
ast-grep outline src/components/widgets/v2/members-heatmap/index.tsx --view expanded || true

# Read the relevant section with line numbers.
sed -n '1,260p' src/components/widgets/v2/members-heatmap/index.tsx | cat -n

echo '---'
sed -n '260,430p' src/components/widgets/v2/members-heatmap/index.tsx | cat -n

echo '---'
# Search for related symbols and any other label/key dedupe logic.
rg -n "seenLabels|seenKeys|CORE_COLUMNS|metricKeyForColumn|bulletCatalogKey|higherIsBetter|metricEntriesByPerson|bulletsByPerson" src/components/widgets/v2/members-heatmap/index.tsx

Repository: constructorfabric/insight-front

Length of output: 21274


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the source types first.
rg -n "interface BulletMetric|type BulletMetric|interface PeerStoryEntry|type PeerStoryEntry" src

# Read the relevant type definitions if found.
files=$(rg -l "interface BulletMetric|type BulletMetric|interface PeerStoryEntry|type PeerStoryEntry" src | head -n 20)
for f in $files; do
  echo "--- $f"
  sed -n '1,260p' "$f" | cat -n
done

Repository: constructorfabric/insight-front

Length of output: 45676


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for places where metric labels are defined or compared in a way that assumes global uniqueness.
rg -n --glob '!**/*.snap' --glob '!**/node_modules/**' \
  "label\s*:" src/lib src/components src/types | head -n 200

echo '---'
rg -n --glob '!**/*.snap' --glob '!**/node_modules/**' \
  "toLowerCase\(\)\).*label|label.*toLowerCase\(\)|seenLabels|duplicate label|same label" src

Repository: constructorfabric/insight-front

Length of output: 14886


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the later column consumers around the member-details sheet.
sed -n '480,590p' src/components/widgets/v2/members-heatmap/index.tsx | cat -n

echo '---'
# Inspect the relevant members heatmap tests for duplicate-label scenarios.
sed -n '1,460p' src/components/widgets/v2/members-heatmap/index.test.tsx | cat -n

Repository: constructorfabric/insight-front

Length of output: 22093


Scope label dedupe to the curated columns
seenLabels grows with every bullet/metric added, so a later dynamic metric that shares a display label with an earlier unrelated one is dropped from the grid and then filtered out of the details sheet too. Anchor the label check to CORE_COLUMNS (or another fixed set) so only curated-vs-dynamic collisions are suppressed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/widgets/v2/members-heatmap/index.tsx` around lines 320 - 371,
Limit label-based deduplication in the columns useMemo to labels from
CORE_COLUMNS only. Keep metric-key deduplication for dynamic bullets and
metrics, but stop adding dynamic labels to seenLabels so unrelated later metrics
with the same display label are retained in the grid and details sheet.

@mitasovr
mitasovr requested a review from aleksdotbar July 14, 2026 14:39
@mitasovr
mitasovr merged commit 1a44492 into main Jul 15, 2026
6 checks passed
mitasovr pushed a commit that referenced this pull request Jul 15, 2026
…from Expand details

In the Members × metrics popup, "Open in IC view" opened the details
sheet while "Expand details" toggled an inline bullet strip under the
row. Rework per review of #198: "Open in IC view" is now a router link
to the member's personal IC page, and "Expand details" opens the
details sheet (which already shows the full metric set after #193).
The inline ExpandedBullets strip and its expansion state go away.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Roman Mitasov <roman.mitasov@constructor.tech>
@mitasovr mitasovr changed the title fix(team-view): grow Members × metrics grid columns to the full metric set fix(team-view): member popup links to the IC page; Expand details opens the full-metric sheet Jul 15, 2026
mitasovr added a commit that referenced this pull request Jul 15, 2026
…he IC page (#200)

* Revert "fix(team-view): grow Members × metrics grid columns to the full metric set (#198)"

This reverts commit 1a44492.

Signed-off-by: Roman Mitasov <roman.mitasov@constructor.tech>

* fix(team-view): link the member popup to the IC page, open the sheet from Expand details

In the Members × metrics popup, "Open in IC view" opened the details
sheet while "Expand details" toggled an inline bullet strip under the
row. Rework per review of #198: "Open in IC view" is now a router link
to the member's personal IC page, and "Expand details" opens the
details sheet (which already shows the full metric set after #193).
The inline ExpandedBullets strip and its expansion state go away.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Roman Mitasov <roman.mitasov@constructor.tech>

---------

Signed-off-by: Roman Mitasov <roman.mitasov@constructor.tech>
Co-authored-by: Roman Mitasov <roman.mitasov@constructor.tech>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants