Repository navigation
🌱 refactor: split hook-heavy card components - #24409
Conversation
Extract EventsTimeline, IframeEmbed, Kubedle, and ContainerTetris state clusters into dedicated hooks without changing their public card exports. Keep each component and hook below 400 lines, preserve UI behavior, and cover game rules and eight visual states. Hive-Run: kubestellar#24405 Hive-Plan: hook-heavy-card-extraction Hive-Spec: kubestellar#24405#behavior-preserving-split Signed-off-by: Karibhou <157208370+Karibhou@users.noreply.github.com>
✅ Deploy Preview for kubestellarconsole ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
@Karibhou this PR is back in your court ( Failing checks:
Reply here or push a new head to this branch (same sign-off); CI and the review swarm re-run automatically and the PR returns to the normal path. Queued in your relay fix queue (2 waiting): fixes are handed out before new work as soon as you have capacity. |
There was a problem hiding this comment.
Conflict with #24407: both PRs create web/src/components/cards/useIframeEmbed.ts and rewrite IframeEmbed.tsx. They cannot both merge.
I read both diffs in full. They make the same semantic change — extracting IframeEmbed's config state, localStorage persistence, URL sanitization, and refresh timer into a new useIframeEmbed hook — with only stylistic differences:
- This PR (#24409) is a near-verbatim move of the original code (same literals
slice(0, 12),50,* 1000; hook callsuseCardExpanded/useCardDemoStateinternally). It also covers EventsTimeline, Kubedle, and ContainerTetris, closing #24405. - #24407 covers only IframeEmbed (
Refs #24400, the parent of #24405), but names the constants (INSTANCE_ID_LENGTH,RELOAD_DELAY_MS,MS_PER_SECOND), null-guardssavedEmbeds((prev || []).filter(...)at its hook lines ~163/179), and ships a dedicateduseIframeEmbed.test.ts(19 tests) that this PR does not have.
Both preserve sanitizeIframeUrl at the restore/save/reload boundaries that main's IframeEmbed.tsx enforces (main lines 107–110, 176–179), so neither regresses the scheme-injection guard. The non-iframe extractions here (useEventsTimeline, useKubedle, useContainerTetris, and their components) are faithful moves — timer literals and cleanup are symmetric with the removed code.
Question for a maintainer: pick one IframeEmbed extraction. Either (a) land #24407's iframe split (tested hook, named constants) and rebase this PR to drop its IframeEmbed.tsx/useIframeEmbed.ts changes, or (b) land this PR wholesale and close #24407 as superseded. Whichever merges second will conflict on both files. I have not closed anything.
Separately, the red ts-null-safety check here is the AI-antipattern ratchet ("AI code quality regression detected", job 117489910045); the timer literals in the moved hooks are the likely counters, and #24407's named-constant style avoids that class of hit.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88
|
hive CI finding — Likely cause: the "Cards missing unified controls" ratchet counts every top-level Concrete fix: keep the 🐝 Hive Agent: — hive: agent=scanner backend=copilot model=claude-fable-5 copilot=1.0.88 |
The nil-safety unified-controls ratchet requires every top-level cards/*.tsx to call useCardLoadingState directly. Return the loading state inputs from useEventsTimeline and invoke useCardLoadingState in EventsTimeline.tsx, restoring the count to baseline. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: scanner <scanner@hive.kubestellar.io>
There was a problem hiding this comment.
Read the full diff at 4622d00 against the base tree. The four hook extractions are verbatim moves with behavior preserved:
useIframeEmbed.ts:36keepssanitizeIframeUrlwith all four call boundaries intact (initial config, localStorage restore, save, and the reload insidehandleRefresh), including the CodeQL-relevantparsed.hrefreturn and the comments explaining them.useContainerTetris.ts:131documents the preservedmoveDowndependency list (scoreintentionally still omitted) as moved-code rather than silently "fixing" it mid-refactor — the right call.useKubedle.tsmoves the #6306 valid-guess gate and shake-timeout cleanup unchanged, and the newuseKubedle.test.tscovers duplicate-letter marking, invalid-word rejection, stats persistence, and timer cleanup — real coverage this logic never had.useEventsTimeline.tskeeps filtering/bucketing/chart logic identical; the only changes are wrapping the defensive fallbacks inuseMemoand returningcardLoadingInputsouseCardLoadingStatestays in the component. Both are behavior-neutral.
Looks correct to me on its own terms.
One thing a maintainer must settle before merging either PR: this overlaps #24407. Both PRs create web/src/components/cards/useIframeEmbed.ts and rewrite IframeEmbed.tsx with the same extraction — #24407 for issue #24400 (Refs, partial) and this one for #24405 (Closes). They conflict and cannot both merge as-is. If this broader PR lands first, #24407 becomes redundant; if #24407 lands first, this one needs a rebase that drops its iframe portion. Same author, so likely an overlapping-issues artifact rather than true duplication — but the ordering choice is yours.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88
|
Needs a decision, not a merge:
Head: verdict requires_human @4622d00, 30/31 checks green, 1 pending, DCO yes, soak 0s of 30m0s. Clear the cause and the hive re-evaluates on its next pass; the stage moves to |
|
Merge conflict with main (sibling refactor PRs merged first). This is a fork branch the hive cannot push to — @Karibhou please rebase onto main and resolve conflicts; CI was otherwise reviewed-approve. 🐝 Hive Agent: — hive: agent=scanner backend=copilot model=claude-fable-5 copilot=1.0.88 |
Keep the merged IframeEmbed extraction from kubestellar#24407 and retain the three distinct card hook extractions. Remove duplicate iframe visual coverage from this PR. Signed-off-by: Karibhou <157208370+Karibhou@users.noreply.github.com>
There was a problem hiding this comment.
Compared the extracted hooks against the removed component code: useKubedle.ts, useContainerTetris.ts, and useEventsTimeline.ts move the state/logic verbatim (word lists, checkGuess two-pass logic, stats persistence via safeGet/safeSet all unchanged), and the components keep only rendering. Verified at head 3a86ff2: tsc --noEmit clean, the new useKubedle.test.ts passes, and the PR includes a visual spec with committed snapshots for all three cards.
One note for CI triage: in a broad local run, WorkloadImportDialog.test.tsx (untouched by this PR) flaked 3 tests but passes in isolation — not attributable to this change. Looks correct to me.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88
c01e1bd
into
kubestellar:main
⏹️ Post-Merge Verification: cancelledCommit: |
Closes #24405
EventsTimeline, Kubedle, and ContainerTetris mixed rendering with substantial stateful logic. Extract their data, persistence, timers, and game controls into dedicated adjacent hooks while preserving the existing card props, exports, markup, and behavior.
useCardLoadingStatecall inEventsTimeline.tsxto satisfy the unified-controls gate.main, including the IframeEmbed extraction already merged through 🌱 refactor: extract iframe embed state and lifecycle #24407. The resulting PR diff does not change IframeEmbed.Validation: 14 focused unit tests passed after the merge, including the IframeEmbed tests from
main.git diff --checkpassed. Visual tests, build, and lint are validated by CI as required by AGENTS.md/CLAUDE.md.— hive: backend=codex