Skip to content

chore(ui): flatten nested ternaries (Sonar typescript:S3358) - #483

Merged
thomasluizon merged 2 commits into
mainfrom
chore/sonar-s3358-web-shared
Jul 13, 2026
Merged

chore(ui): flatten nested ternaries (Sonar typescript:S3358)#483
thomasluizon merged 2 commits into
mainfrom
chore/sonar-s3358-web-shared

Conversation

@thomasluizon

Copy link
Copy Markdown
Owner

What

Fixes every open typescript:S3358 (nested ternary) instance in the scoped surfaces: 41 in apps/web + 1 in packages/shared (42 total). The apps/mobile instances are handled by a sibling slice.

Each nested ternary is rewritten into an equivalent, more readable form — behavior and rendered output identical:

  • Value ternarieslet x; if/else assignments (e.g. login-sections title, calendar-* labels, pricing-section eyebrow, multi-month-heatmap alphaFor/cellSize, command-menu activePageLabel).
  • JSX render-state chains (loading/error/empty/content) → extracted local render helpers with early returns (accountability-section, friend-profile-view, pair-detail, social-feed, social-friends, social/page, upgrade/page, today-rail, reschedule-sheet, goal-card, empty-state, command-menu).
  • Ternary nested inside a template literal → extracted the inner expression to a named const (goal-detail-drawer / edit-goal-modal unitSuffix, move-parent-overlay hoverClass).

No // NOSONAR / eslint-disable used — every instance is a real refactor.

Verification

  • turbo type-check (web + shared) — pass
  • eslint (web + shared) — 0 errors
  • vitest run — web 2239 tests pass, shared pass
  • React Doctor (changed scope, --blocking error) — 0 issues
  • jscpd (changed dirs, strict) — 0 clones intersecting changed lines; no new duplication introduced

Refs #243

🤖 Generated with Claude Code

Refactors all 42 open S3358 nested-ternary occurrences in scope (41 in
apps/web, 1 in packages/shared) into equivalent readable forms: early-return
render helpers, if/else assignments, and extracted suffix/label variables.
Logic and rendered output are identical.

Refs #243

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
orbit-ui-mobile-web Ignored Ignored Jul 13, 2026 12:26pm

Request Review

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review: PR #483

Scope: PR #483 - flatten nested ternaries (Sonar typescript:S3358) - 26 files in apps/web + 1 file in packages/shared
Recommendation: APPROVE

Summary

This PR eliminates every nested-ternary (Sonar typescript:S3358) instance across 26 apps/web files and one packages/shared utility (parseReviewMomentKey), rewriting each into an equivalent let/if-else assignment or an extracted local render-helper with early returns. Every hunk was checked by hand against the pre-image; each rewrite preserves the exact branch order, condition polarity, and rendered/returned value of the original ternary chain - a behavior-preserving mechanical refactor, not a redesign. CI corroborates: Build, Type Check, Lint, Design Token Guard, and Contract Drift all report SUCCESS.

Findings

Critical

None.

High

None.

Medium

None.

Low / Info

  • [Info] apps/web/app/(app)/retrospective/_components/retrospective-dashboard.tsx:158-185 - the returned JSX inside the new habits.map callback isn't re-indented to its new nesting level. Purely cosmetic, lint/Prettier pass on it; noted for awareness, not a reportable finding.
  • [Info] Cross-platform parity: this PR touches only apps/web/** and packages/shared/** - no apps/mobile/** file included. The PR body states apps/mobile's S3358 instances are handled by a separate sibling slice. Since this refactor changes zero behavior/props/data-flow, there is no behavioral drift for a mobile mirror to close. Sibling mobile PR's existence was not independently verifiable in this environment - a tracking note, not a blocking parity violation for this PR.

Correctness verification

All 27 ternary-to-if/else or ternary-to-render-helper rewrites (26 web files + 1 shared file) were checked branch-by-branch against the pre-image and are logically identical - including layout.tsx's candidateKey chain, retrospective-dashboard.tsx's statusLabel chain (branch order flipped but exhaustive/equivalent), the loading/error/empty/content chains across accountability-section, friend-profile-view, pair-detail, social-feed, social-friends, social/page, upgrade/page, reschedule-sheet, today-rail, empty-state, goal-card, the command-menu.tsx outer/inner split, the value-ternary rewrites in login-sections, the three calendar views, multi-month-heatmap, edit-goal-modal/goal-detail-drawer, move-parent-overlay, habit-row-check-circle, habit-row-menu, route-transition-shell, pricing-section, and engagement-prompt-store.ts's parseReviewMomentKey. No any, no console.log, no new comments, no dropped className/token/style value, no changed prop shape, no new i18n key, and no packages/shared/src/types/* or orbit-api DTO touched.

Subagents

Agent Verdict
parity-checker N/A - reconstructed inline; behavior-preserving refactor, nothing for a mobile mirror to catch up to
i18n-syncer N/A - no user-facing string/locale JSON change
contract-aligner N/A - no shared types/endpoints or orbit-api DTO change
security-reviewer N/A - orbit-api untouched
design-reviewer PASS - every extracted branch preserves its exact pre-existing JSX/className/style/token values verbatim

Validation

Check Result
Lint PASS (CI)
Type check PASS (CI)
Tests in progress in CI at review time; PR body reports 2239 web + shared tests passing locally
Build (web) PASS (CI)
Design Token Guard PASS (CI)
Contract Drift PASS (CI)
Build (api) N/A - orbit-api not touched

Deferred

i18n / contract-drift / security / backend-hard-rules / FEATURES.md parity dimensions: N/A, surface not touched. CI Unit Tests still in progress at review time. Mobile sibling PR for remaining apps/mobile S3358 instances: existence not independently verifiable here (gh pr list/issue view were blocked in this session) - Info only. All 27 changed files received an explicit correctness verdict above; none deferred.

What's good

Textbook mechanical refactor: every ternary chain replaced with a strictly equivalent, more readable construct, verified by hand across all sites. No NOSONAR/eslint-disable suppressions. Extracted render-helpers are descriptively named and small. Zero behavior/prop/token drift slipped in alongside the mechanical rewrite.

Recommendation

Approve and merge. No Critical/High findings survive review.

The S3358 render-helper extraction left the loading spinner and load-error
EmptyState blocks duplicated verbatim across the social feed, friends, and
buddies sections, tripping the SonarCloud new-code duplication gate (8.9%).
Extract them into shared SocialSectionSpinner / SocialSectionLoadError
components (DRY rule 10). Rendered output unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thomasluizon

Copy link
Copy Markdown
Owner Author

Note on SonarCloud conditions

The first scan flagged two new-code conditions:

  • new_duplicated_lines_density 8.9% > 3% — the S3358 render-helper extraction had left the social loading spinner + load-error EmptyState blocks duplicated verbatim across the feed/friends/buddies sections. Fixed by extracting SocialSectionSpinner / SocialSectionLoadError into a shared social-section-states.tsx (DRY rule 10). Re-scan should report ~0% new duplication.
  • new_coverage 70.2% < 80% — expected and coverage-only. This is a behavior-preserving refactor that relocates already-tested ternary branches into named helpers/if-else blocks; the existing suite (2239 web tests, all green) exercises the same behavior but the added helper lines dilute new-line coverage. Per the Final pre-launch: SonarCloud full-surface → zero + loop /prod-readiness to clean (both repos) #243 Sonar burn-down practice, a coverage-only condition is cleared by admin-override at merge.

No // NOSONAR / eslint-disable used anywhere.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review: PR #483

Recommendation: APPROVE

Summary

Pure mechanical refactor: 42 Sonar typescript:S3358 nested-ternary violations across 27 apps/web files + 1 packages/shared file, rewritten into let/if-else assignments or extracted render-helper functions (plus one new shared component, apps/web/app/(app)/social/_components/social-section-states.tsx, deduping three identical loading/error blocks). Spot-checked the most complex conversions by hand (command-menu.tsx, today-rail.tsx, retrospective-dashboard.tsx, habit-row-check-circle.tsx, packages/shared/src/stores/engagement-prompt-store.ts, route-transition-shell.tsx, pricing-section.tsx, move-parent-overlay.tsx, layout.tsx) — every rewrite preserves the original ternary chain's branch order and output exactly. apps/mobile is untouched by design (PR body + issue #243 defer it to a sibling slice).

Findings

Critical: None.
High: None.
Medium: None. A design-reviewer flag on apps/web/components/upgrade/pricing-section.tsx:117 (--status-bad used for body text vs. the -text variant) traced via git blame to commit bab3e455 — pre-existing, untouched by this diff (which only touches that file's eyebrow ternary around lines 38-51). Out of scope per rubric.
Low/Info: friend-profile-view.tsx still hand-rolls its own spinner identical to the new SocialSectionSpinner rather than reusing it — legitimate follow-up (that file wasn't one of the three dedup targets), not a defect. Not posted per signal gate.

Subagents

Agent Verdict
parity-checker N/A — web-only, behavior-preserving refactor; mobile mirrors remain aligned; mobile's own S3358 pass is intentionally deferred to #243
i18n-syncer N/A — no string/key changes
contract-aligner N/A — no shared-type/endpoint changes; orbit-api untouched
security-reviewer N/A — orbit-api untouched
design-reviewer PASS — new social-section-states.tsx verified byte-for-byte against its 3 call sites; no token/a11y/copy regressions in any reviewed file

Validation

Skipped per this workflow's CI adaptations (Build / Unit Tests / SonarCloud run as separate required checks). PR body self-reports: turbo type-check pass, ESLint 0 errors, Vitest 2239 web tests + shared pass, React Doctor 0 issues, jscpd 0 new clones — not independently re-run in this pass.

Deferred

Dimensions 10-14 (i18n, contract drift, security, backend hard rules, FEATURES.md parity) are N/A — this diff touches none of their surfaces (no strings, no shared types/endpoints, no orbit-api, no feature/behavior change). The sibling orbit-api repo is not checked out in this job; no cross-repo dimension was needed for this diff anyway. All 28 changed files received a verdict — nothing silently skipped.

What's good

Zero NOSONAR/eslint-disable suppressions; the social-section-states.tsx extraction is a clean rule-6 application (3 real duplicated call sites, not invented); engagement-prompt-store.ts's rewrite is strictly better than the original (drops a redundant double startsWith check); comment policy is clean (only 2 new JSDoc blocks, both sanctioned).

Recommendation

Approve as-is — no correctness, contract, security, or parity risk found. Mobile-side S3358 cleanup should land as its own PR per #243.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
70.2% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@thomasluizon
thomasluizon merged commit 7da620f into main Jul 13, 2026
19 of 20 checks passed
@thomasluizon
thomasluizon deleted the chore/sonar-s3358-web-shared branch July 13, 2026 12:36
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.

1 participant