refactor(hooks): extrai useEntitySelectionMode genérico (F1-1.x Onda D #2)#122
Conversation
…#2) ## Onda D — Eliminar duplicação top 7 — par #2 useNoveltiesSelectionMode (176L) e useReplenishmentsSelectionMode (153L) eram **95% idênticos** — par #6 da lista jscpd com 62 linhas duplicadas. ## Mudanças | Arquivo | Antes | Depois | |---|---|---| | useNoveltiesSelectionMode.ts | 176L | **65L** wrapper | | useReplenishmentsSelectionMode.ts | 153L | **64L** wrapper | | useEntitySelectionMode.ts (NEW) | — | 233L genérico | API mantida 100%. Callers (3) intactos: - src/components/novelties/NoveltyProductGrid.tsx - src/components/replenishments/ReplenishmentProductGrid.tsx - src/components/replenishments/VirtualizedReplenishmentList.tsx ## Risk 🟡 médio. State machine compartilhada, mas: - Genérico tipado <TEntity extends SelectableEntity> - Wrappers só fornecem o entityToProduct converter - API pública preservada (incluindo `noveltyToProduct` no return)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review WalkthroughNovo hook genérico ChangesRefatoring de Seleção em Lote Centralizada
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 80f271224d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return useEntitySelectionMode<ReplenishmentWithDetails>({ | ||
| selectionMode, | ||
| filteredProducts, | ||
| entityToProduct: replenishmentToProduct, | ||
| }); |
There was a problem hiding this comment.
Preserve replenishment hook return shape
When a consumer relies on the hook result for replenishmentToProduct, this wrapper now returns only the generic hook object, whereas the previous implementation included replenishmentToProduct in its return value. The novelties wrapper explicitly preserves the analogous noveltyToProduct property, so replenishment callers that destructure the converter from useReplenishmentsSelectionMode() will now get a missing property/undefined; include replenishmentToProduct in the returned object to keep the API compatible.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Refactors the “bulk selection mode” logic for Novidades and Reposição into a shared generic hook (useEntitySelectionMode) to remove duplicated state-machine code while keeping existing module hooks as thin wrappers.
Changes:
- Added
useEntitySelectionMode<TEntity>()generic hook encapsulating selection set + bulk wizard workflows. - Simplified
useNoveltiesSelectionModeanduseReplenishmentsSelectionModeinto wrappers that provide the entity→Productconverter. - Exported/standardized the converter functions (
noveltyToProduct,replenishmentToProduct) and aligned string literal formatting.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/hooks/useEntitySelectionMode.ts |
New generic hook implementing shared selection + bulk action workflow. |
src/hooks/useNoveltiesSelectionMode.ts |
Wrapper over the generic hook; now exports and re-exposes noveltyToProduct. |
src/hooks/useReplenishmentsSelectionMode.ts |
Wrapper over the generic hook; exports replenishmentToProduct and delegates selection logic to the generic hook. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export function useReplenishmentsSelectionMode({ | ||
| selectionMode, | ||
| filteredProducts, | ||
| }: UseReplenishmentsSelectionModeParams) { | ||
| return useEntitySelectionMode<ReplenishmentWithDetails>({ | ||
| selectionMode, | ||
| filteredProducts, | ||
| entityToProduct: replenishmentToProduct, | ||
| }); |
| export function useEntitySelectionMode<TEntity extends SelectableEntity>({ | ||
| selectionMode, | ||
| filteredProducts, | ||
| entityToProduct, | ||
| }: UseEntitySelectionModeParams<TEntity>) { | ||
| const navigate = useNavigate(); | ||
| const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set()); | ||
| const [collectionModalOpen, setCollectionModalOpen] = useState(false); | ||
| const [cartModalOpen, setCartModalOpen] = useState(false); | ||
| const [variantWizardOpen, setVariantWizardOpen] = useState(false); | ||
| const [wizardMode, setWizardMode] = useState<BulkWizardMode>("cart"); | ||
| const [wizardSelections, setWizardSelections] = useState<BulkVariantSelection[]>([]); | ||
|
|
||
| const selectedCount = selectedIds.size; | ||
|
|
||
| // Clear selection when leaving selection mode | ||
| useEffect(() => { | ||
| if (!selectionMode) setSelectedIds(new Set()); | ||
| }, [selectionMode]); | ||
|
|
||
| // Remove stale IDs when products change | ||
| useEffect(() => { | ||
| setSelectedIds((prev) => { | ||
| if (prev.size === 0) return prev; | ||
| const validIds = new Set(filteredProducts.map((p) => p.product_id)); | ||
| const filtered = new Set([...prev].filter((id) => validIds.has(id))); | ||
| return filtered.size === prev.size ? prev : filtered; | ||
| }); | ||
| }, [filteredProducts]); |
Onda D — Duplicação par #2
useNoveltiesSelectionMode(176L) euseReplenishmentsSelectionMode(153L) eram 95% idênticos — par #6 da lista jscpd com 62 linhas duplicadas.📦 Mudanças
useNoveltiesSelectionMode.tsuseReplenishmentsSelectionMode.tsuseEntitySelectionMode.ts(NEW)✅ API mantida 100%
Callers (3) intactos:
src/components/novelties/NoveltyProductGrid.tsxsrc/components/replenishments/ReplenishmentProductGrid.tsxsrc/components/replenishments/VirtualizedReplenishmentList.tsxnoveltyToProduct(era function privada, agora exportada) ereplenishmentToProductmantidos no contrato.Design
Hook genérico com:
🟡 Médio. Compartilhamento de state machine, mas:
TEntity extends SelectableEntity)newArrival: truepara novelties,falsepara replenishments)Summary by CodeRabbit