Skip to content

Key Factors Redesign 1st Iteration#4414

Open
ncarazon wants to merge 10 commits intomainfrom
feat/key-factors-new-iteration
Open

Key Factors Redesign 1st Iteration#4414
ncarazon wants to merge 10 commits intomainfrom
feat/key-factors-new-iteration

Conversation

@ncarazon
Copy link
Copy Markdown
Contributor

@ncarazon ncarazon commented Feb 23, 2026

This PR implements the 1st iteration of the Key Factors Redesign

Iteration 1: Unified Cards + Voting + Grid Layout

  • Unified card design with vertical impact bar (replacing the segmented progress bar)
  • Both forecaster and consumer views use the same card component
  • Voting redesign: upvote/downvote buttons with 2-step panels (strength selection for upvote, reason selection for downvote, plus a “more” menu, for now no be support)
  • Masonry grid layout (3 columns desktop, 2 mobile) replacing the vertical feed
  • This is the core visual overhaul – ships as one cohesive update
  • Collapse key factors by default on resolved questions, hide from feed tiles
image image image image image image image

Summary by CodeRabbit

  • New Features

    • Impact-direction voting with strength selection and a vertical impact indicator.
    • New vote panels (impact, downvote, more) with optimistic voting and downvote reasons.
    • Floating "More" panel offering view/report/dispute/delete actions.
    • Visible creation timestamps on key factors.
  • Internationalization

    • Added new UI translations: viewComment, createdTimeAgo[By], direction, voteOnImpact, why, wrongDirection, redundant, thanksForVoting.
  • UI/UX

    • Updated key-factor layouts, compact views, placeholders, and thumb-vote styling.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds KeyFactor.created_at serialization and new i18n keys; introduces deterministic sorting and many front-end changes: optimistic voting hooks/panels, PanelContainer/VotePanel/MorePanel, VerticalImpactBar, KeyFactorStrengthItem composition, API-backed optimistic voting flow, prop/type adjustments, and removal of several legacy components.

Changes

Cohort / File(s) Summary
Backend & Types
comments/serializers/key_factors.py, front_end/src/types/comment.ts, front_end/src/utils/key_factors.ts
Serialize created_at; add ImpactDirection type and getImpactDirectionFromMetadata utility.
Localization
front_end/messages/en.json, front_end/messages/cs.json, front_end/messages/es.json, front_end/messages/pt.json, front_end/messages/zh.json, front_end/messages/zh-TW.json
Add nine i18n keys for comments, timestamps, direction, voting, and voting reasons.
Feed / provider / sorting
Feed & provider
front_end/src/app/(main)/components/.../comments_feed_provider.tsx, front_end/src/app/(main)/questions/[id]/components/key_factors/key_factors_feed.tsx, front_end/src/app/(main)/questions/[id]/components/key_factors/key_factors_question_consumer_section.tsx, front_end/src/app/(main)/questions/[id]/components/key_factors/key_factors_comment_section.tsx, front_end/src/components/comment_feed/comment_card.tsx
Deterministic sort (score then id); derive keyFactors from feed; adjust carousel gap and item props (linkToComment, className).
Voting infra & panels
.../use_vote_panel.ts, .../use_optimistic_vote.ts, .../panel_container.tsx, .../vote_panel.tsx, .../key_factor_vote_panels.tsx, .../more_panel.tsx
Add panel management hook, optimistic-vote hook, PanelContainer portal, generic VotePanel, composed KeyFactorVotePanels, and MorePanel action panel.
Optimistic vote usage
.../question_link_agree_voter.tsx, .../question_link_key_factor_item.tsx, .../question_link_key_factor_item.tsx
Switch agree-voter flows to useOptimisticVote/useVotePanel; add submitting state, userVote management, panel toggle callbacks, and strength/impactDirection derivation.
Strength wrapper & composition
.../item_view/key_factor_strength_item.tsx, .../item_view/key_factor_vote_panels.tsx, .../item_view/key_factor_card_container.tsx, .../item_view/driver/key_factor_driver.tsx
Introduce KeyFactorStrengthItem (integrated voting wrapper), pass impactDirection/impactStrength to card container, and simplify driver props.
Impact visualization
.../item_view/vertical_impact_bar.tsx
Add VerticalImpactBar component rendering directional arrows and strength fill.
Base-rate & UI adjustments
.../base_rate/key_factor_base_rate.tsx, .../base_rate/key_factor_base_rate_frequency.tsx, .../base_rate/key_factor_base_rate_trend.tsx
Wrap base-rate with KeyFactorStrengthItem, add hideBoxes to frequency, and adjust trend markup/layout.
Voter/button/scale changes
.../item_view/key_factor_strength_voter.tsx, .../item_view/thumb_vote_buttons.tsx
Simplify StrengthScale API (count-only); remove labels from thumb buttons and update styling/colors.
New UI blocks & placeholders
.../key_factors_grid_placeholder.tsx, .../key_factors_consumer_carousel.tsx, .../key_factors_tile_view.tsx, .../key_factors_feed.tsx
Add grid placeholder, adjust carousel wrappers/widths, hide tile view for resolved posts, and refactor feed layout with add-modal flow.
LLM suggestions & fake key-factors
.../key_factors_add_in_comment_llm_suggestions.tsx
Centralize LINK_STRENGTH_MAP; add fallback created_at for fake KeyFactor objects and use translated "direction" label.
Removals (legacy)
.../base_rate/key_factor_direction_voter.tsx, .../dropdown_menu_items.tsx, .../segmented_progress_bar.tsx
Remove legacy voter, dropdown menu items, and segmented progress bar (functionality migrated into new components).
Helpers & small hooks
.../item_view/use_optimistic_vote.ts, .../item_view/vote_panel.tsx, front_end/src/utils/key_factors.ts
Introduce useOptimisticVote, generic VotePanel, and helper to derive impact direction.
Call-site signature updates
multiple files under front_end/src/app/(main)/questions/[id]/components/key_factors/... and .../question_layout, .../question_view
Prop/type updates across call sites: removal/addition of props (e.g., remove keyFactors prop, add impactDirection/impactStrength, remove keyFactorItemClassName), and hide key-factors for resolved posts.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as KeyFactor UI
    participant Panels as KeyFactorVotePanels
    participant Optim as useOptimisticVote
    participant API as Backend API
    participant Feed as Comments Feed

    User->>UI: click vote / open panel
    UI->>Panels: open specific panel (impact/downvote/more)
    User->>UI: select option & confirm
    UI->>Optim: setOptimistic(vote)
    Optim-->>UI: update local counts (optimistic)
    UI->>API: POST voteKeyFactor
    API-->>Feed: persist vote
    alt success
        Feed->>UI: aggregated update
        Optim->>UI: clearOptimistic -> render server counts
    else failure
        API-->>Optim: error
        Optim->>UI: clearOptimistic -> revert UI
    end
Loading
sequenceDiagram
    participant User
    participant Anchor as Card Anchor
    participant Panel as PanelContainer
    participant Parent as Card Parent

    User->>Anchor: click ellipsis / vote button
    Anchor->>Panel: provide anchorRef for positioning
    Panel->>Parent: onVotePanelToggle(true)
    Parent->>Parent: ensure exclusivity (close others)
    User->>Panel: click outside / close
    Panel->>Parent: onVotePanelToggle(false)
    Parent->>Panel: closePanel()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Possibly related PRs

Suggested reviewers

  • cemreinanc
  • hlbmtc
  • lsabor

Poem

🐰 I hopped in with a tiny cheer,

Arrows point up, down, or mildly unclear.
Panels pop open, I press with a paw,
Counts blink optimistic — then server says aw.
A rabbit applauds: key facts dance, hurrah!

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Key Factors Redesign 1st Iteration' directly summarizes the main changeset, which implements the first iteration of a Key Factors redesign with unified card design, voting system, and grid layout.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/key-factors-new-iteration

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 and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 23, 2026

🚀 Preview Environment

Your preview environment is ready!

Resource Details
🌐 Preview URL https://metaculus-pr-4414-feat-key-factors-new-iteration-preview.mtcl.cc
📦 Docker Image ghcr.io/metaculus/metaculus:feat-key-factors-new-iteration-0b0e30b
🗄️ PostgreSQL NeonDB branch preview/pr-4414-feat-key-factors-new-iteration
Redis Fly Redis mtc-redis-pr-4414-feat-key-factors-new-iteration

Details

  • Commit: 136de1be63eb2daa11d8a72fd1c11addccc86721
  • Branch: feat/key-factors-new-iteration
  • Fly App: metaculus-pr-4414-feat-key-factors-new-iteration

ℹ️ Preview Environment Info

Isolation:

  • PostgreSQL and Redis are fully isolated from production
  • Each PR gets its own database branch and Redis instance
  • Changes pushed to this PR will trigger a new deployment

Limitations:

  • Background workers and cron jobs are not deployed in preview environments
  • If you need to test background jobs, use Heroku staging environments

Cleanup:

  • This preview will be automatically destroyed when the PR is closed

@ncarazon ncarazon force-pushed the feat/key-factors-new-iteration branch from 597275c to 14580b4 Compare February 27, 2026 14:53
@ncarazon ncarazon force-pushed the feat/key-factors-new-iteration branch from 14580b4 to 9858b7a Compare February 27, 2026 14:54
@ncarazon ncarazon force-pushed the feat/key-factors-new-iteration branch from d6d2a0c to 629c70a Compare March 4, 2026 09:55
@ncarazon ncarazon changed the title Key Factors new iteration Key Factors Redesign 1st Iteration Mar 4, 2026
@ncarazon ncarazon force-pushed the feat/key-factors-new-iteration branch from 629c70a to 4aa477e Compare March 4, 2026 09:56
@ncarazon ncarazon marked this pull request as ready for review March 4, 2026 09:56
@ncarazon ncarazon marked this pull request as draft March 4, 2026 09:59
@ncarazon ncarazon marked this pull request as ready for review March 4, 2026 10:05
@cemreinanc
Copy link
Copy Markdown
Contributor

I think title of linked question shouldn't look like that (one word in every line). Can you please check with design?

CleanShot 2026-03-11 at 10 06 14@2x

Copy link
Copy Markdown
Contributor

@cemreinanc cemreinanc left a comment

Choose a reason for hiding this comment

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

Left couple of comments. LGTM otherwise.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why we didn't use a popover component instead of the custom portal/positioning, is it intentional? It would handle SSR, accessibility, click-outside, and positioning out of the box.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks! I'll try to refactor this, likely in the 2nd iteration PR.

}, []);

const toggleOption = useCallback((option: T) => {
setSelectedOption((prev) => (prev === option ? null : option));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

these selections looks like they don't have any impect besides ui state. Are we expecting it in upcoming iterations?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, for now it's only handled on the UI side. We’re planning to add backend support for it in upcoming iterations.

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