Repository navigation
fix(frontend): show the monthly charge and term total before purchase - #1364
Conversation
…se screen The bulk Review Purchase modal only stated "Total upfront", which reads $0 for no-upfront and partial-upfront buckets that bill monthly for one or three years. Its confirm dialog stated no amounts at all, the Execute Now warning said "charge $0.00 upfront" for a monthly-billed purchase, and the approval dialog showed the upfront and the savings but not the monthly cost, so an approver could not judge the commitment. commitmentSummary.ts already computed upfront, monthly and total over term for the Execute now / Run now confirms. Add commitmentLine (rec to line), formatCommitmentTotals (the three totals as text, never a partial monthly sum) and buildCommitmentBand, and use them in: - the bulk modal header (Monthly recurring, Total over term) and each bucket's totals line (monthly recurring), - the bulk confirm dialog (the same stat band and line list as the single-purchase confirm), - the single purchase modal (a band under the table for the checked rows) and its Execute Now warning, - the approval dialog header (Monthly cost, Total over term), laid out four stats per row so the eight stats do not leave an orphan. Refs LeanerCloud#711 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 10 billable files and costs up to $2.50. Or wait 59 minutes for your next included review. View limit details
Comment |
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): APPROVE Blocking:
|
|
Local verification at
|
|
Marked ready and merged by IAmJSD's agent, at IAmJSD's request (IAmJSD reviewed the before/after screenshots; cristim is traveling), after the independent review and local verification above, all at |
Conflicts: - frontend/src/app.ts: main's LeanerCloud#1364 (Refs LeanerCloud#711) added commitmentLine() to commitmentSummary.ts and already gives the bulk confirm the same Upfront on approval / Monthly / Total over term summary this branch added. Took main's commitmentLine for both the single and the fan-out confirm and dropped this branch's now-duplicate toCommitmentLine helper (and its LocalRecommendation/CommitmentLine imports). Kept this branch's remaining LeanerCloud#707 behavior on top: the "Totals below are across all requests." intro sentence and the amount on the confirm button via executeConfirmLabel(false, totals.upfront) instead of main's plain "Send all for approval". - frontend/src/__tests__/purchase-execution-toast.test.ts: comment on the getAccountName mock; merged both wordings (LeanerCloud#707/LeanerCloud#711). - frontend/src/__tests__/purchase-modal-submit.test.ts: main split this suite over a shared harness (LeanerCloud#1349). Took main's file and moved this branch's "bulk approval confirm states the totals across all buckets (LeanerCloud#707)" test into purchase-modal-fanout-payment.test.ts, next to the fan-out payment-change test it sat beside before the split, adding the confirmDialog and formatCurrency imports it needs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts (all in frontend/src/history.ts): - Purchase History row: kept main's escaped count and upfrontCell() (LeanerCloud#1364 amortized upfront) and this branch's right-aligned `num` classes on count, monthly and savings. - Approval queue placeholders: kept this branch's NO_VALUE for account, term and payment; dropped the branch's local `const amortize` because main hoisted the same declaration above the row map. - Approval queue row: same combination as the history row. - upfrontCell() (main, merged cleanly) now emits class `num` on both its plain and "(in monthly)" variants, so the upfront column stays right-aligned like the other money columns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: - frontend/src/app.ts: both sides added an import after the closeModal import (this branch's ./fanout-retry, main's ./init-error from LeanerCloud#1338). Kept both. The submitFanOutBuckets/handleFanOutExecute retry changes merged cleanly with main's LeanerCloud#1352 account-labelled bucket names and LeanerCloud#1364 commitment lines; the toast those feed is still used when retry mode does not apply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#781 added the Upfront / Monthly / Total over term band to the single-purchase Execute now, Run now and RI exchange confirms, but the other decision screens still showed only the upfront. The bulk Review Purchase modal said "Total upfront: $0" for no-upfront buckets that bill monthly for 1 or 3 years, its confirm dialog showed no amounts at all, the Execute Now warning read "This will charge $0.00 upfront immediately" for a monthly-billed purchase, and the approval dialog had no monthly cost or term total. This PR shows the monthly charge and the term total on all of them, using the shared helper from #781.
Closes #711
What changed
frontend/src/commitmentSummary.ts: new shared helperscommitmentLine(priced rec to line, with optional bucket payment and account),formatCommitmentTotals(upfront / monthly / term total as text; an unknown monthly reads "Not reported (monthly fees apply)" instead of a partial sum),billsMonthly, andbuildCommitmentBand(the stat band without the line list).buildCommitmentSummarynow uses them.frontend/src/recommendations.ts:#purchase-modal-commitment-band) for the checked rows.frontend/src/app.ts: the single confirm usescommitmentLine; the bulk confirm now carries the same summary band and line list as the single confirm.frontend/src/approval-details.ts: the header gains "Monthly cost" and "Total over term" stats right after "Upfront".frontend/src/styles/components.css: the approval header grid is capped at four stats per row so the eight stats sit in two even rows.commitmentSummary.test.ts,approval-details.test.ts,purchase-modal-submit.test.ts,purchase-execution-toast.test.tsandtests-e2e/execute-now-warning.spec.ts.Why this approach
It builds on the helper #781 introduced instead of adding a second one, so every screen computes and words the three numbers the same way (term total = upfront + monthly x 12 x term, per line). This is the shared
{upfront, monthlyRecurring, totalOverTerm}helper the issue suggests. The bulk modal keeps its existing "Label: value" lines and 0-decimal format, with two lines added. The confirm dialogs reuse the existing stat band. The approval header's upfront still comes from the backend'stotal_upfront_cost, but the monthly and term totals are summed from the per-rec rows because the API has no aggregate for them.Screenshots
Before is main (
a14dc8f2), after is this branch. Both are headless Chromium at 1440x900 against the repo's mocked e2e API, with two no-upfront AWS EC2 recs ($280/mo over 3 years and $150/mo over 1 year).Verification
Run on this branch's head
121e5491on top of maina14dc8f2:--randomize(138 and 31 passed). New tests:commitmentSummary(commitmentLine,formatCommitmentTotals,billsMonthly,buildCommitmentBand),approval-details(monthly and term stats, unreported monthly), and a newpurchase-modal-submitblock (modal band follows the checkboxes, Execute Now warning with a monthly and with an unreported monthly, bulk summary plus bucket line plus bulk confirm). Updated:approval-detailsstat indices (+2), and thepurchase-execution-toastmock gainedgetAccountName.e2e-local.sh: 157 passed.execute-now-warning.spec.tsnow expects the monthly wording and asserts the band and the fan-out "Monthly recurring" / "Total over term" lines.scripts/test-git-secrets-allowlist.sh: 137 pass, 0 fail.Notes for review
monthly_costover only the rows that report one, so it can show a partial sum. It is left as is because the new band below it says "Not reported".Overlaps
recommendations.tsand the stat styling.purchase-modal-submit.test.ts; with that split the new 74-line describe block here would push the file to about 512 lines, so it should move to its own suite or topurchase-modal-repricing.test.tswhen rebasing.app.tshunks aroundfanOutBucketLabeland the fan-out execute path.purchase-modal-submit.test.tsandapproval-details.test.tsare hot files across the purchase-modal branches, so expect textual conflicts there.Those PRs will be opened alongside this one and merged in sequence, with conflicts resolved on the later branch.
Note for the UI owner
This changes UI code that @cristim owns. IAmJSD reviewed the before/after screenshots and asked for it to be merged; any design point you disagree with can be a follow-up.
🤖 Generated with Claude Code