Skip to content

refactor(hooks): extrai useEntitySelectionMode genérico (F1-1.x Onda D #2)#122

Merged
adm01-debug merged 1 commit into
mainfrom
refactor/use-selection-mode
May 9, 2026
Merged

refactor(hooks): extrai useEntitySelectionMode genérico (F1-1.x Onda D #2)#122
adm01-debug merged 1 commit into
mainfrom
refactor/use-selection-mode

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 9, 2026

Onda D — Duplicação 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 tipado

✅ API mantida 100%

Callers (3) intactos:

  • src/components/novelties/NoveltyProductGrid.tsx
  • src/components/replenishments/ReplenishmentProductGrid.tsx
  • src/components/replenishments/VirtualizedReplenishmentList.tsx

noveltyToProduct (era function privada, agora exportada) e replenishmentToProduct mantidos no contrato.

Design

Hook genérico com:

useEntitySelectionMode<TEntity extends SelectableEntity>({
  selectionMode,
  filteredProducts,
  entityToProduct  // ← única diferença entre os 2 hooks
})

⚠️ Risk

🟡 Médio. Compartilhamento de state machine, mas:

  • Tipado genericamente (TEntity extends SelectableEntity)
  • Wrappers só fornecem o converter
  • Comportamento preservado (incluindo newArrival: true para novelties, false para replenishments)

Summary by CodeRabbit

  • Refator
    • Consolidação de fluxos de seleção em lote para melhor consistência nas operações em massa através de diferentes tipos de entidades.

Review Change Stack

…#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)
Copilot AI review requested due to automatic review settings May 9, 2026 20:53
@vercel
Copy link
Copy Markdown

vercel Bot commented May 9, 2026

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

Project Deployment Actions Updated (UTC)
promo-gifts Ready Ready Preview, Comment May 9, 2026 8:54pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

Novo hook genérico useEntitySelectionMode centraliza seleção em lote e orquestração de bulk wizard (carrinho, quote, favoritos, comparação, coleção). Dois hooks existentes (useNoveltiesSelectionMode, useReplenishmentsSelectionMode) são refatorados como thin wrappers que delegam ao novo hook, eliminando duplicação de código de state, modal, store updates, navegação e notifications.

Changes

Refatoring de Seleção em Lote Centralizada

Layer / File(s) Summary
Contratos de Tipo
src/hooks/useEntitySelectionMode.ts
SelectableEntity define contrato mínimo (product_id); UseEntitySelectionModeParams<TEntity> especifica modo seleção, entidades filtradas, conversor entidade-produto.
State Management & Efeitos
src/hooks/useEntitySelectionMode.ts
Core state (selectedIds, wizardMode, modal flags), auto-limpeza ao sair modo seleção, pruning de IDs inválidas quando filtro muda.
Operações de Seleção
src/hooks/useEntitySelectionMode.ts
Helpers: toggleSelect(), selectAll(), clearSelection() para manipular set de IDs selecionados.
Orquestração de Wizard
src/hooks/useEntitySelectionMode.ts
handleWizardComplete() executa fluxos modo-específicos: carrinho/coleção abrem modais, quote navega com query params, favorito/compare/collection atualizam stores com toasts, limpeza de seleção.
API de Retorno
src/hooks/useEntitySelectionMode.ts
Memoized bulkCartProducts, selectedProducts, firstSelectedProduct, além de estado/helpers/callbacks expostos ao consumidor.
Wrapper Novelties
src/hooks/useNoveltiesSelectionMode.ts
Hook simplificado delega ao useEntitySelectionMode<NoveltyWithDetails> via noveltyToProduct; remove orquestração de wizard/modal/store/navegação inline. Exports noveltyToProduct converter.
Wrapper Replenishments
src/hooks/useReplenishmentsSelectionMode.ts
Hook simplificado delega ao useEntitySelectionMode<ReplenishmentWithDetails> via replenishmentToProduct; remove orquestração de wizard/modal/store/navegação inline. Exports replenishmentToProduct converter.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed O título descreve precisamente o objetivo principal do PR: extração de um hook genérico useEntitySelectionMode para eliminar duplicação entre dois hooks similares.
Description check ✅ Passed A descrição segue a template do repositório com seções principais preenchidas: Descrição, Tipo de mudança (refatoração), Mudanças com tabela, API preservada e Design. Faltam Checklist e instruções de teste, mas as seções críticas estão cobertas.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/use-selection-mode

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 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".

Comment on lines +59 to +63
return useEntitySelectionMode<ReplenishmentWithDetails>({
selectionMode,
filteredProducts,
entityToProduct: replenishmentToProduct,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

@adm01-debug adm01-debug merged commit 22d19c1 into main May 9, 2026
15 of 17 checks passed
@adm01-debug adm01-debug deleted the refactor/use-selection-mode branch May 9, 2026 20:56
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 useNoveltiesSelectionMode and useReplenishmentsSelectionMode into wrappers that provide the entity→Product converter.
  • 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.

Comment on lines +55 to +63
export function useReplenishmentsSelectionMode({
selectionMode,
filteredProducts,
}: UseReplenishmentsSelectionModeParams) {
return useEntitySelectionMode<ReplenishmentWithDetails>({
selectionMode,
filteredProducts,
entityToProduct: replenishmentToProduct,
});
Comment on lines +36 to +64
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]);
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.

2 participants