Skip to content

fix(opportunities): disable 'Plan from X selected' on heterogeneous selection - #777

Merged
cristim merged 2 commits into
feat/multicloud-web-frontendfrom
fix/769-plan-button-heterogeneous
May 28, 2026
Merged

fix(opportunities): disable 'Plan from X selected' on heterogeneous selection#777
cristim merged 2 commits into
feat/multicloud-web-frontendfrom
fix/769-plan-button-heterogeneous

Conversation

@cristim

@cristim cristim commented May 27, 2026

Copy link
Copy Markdown
Member

Summary

QA 6.2: the "Plan from X selected" button was always clickable even when the selection spanned multiple providers / services / terms / payment options. A single plan can only represent one of each, so the modal couldn't actually act on heterogeneous selections.

Fix

  • Added exported isHomogeneousSelection(recs) helper that returns true when all items share the same provider / service / term / payment.
  • updateBottomActionBox gates the plan button on hasSelection && planHomogeneous.
  • Hint span surfaces either the no-selection message or the heterogeneous explanation: "Plans require one provider, service, term, and payment. Refine your selection."
  • The Purchase button is unaffected (it can act on heterogeneous selections).

Files changed

  • frontend/src/recommendations.ts
  • frontend/src/__tests__/recommendations.test.ts

Test plan

  • DOM-level test: heterogeneous term=1 vs term=3 fixture -> plan button disabled, purchase still enabled, hint visible.
  • 7 unit tests for isHomogeneousSelection: each of 4 axes individually, plus homogeneous, single-row, empty-slice.
  • 318 / 318 tests pass.

Closes #769.

Summary by CodeRabbit

  • Bug Fixes

    • Plan action button is now properly disabled when selected recommendations have mismatched attributes (provider, service, term, or payment).
    • Added explanatory message when the plan button is disabled due to incompatible selections.
  • Tests

    • Added comprehensive test coverage for selection homogeneity validation.

Review Change Stack

…election (closes #769)

Plans require a uniform provider/service/term/payment combination.
Add isHomogeneousSelection() helper that checks all four axes; gate the
"Plan from N selected" button on the result. The Purchase button is
unaffected. The existing a11y hint span surfaces the explanation when
the selection is heterogeneous. Eight new tests cover all four axes,
the single-row pass-through, and the DOM-level button/hint state.
@cristim cristim added triaged Item has been triaged priority/p2 Backlog-worthy severity/medium Moderate harm urgency/this-sprint Within the current sprint impact/many Affects most users effort/s Hours type/bug Defect labels May 27, 2026
@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@cristim, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 13 minutes and 53 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 012e1201-2b29-470f-9687-ebbc9a717229

📥 Commits

Reviewing files that changed from the base of the PR and between 13adeb7 and ccc8081.

📒 Files selected for processing (2)
  • frontend/src/__tests__/recommendations.test.ts
  • frontend/src/recommendations.ts
📝 Walkthrough

Walkthrough

This PR implements issue #769: the "Create Plan" button now disables when selected recommendations are heterogeneous (span multiple providers, services, terms, or payment options). A new isHomogeneousSelection helper detects homogeneity, the action box uses it to gate the button state, and tests verify both the helper logic and resulting UI behavior.

Changes

Heterogeneous Selection Gating for Plan Button

Layer / File(s) Summary
Homogeneity detection helper
frontend/src/recommendations.ts, frontend/src/__tests__/recommendations.test.ts
Exported isHomogeneousSelection function returns true for empty/singleton recommendation slices and checks that all items match the first one's (provider, service, term, payment) tuple. Unit tests cover homogeneity across empty, single-item, and heterogeneous provider/service/term/payment axes.
Plan button gating on heterogeneous selection
frontend/src/recommendations.ts, frontend/src/__tests__/recommendations.test.ts
Action box computes whether selected-visible recommendations are homogeneous. "Create Plan" button disables when hasSelection is true but planHomogeneous is false. Accessibility hint shows heterogeneous-selection constraint ("Plans require one provider/service/term/payment") when appropriate. UI regression test asserts button disable and hint appear for heterogeneous selection while "Purchase" button remains enabled.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • LeanerCloud/CUDly#275: Modifies the same recommendations action-box logic and tests to gate Plan/Purchase button states based on selection criteria.

Poem

🐰 When choices spread too wide and far,
Across providers, terms, and stars,
One plan cannot hold them all—
So down the button's forced to fall.
But pick one slice, and watch it shine,
The Plan awaits your homogeneous line! 🎯

🚥 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 describes the main change: disabling the 'Plan from X selected' button when recommendations are heterogeneous across provider/service/term/payment axes.
Linked Issues check ✅ Passed The PR fully implements all coding requirements from issue #769: exported isHomogeneousSelection helper, plan button gating logic, disabled-state hint message, and comprehensive unit and regression tests covering all heterogeneous axes.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #769: the helper function, button-gating logic, hint message updates, and related tests are all necessary to fix the heterogeneous selection bug.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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 fix/769-plan-button-heterogeneous

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

@cristim

cristim commented May 27, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim

cristim commented May 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 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 `@frontend/src/__tests__/recommendations.test.ts`:
- Around line 6426-6442: The test helper makeRec uses non-canonical underscore
payment tokens (overrides.payment defaulting to 'all_upfront' and elsewhere
'no_upfront'); update these defaults and any hardcoded test values in the new
homogeneity tests to use the canonical hyphenated tokens ('all-upfront' and
'no-upfront') so test fixtures match real app payloads—locate the makeRec
function and other occurrences around the referenced blocks (e.g., where
overrides.payment is set) and replace underscore variants with the hyphenated
tokens.

In `@frontend/src/recommendations.ts`:
- Around line 3159-3167: The heterogeneous-plan hint is currently gated by
existence (planBtn != null) which still holds when the plan button is hidden;
update the guard so heterogeneousPlanBlock uses visibility instead: check that
planBtn exists and is visible (e.g., planBtn && !planBtn.hidden) when computing
heterogeneousPlanBlock (alongside hasSelection and !planHomogeneous), so the
disabledHint text about plans only appears for users who can actually see/use
the plan button; leave the rest of the logic for disabledHint, disabledMessage,
and planHomogeneous unchanged.
🪄 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: f36239f3-07d6-43dd-b979-3eff7dee189d

📥 Commits

Reviewing files that changed from the base of the PR and between d986b4d and 13adeb7.

📒 Files selected for processing (2)
  • frontend/src/__tests__/recommendations.test.ts
  • frontend/src/recommendations.ts

Comment thread frontend/src/__tests__/recommendations.test.ts
Comment thread frontend/src/recommendations.ts Outdated
…an hint on button visibility

Replace underscore payment tokens (`all_upfront`, `no_upfront`) with the
canonical hyphenated form (`all-upfront`, `no-upfront`) in the `makeRec`
test helper default and the heterogeneous-payment fixture so test payloads
match real app payloads.

Tighten the `heterogeneousPlanBlock` guard in recommendations.ts to
`planBtn != null && !planBtn.hidden` so the heterogeneous-selection hint
only surfaces when the plan button is actually visible (not merely present
in the DOM for users who lack the `create:plans` permission).
@cristim

cristim commented May 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/s Hours impact/many Affects most users priority/p2 Backlog-worthy severity/medium Moderate harm triaged Item has been triaged type/bug Defect urgency/this-sprint Within the current sprint

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant