Skip to content

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

Merged
cemreinanc merged 5 commits intomainfrom
claude/issue-4260-20260206-0955
Mar 14, 2026
Merged

Fix: Show all subquestions in "Copy from" menu#4322
cemreinanc merged 5 commits intomainfrom
claude/issue-4260-20260206-0955

Conversation

@SylvainChevalier
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
Contributor

github-actions Bot commented Feb 11, 2026

Cleanup: Preview Environment Removed

The preview environment for this PR has been destroyed.

Resource Status
🌐 Preview App Deleted
🗄️ PostgreSQL Branch Deleted
⚡ Redis Database Deleted
🔧 GitHub Deployments Removed
📦 Docker Image Retained (auto-cleanup via GHCR policies)

Cleanup triggered by PR close at 2026-03-14T20:03:33Z

@SylvainChevalier
Copy link
Copy Markdown
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
Copy Markdown
Contributor

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
Copy Markdown
Contributor Author

@claude fix unit tests issues.

@claude
Copy link
Copy Markdown
Contributor

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

@SylvainChevalier SylvainChevalier marked this pull request as ready for review February 13, 2026 16:30
Copy link
Copy Markdown
Contributor

@ncarazon ncarazon left a comment

Choose a reason for hiding this comment

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

LGTM, seen your comment to claude about disabling for closed/resolved

@cemreinanc cemreinanc merged commit 68998d8 into main Mar 14, 2026
14 checks passed
@cemreinanc cemreinanc deleted the claude/issue-4260-20260206-0955 branch March 14, 2026 20:03
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

3 participants