refactor(ui): centralize device & container action logic#6573
Merged
Conversation
|
Claude finished @luannmoreira's task in 5m 51s —— View job Code Review CompleteReviewed 15 files across code quality, security, testing, language patterns, and architecture — no new issues found. The code looks good as-is. Highlights from the review:
If you push additional changes and want a new review, tag |
luizhf42
reviewed
Jun 30, 2026
luannmoreira
added a commit
that referenced
this pull request
Jun 30, 2026
Drop the unused TEntity/TAction generics from useActionDialogState — both
domains always use {uid, name} entities and the accept/reject/remove action
set, so the hook now operates on the concrete EntityBase/EntityAction types.
The action dialogs reuse the shared EntityBase instead of redefining it.
The useActionDialogState test mock now spreads env's defaultConfig rather
than re-declaring the full ClientConfig literal.
Member
|
/review |
|
Claude finished @otavio's task in 11m 54s —— View job Code Review CompleteReviewed 17 files across code quality, security, testing, language patterns, and architecture — no new issues found. The code looks good as-is. Highlights from the review:
If you've addressed the feedback and want a new review, tag |
Extract the shared action-dialog state machine into useActionDialogState, with thin useDeviceActions/useContainerActions wrappers and the Device/Container ActionsPortal components, replacing the duplicated action logic in the device and container list/detail pages. Tests for the hook and portals are rewritten to drive behavior through the public API (renderHook + userEvent) rather than inspecting passed props.
3ba8d27 to
803ea17
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Accept/reject/remove dialog wiring and the billing-warning gate were duplicated across
DeviceDetails,ContainerDetails, and both list pages. This extracts a single shared implementation that all four pages consume.Why
Closes shellhub-io/team#153. Any bug in the action flow, loading state, or error handling previously had to be fixed in each page independently. (The audit named three files; the real duplication spans four —
admin/deviceshas no action logic, whileContainerDetailsdoes.)Changes
hooks/useActionDialogState: generic state core —operationstate,requestAction,close, the cloud-gatedonBillingWarning, andrunSuccess(action). All returned callbacks areuseCallback-stable so list-page columnuseMemos don't churn.hooks/useDeviceActions/useContainerActions: thin typed wrappers (the issue-named public API);enableBillingWarningdefaults to!!getConfig().cloud.DeviceActionsPortal/ContainerActionsPortal: render the existing*ActionDialog+BillingWarningfrom the controller, preserving thekey-based reset and the entity→device/containerprop mapping.DeviceDetails,devices/index,ContainerDetails,containers/indexdrop their inline state/render in favor of the hook + portal.ContainerDetailspassesenableBillingWarning: falseto keep its existing no-billing-warning flow.*ActionDialogandBillingWarningcomponents are unchanged — they already centralized the mutations and 402 handling.Testing
useActionDialogState(state, billing gating, stable refs, action forwarding) and both portals (prop mapping;ContainerActionsPortalassertsBillingWarningis absent whenenableBillingWarning: false).eslintandtsc -bclean.ContainerDetailsstill shows the inline 402 error (not the billing dialog) on a cloud build — that asymmetry vs. the other pages is intentional and preserved.