Skip to content

Fix: Show all subquestions in "Copy from" menu#4322

Open
SylvainChevalier wants to merge 3 commits intomainfrom
claude/issue-4260-20260206-0955
Open

Fix: Show all subquestions in "Copy from" menu#4322
SylvainChevalier wants to merge 3 commits intomainfrom
claude/issue-4260-20260206-0955

Conversation

@SylvainChevalier
Copy link
Contributor

@SylvainChevalier SylvainChevalier commented Feb 11, 2026

Previously, the "Copy from" dropdown only showed open subquestions because all three copy operations (Copy to all, Copy to, Copy from) were using the same filtered list of openOptions.

This fix adds a separate copyFromOptions prop to ForecastMakerGroupCopyMenu that receives all options (open, closed, and resolved), while maintaining the existing behavior for "Copy to" and "Copy to all" operations.

Fixes #4260

Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Expanded the range of forecasts available for copying to include previously unavailable options.
    • Added visual indicators to show which forecasts cannot be copied to, based on question status.

Previously, the "Copy from" dropdown only showed open subquestions
because all three copy operations (Copy to all, Copy to, Copy from)
were using the same filtered list of openOptions.

This fix adds a separate copyFromOptions prop to ForecastMakerGroupCopyMenu
that receives all options (open, closed, and resolved), while maintaining
the existing behavior for "Copy to" and "Copy to all" operations.

Fixes #4260

Co-authored-by: Sylvain <SylvainChevalier@users.noreply.github.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

Added a new optional prop copyFromOptions to enable copying from a broader set of questions in the copy menu. Updated the copy-from list to display all questions regardless of status while conditionally disabling interactions based on question closure state. Replaced Post import with QuestionStatus for status-based logic.

Changes

Cohort / File(s) Summary
Group Forecast Copy Menu Enhancement
front_end/src/components/forecast_maker/continuous_group_accordion/group_forecast_accordion.tsx, front_end/src/components/forecast_maker/forecast_maker_group/forecast_maker_group_copy_menu.tsx
Added copyFromOptions prop to pass full options array for broader source selection. Updated copy-from list to use new prop (fallback to options), replaced Post import with QuestionStatus, added per-item disabled state logic based on question status (CLOSED/RESOLVED), and conditionally enabled main menu based on canCopyFrom condition. Updated dependency array in memoization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • ncarazon
  • cemreinanc

Poem

🐰 A copy menu grows so grand,
All questions now can lend a hand,
Though closed ones dim, they show the way,
Let copying come out to play!
Status checks keep all in place,

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (133 files):

⚔️ .github/workflows/claude.yml (content)
⚔️ .github/workflows/pr_preview.yml (content)
⚔️ README.md (content)
⚔️ authentication/services.py (content)
⚔️ authentication/views/common.py (content)
⚔️ coherence/serializers.py (content)
⚔️ coherence/views.py (content)
⚔️ front_end/messages/cs.json (content)
⚔️ front_end/messages/en.json (content)
⚔️ front_end/messages/es.json (content)
⚔️ front_end/messages/pt.json (content)
⚔️ front_end/messages/zh-TW.json (content)
⚔️ front_end/messages/zh.json (content)
⚔️ front_end/next.config.mjs (content)
⚔️ front_end/package-lock.json (content)
⚔️ front_end/package.json (content)
⚔️ front_end/src/app/(main)/(home)/components/future_eval_table.tsx (content)
⚔️ front_end/src/app/(main)/(leaderboards)/leaderboard/components/project_leaderboard.tsx (content)
⚔️ front_end/src/app/(main)/(leaderboards)/leaderboard/components/project_leaderboard_client.tsx (content)
⚔️ front_end/src/app/(main)/(leaderboards)/leaderboard/components/project_leaderboard_table/index.tsx (content)
⚔️ front_end/src/app/(main)/(tournaments)/tournament/[slug]/page.tsx (content)
⚔️ front_end/src/app/(main)/(tournaments)/tournament/components/tournament_feed.tsx (content)
⚔️ front_end/src/app/(main)/(tournaments)/tournament/components/tournament_timeline.tsx (content)
⚔️ front_end/src/app/(main)/accounts/actions.ts (content)
⚔️ front_end/src/app/(main)/accounts/profile/components/social_media_section.tsx (content)
⚔️ front_end/src/app/(main)/accounts/profile/components/user_info.tsx (content)
⚔️ front_end/src/app/(main)/accounts/reset/actions.ts (content)
⚔️ front_end/src/app/(main)/accounts/reset/components/password_reset.tsx (content)
⚔️ front_end/src/app/(main)/accounts/reset/page.tsx (content)
⚔️ front_end/src/app/(main)/accounts/settings/(general)/page.tsx (content)
⚔️ front_end/src/app/(main)/accounts/settings/account/components/change_password.tsx (content)
⚔️ front_end/src/app/(main)/accounts/settings/account/components/email_edit.tsx (content)
⚔️ front_end/src/app/(main)/accounts/settings/account/page.tsx (content)
⚔️ front_end/src/app/(main)/accounts/settings/actions.tsx (content)
⚔️ front_end/src/app/(main)/accounts/settings/notifications/page.tsx (content)
⚔️ front_end/src/app/(main)/c/[slug]/page.tsx (content)
⚔️ front_end/src/app/(main)/components/bulletins.tsx (content)
⚔️ front_end/src/app/(main)/components/headers/components/create_question_button.tsx (content)
⚔️ front_end/src/app/(main)/components/headers/components/mobile_menu.tsx (content)
⚔️ front_end/src/app/(main)/components/headers/hooks/useNavbarLinks.tsx (content)
⚔️ front_end/src/app/(main)/questions/[id]/components/download_question_data_modal/aggregation_methods_picker.tsx (content)
⚔️ front_end/src/app/(main)/questions/[id]/components/key_factors/add_button.tsx (content)
⚔️ front_end/src/app/(main)/questions/[id]/components/key_factors/item_view/base_rate/key_factor_direction_voter.tsx (content)
⚔️ front_end/src/app/(main)/questions/[id]/components/key_factors/item_view/key_factor_strength_voter.tsx (content)
⚔️ front_end/src/app/(main)/questions/[id]/components/key_factors/item_view/question_link/question_link_agree_voter.tsx (content)
⚔️ front_end/src/app/(main)/questions/[id]/components/multiple_choices_chart_view/index.tsx (content)
⚔️ front_end/src/app/(main)/questions/[id]/components/question_view/consumer_question_view/action_buttons/question_predict_button.tsx (content)
⚔️ front_end/src/app/(main)/questions/[id]/components/question_view/consumer_question_view/index.tsx (content)
⚔️ front_end/src/app/(main)/questions/[id]/components/question_view/consumer_question_view/prediction/index.tsx (content)
⚔️ front_end/src/app/(main)/questions/components/coherence_links/coherence_links.tsx (content)
⚔️ front_end/src/app/(main)/questions/components/group_form.tsx (content)
⚔️ front_end/src/app/(main)/questions/components/question_form.tsx (content)
⚔️ front_end/src/app/(main)/questions/components/question_picker.tsx (content)
⚔️ front_end/src/app/(main)/questions/create/[content_type]/page.tsx (content)
⚔️ front_end/src/app/(main)/services/(pages)/financial-services/pro-forecasters/config.tsx (content)
⚔️ front_end/src/app/(main)/services/components/templates/private_instances_page_template.tsx (content)
⚔️ front_end/src/app/(main)/services/components/templates/pro_forecasters_page_template.tsx (content)
⚔️ front_end/src/app/(main)/services/components/templates/services_page_template.tsx (content)
⚔️ front_end/src/app/(main)/services/components/templates/tournaments_page_template.tsx (content)
⚔️ front_end/src/app/(main)/services/page.tsx (content)
⚔️ front_end/src/app/globals.css (content)
⚔️ front_end/src/components/auth/signin.tsx (content)
⚔️ front_end/src/components/charts/numeric_chart.tsx (content)
⚔️ front_end/src/components/comment_feed/comment.tsx (content)
⚔️ front_end/src/components/comment_feed/comment_voter.tsx (content)
⚔️ front_end/src/components/comment_feed/index.tsx (content)
⚔️ front_end/src/components/consumer_post_card/group_forecast_card/percentage_forecast_card.tsx (content)
⚔️ front_end/src/components/detailed_question_card/detailed_question_card/continuous_chart_card.tsx (content)
⚔️ front_end/src/components/forecast_maker/continuous_group_accordion/group_forecast_accordion.tsx (content)
⚔️ front_end/src/components/forecast_maker/forecast_maker_group/forecast_maker_group_continuous.tsx (content)
⚔️ front_end/src/components/forecast_maker/forecast_maker_group/forecast_maker_group_copy_menu.tsx (content)
⚔️ front_end/src/components/forecast_maker/forecast_maker_question/forecast_maker_multiple_choice.tsx (content)
⚔️ front_end/src/components/forecast_maker/index.tsx (content)
⚔️ front_end/src/components/forecast_maker/predict_button.tsx (content)
⚔️ front_end/src/components/gradient-carousel.tsx (content)
⚔️ front_end/src/components/post_card/basic_post_card/post_voter.tsx (content)
⚔️ front_end/src/components/post_card/group_of_questions_tile/index.tsx (content)
⚔️ front_end/src/components/post_card/index.tsx (content)
⚔️ front_end/src/components/sliders/multi_slider.tsx (content)
⚔️ front_end/src/components/sliders/primitives/thumb.tsx (content)
⚔️ front_end/src/components/theme_toggle.tsx (content)
⚔️ front_end/src/constants/colors.ts (content)
⚔️ front_end/src/hooks/share.ts (content)
⚔️ front_end/src/sentry/options.ts (content)
⚔️ front_end/src/services/api/leaderboard/leaderboard.shared.ts (content)
⚔️ front_end/src/services/api/profile/profile.server.ts (content)
⚔️ front_end/src/types/question.ts (content)
⚔️ front_end/src/types/scoring.ts (content)
⚔️ front_end/src/types/users.ts (content)
⚔️ front_end/src/utils/fonts.ts (content)
⚔️ front_end/src/utils/navigation.ts (content)
⚔️ front_end/src/utils/questions/predictions.ts (content)
⚔️ front_end/tailwind.config.ts (content)
⚔️ metaculus_web/settings.py (content)
⚔️ misc/management/commands/cron.py (content)
⚔️ notifications/templates/emails/multiple_choice_option_addition.html (content)
⚔️ notifications/templates/emails/multiple_choice_option_addition.mjml (content)
⚔️ notifications/templates/emails/multiple_choice_option_deletion.html (content)
⚔️ notifications/templates/emails/multiple_choice_option_deletion.mjml (content)
⚔️ poetry.lock (content)
⚔️ posts/services/subscriptions.py (content)
⚔️ pyproject.toml (content)
⚔️ questions/admin.py (content)
⚔️ questions/models.py (content)
⚔️ questions/serializers/common.py (content)
⚔️ questions/tasks.py (content)
⚔️ scoring/admin.py (content)
⚔️ scoring/jobs.py (content)
⚔️ scoring/management/commands/update_coherence_tournament_leaderboard.py (content)
⚔️ scoring/management/commands/update_global_bot_leaderboard.py (content)
⚔️ scoring/migrations/0006_alter_leaderboardentry_excluded_and_more.py (content)
⚔️ scoring/migrations/0018_leaderboardentry_ci_lower_leaderboardentry_ci_upper.py (content)
⚔️ scoring/models.py (content)
⚔️ scoring/score_math.py (content)
⚔️ scoring/tasks.py (content)
⚔️ scoring/urls.py (content)
⚔️ scoring/utils.py (content)
⚔️ scoring/views.py (content)
⚔️ screenshot/poetry.lock (content)
⚔️ tests/unit/test_auth/test_services.py (content)
⚔️ tests/unit/test_scoring/test_utils.py (content)
⚔️ users/models.py (content)
⚔️ users/serializers.py (content)
⚔️ users/services/common.py (content)
⚔️ users/services/profile_stats.py (content)
⚔️ users/urls.py (content)
⚔️ users/views.py (content)
⚔️ utils/cache.py (content)
⚔️ utils/csv_utils.py (content)
⚔️ utils/serializers.py (content)
⚔️ utils/tasks.py (content)
⚔️ utils/the_math/aggregations.py (content)
⚔️ utils/views.py (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: enabling all subquestions (open, closed, resolved) to appear in the 'Copy from' menu, which is the primary objective of this PR.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #4260: 'Copy from' now shows all questions by using a separate copyFromOptions prop, while 'Copy to' and 'Copy to all' behavior is preserved.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #4260: adding copyFromOptions prop, disabling 'Copy from' for closed/resolved subquestions, and adjusting 'Copy to' enablement based on user forecast status.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/issue-4260-20260206-0955
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch claude/issue-4260-20260206-0955
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
front_end/src/components/forecast_maker/forecast_maker_group/forecast_maker_group_copy_menu.tsx (1)

78-78: Misleading variable name: canCopyFrom actually gates "Copy to" actions.

canCopyFrom is used to enable/disable "Copy to all" and "Copy to" (lines 86, 102), which copy from the current option to others. The name reads as though it controls whether the user can copy from other options. Consider renaming to hasForecastToCopy or canCopyToOthers to match the intent.

✏️ Suggested rename
-  const canCopyFrom = option.hasUserForecast || option.wasWithdrawn;
+  const canCopyToOthers = option.hasUserForecast || option.wasWithdrawn;

And update references on lines 86 and 102 accordingly.

front_end/src/components/forecast_maker/continuous_group_accordion/group_forecast_accordion.tsx (1)

243-255: Consider whether the copy menu should be shown for closed subquestions at all.

For closed subquestions, the copy menu is rendered whenever openOptions.length > 0. A user on a closed subquestion with a prior forecast (hasUserForecast) will see "Copy to all" / "Copy to" enabled, which allows copying the old forecast to open questions — this seems intentional and useful.

However, "Copy from" is also enabled here, letting the user attempt to copy an open question's forecast into a closed subquestion. Since canPredict is false for closed questions, the copied values can't be submitted, which could confuse users. If the intent (per the PR author's comment) is to disable "Copy from" entirely on closed/resolved subquestions, that logic should live in the menu component based on the current option's status.


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
Contributor

github-actions bot commented Feb 11, 2026

🚀 Preview Environment

Your preview environment is ready!

Resource Details
🌐 Preview URL https://metaculus-pr-4322-claude-issue-4260-20260206-095-preview.mtcl.cc
📦 Docker Image ghcr.io/metaculus/metaculus:claude-issue-4260-20260206-0955-9aef6c0
🗄️ PostgreSQL NeonDB branch preview/pr-4322-claude-issue-4260-20260206-095
Redis Fly Redis mtc-redis-pr-4322-claude-issue-4260-20260206-095

Details

  • Commit: e0728f4ef8765e18982e3e2e36c5950986b2345a
  • Branch: claude/issue-4260-20260206-0955
  • Fly App: metaculus-pr-4322-claude-issue-4260-20260206-095

ℹ️ 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

@SylvainChevalier
Copy link
Contributor Author

SylvainChevalier commented Feb 12, 2026

@claude

"copy from" should be completely disabled on closed and resolved subquestions.

"copy to" should be disabled when the user doesn't have a prediction. it should still be enabled when the user had a prediction but withdrew.

@claude
Copy link

claude bot commented Feb 12, 2026

Claude finished @SylvainChevalier's task in 3m 28s —— View job


Implemented "Copy from" and "Copy to" menu behavior changes

  • Gather context: Read relevant component files
  • Understand how predictions, withdrawals, and question states work
  • Disable "Copy from" items for closed/resolved subquestions
  • Disable "Copy to" and "Copy to all" when user has no prediction (keep enabled for withdrawn)
  • Commit and push changes

Summary

Pushed commit df980bf to claude/issue-4260-20260206-0955 with the following changes to forecast_maker_group_copy_menu.tsx:

  1. "Copy from" submenu: Items for closed/resolved subquestions are now disabled — greyed out with opacity-50, cursor-not-allowed, and the disabled HTML attribute. They still appear in the list but cannot be clicked.

  2. "Copy to all" and "Copy to" in main menu: Disabled when the current subquestion has no user forecast and wasn't withdrawn (!hasUserForecast && !wasWithdrawn). When disabled, they render as greyed-out, non-interactive buttons. When the user had a prediction but withdrew it, these options remain enabled since the forecast data is still available to copy.

  3. Cleanup: Removed unused Post import and post prop from the component's Props type (it was already optional and never passed by the parent).
    | Branch

- Disable Copy from items for closed and resolved subquestions

- Disable Copy to and Copy to all when user has no prediction

- Keep Copy to enabled when user had a prediction but withdrew

Co-authored-by: Sylvain <SylvainChevalier@users.noreply.github.com>
@SylvainChevalier
Copy link
Contributor Author

@claude fix unit tests issues.

@claude
Copy link

claude bot commented Feb 12, 2026

Claude finished @SylvainChevalier's task in 4m 0s —— View job


Fixed Prettier formatting issue

  • Gather context: Read CI logs and identify failing checks
  • Fix Prettier formatting issue in forecast_maker_group_copy_menu.tsx
  • Commit and push changes

Summary

The CI failure was a Prettier formatting issue (not a unit test failure). The canCopyFrom variable declaration was unnecessarily split across two lines:

-  const canCopyFrom =
-    option.hasUserForecast || option.wasWithdrawn;
+  const canCopyFrom = option.hasUserForecast || option.wasWithdrawn;

Pushed commit 9aef6c0 with the fix.

| View job | Branch

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.

Copying distribution to and from closed subquestions bugs

1 participant