# FAQ - Reordenação Drag & Drop (Perguntas Frequentes)

## ❓ Perguntas sobre Funcionalidade

### P: Como ativo a reordenação no meu componente?
**R**: Adicione a prop `sortable="true"` ao DynamicList:
```vue
<DynamicList
  :schema="schema"
  :data="data"
  :sortable="true"
  @reorder="handleReorder"
/>
```

### P: Qual é a diferença entre DynamicList e PropertyListEditor?
**R**: 
- **DynamicList.vue**: Componente genérico para exibir coleções de dados com reordenação opcional
- **PropertyListEditor.vue**: Componente especializado para editar propriedades de objetos (metadados) com suporte completo a inline-editing

### P: O que é o "drag-handle"?
**R**: É o ícone `⋮⋮` (seis pontos) que aparece no início de cada linha quando `sortable="true"`. Você deve clicar/arrastar nele para mover a linha de posição.

### P: Preciso atualizar a API quando reordenar?
**R**: Não imediatamente. O componente emite o evento `reorder` com a nova ordem. Você deve:
1. Capturar o evento
2. Marcar como "dirty" (isDirty = true)
3. Aguardar o usuário clicar "Salvar"
4. Então enviar para a API

### P: Como funciona a sincronização com o estado "dirty"?
**R**: 
```typescript
@reorder="(newList) => {
  isDirty = true;  // Marca como modificado
  dataList = newList;  // Atualiza dados locais
  toast.add({ severity: 'info', summary: 'Alteração pendente' });
}"
```

### P: Posso reordenar dentro de um grupo específico?
**R**: Sim. Use a propriedade `group` no componente:
```javascript
const dragOptions = {
  group: "meu-grupo",  // Restringe a qual grupo pode arrastar
  // ...
}
```

### P: O que acontece se o usuário sair sem salvar?
**R**: Dois comportamentos:
1. **PropertyListEditor**: Detecta isDirty e avisa ("Existem alterações não salvas")
2. **DynamicList**: Sem gestão de dirty, você controla no componente pai

---

## ❓ Perguntas sobre UI/UX

### P: Como faço o handle aparecer apenas ao passar o mouse?
**R**: Atualmente ele aparece sempre. Se quiser mudar, adicione CSS:
```css
.drag-handle {
  opacity: 0.3;  /* Invisível */
}
.record-card:hover .drag-handle {
  opacity: 1;  /* Visível ao passar mouse */
}
```

### P: Posso customizar o ícone do handle?
**R**: Sim! Edite em DynamicList.vue ou PropertyListEditor.vue:
```vue
<!-- Antes -->
<i class="pi pi-bars text-gray-400 text-sm"></i>

<!-- Depois (exemplo com ícone de drag) -->
<i class="pi pi-arrow-down-up text-gray-400 text-sm"></i>
```

### P: Qual é a cor durante o arraste?
**R**: Configurada em CSS no `.drag` class:
```css
.drag {
  opacity: 1;
  transform: rotate(2deg) scale(1.02);
  box-shadow: 0 5px 25px rgba(99, 102, 241, 0.3);  /* Azul índigo */
}
```

### P: Posso mudar a duração da animação?
**R**: Sim, no `dragOptions`:
```javascript
const dragOptions = {
  animation: 200,  // ms (mude aqui)
  // ...
}
```

### P: Como funciona no mobile?
**R**: Funciona normalmente, mas considere:
- Handle talvez seja pequeno (aumentar em mobile)
- Arraste de toque é suportado
- Recomenda-se aumentar padding em telas pequenas

---

## ❓ Perguntas sobre Dados

### P: Os dados são salvos automaticamente ao reordenar?
**R**: Não. Você deve:
1. Capturar evento `reorder`
2. Atualizar estado local
3. **Manualmente** chamar API ao clicar "Salvar"

Exemplo:
```typescript
function handleReorder(newOrder) {
  localData.value = newOrder;  // Local
  isDirty.value = true;        // Marcar como pendente
  // Não salva ainda!
}
```

### P: Como garanto que a ordem é única?
**R**: A ordem é determinada pelo índice no array. Vue mantém a reatividade automaticamente.

### P: E se duas propriedades tiverem o mesmo nome?
**R**: Isso causaria conflito. Implemente validação:
```typescript
function validatePropertyName(newName) {
  const exists = editingObject.properties.some(p => p.name === newName);
  if (exists) {
    toast.add({ severity: 'error', summary: 'Nome já existe' });
    return false;
  }
  return true;
}
```

### P: Como desfaço uma reordenação?
**R**: Três opções:
1. **Sem salvar**: Recarregue a página (dados não salvos são perdidos)
2. **Com salvar**: Reordene novamente manualmente
3. **Undo avançado**: Implemente stack de mudanças (ver roadmap)

### P: Posso reordenar entre múltiplas listas?
**R**: Apenas se as listas tiverem o mesmo `group`:
```typescript
// Lista A
const dragOptionsA = { group: "shared" };

// Lista B  
const dragOptionsB = { group: "shared" };

// Agora itens podem ir de A para B e vice-versa
```

---

## ❓ Perguntas sobre Performance

### P: Qual é o limite de propriedades que posso reordenar?
**R**: Teoricamente ilimitado, mas:
- **< 50**: Muito rápido
- **50-200**: Rápido
- **200+**: Considere virtualização (ainda não implementada)

### P: Há lag ao arrastar muitos itens?
**R**: Se houver, verifique:
1. Número de computed properties
2. Watchers profundos
3. Tamanho dos dados renderizados
4. Performance do navegador (DevTools > Performance)

### P: Como otimizo a renderização?
**R**: 
```typescript
// ✅ BOM: Computed para dados filtrados
const visibleProperties = computed(() => {
  return properties.value.filter(p => p.show_in_list);
});

// ❌ EVITE: Lógica no template
<div v-for="p in properties.filter(p => p.show_in_list)">
```

### P: Devo usar `v-key="item.id"` ou `v-key="index"`?
**R**: Sempre `item.id` se disponível. O índice muda ao reordenar, causando re-renders desnecessários.

---

## ❓ Perguntas sobre Integração

### P: Como integro com dados do backend?
**R**: 
```typescript
// 1. Fetch dos dados
const properties = ref([]);
onMounted(async () => {
  properties.value = await $fetch('/api/object/lead/properties');
});

// 2. Componente com sortable
<PropertyListEditor
  :properties="properties"
  @reorder="onReorder"
/>

// 3. Handler
function onReorder(newOrder) {
  isDirty = true;
  // Salvar mais tarde com API call
}
```

### P: Como funciona com Pinia store?
**R**: 
```typescript
// store/object.ts
const properties = ref([]);

function setProperties(newProperties) {
  properties.value = newProperties;
}

function reorderProperties(newOrder) {
  properties.value = newOrder;
  isDirty = true;  // Marcar store como dirty
  // Salvar quando necessário
}
```

### P: Como sincronizo com Sistema de Manifesto?
**R**: O Schema Manager já faz isso. Seu objeto é:
```typescript
editingObject.value.properties = reorderedProperties;  // Atualiza referência
isDirty.value = true;  // Marca para salvar
```

---

## ❓ Perguntas sobre Debugging

### P: Como vejo quais eventos estão sendo disparados?
**R**: Adicione logs no handler:
```typescript
function onReorder(newOrder) {
  console.log('[REORDER EVENT]', newOrder);
  console.log('[ORDER NAMES]', newOrder.map(p => p.name));
}
```

### P: Como verifico o estado drag durante animação?
**R**: Use DevTools:
1. Abra Elements/Inspector
2. Selecione um item durante arraste
3. Veja classe `.drag` sendo aplicada

### P: Como verifico se isDirty está sendo marcado?
**R**: 
```typescript
watch(() => isDirty.value, (newVal) => {
  console.log('[DIRTY CHANGED]', newVal);
});
```

### P: Por que o evento reorder é emitido múltiplas vezes?
**R**: Verifique se você tem múltiplos watchers:
```typescript
// ❌ PROBLEMA: Watcher duplicado
watch(properties, () => {
  emit('reorder', properties.value);  // Emite sempre que muda
});

// ✅ SOLUÇÃO: Emita apenas no @end do draggable
@end="onDragEnd"
```

---

## ❓ Perguntas sobre Erros Comuns

### P: "Cannot read property 'name' of undefined"
**R**: Propriedade está null. Verifique:
```typescript
// ✅ BOM: Validação
const propName = property?.name || 'Unknown';

// ❌ EVITE: Sem checar
const propName = property.name;  // Erro se property = null
```

### P: Array não atualiza após reordenar
**R**: Você está mutando diretamente? Use Vue.set:
```typescript
// ❌ ERRADO
properties[0] = newValue;  // Vue não detecta

// ✅ CORRETO
properties.value[0] = newValue;  // Reativo
// ou
properties.value = [...properties.value];  // Novo array
```

### P: Drag & Drop não funciona
**R**: Verifique:
1. `vuedraggable` está importado?
2. Prop `sortable="true"` foi adicionado?
3. Handle `.drag-handle` existe no template?
4. Browser suporta drag & drop?

### P: Estilos não aplicam durante arraste
**R**: Você está importando o CSS de `.drag`?
```vue
<style scoped>
.drag {
  opacity: 1;
  box-shadow: 0 5px 25px rgba(99, 102, 241, 0.3);
}
</style>
```

---

## ❓ Perguntas sobre Acessibilidade

### P: Como faço reordenação acessível via teclado?
**R**: Isso ainda não foi implementado. Você pode:
1. Adicionar botões "Mover Para Cima"/"Mover Para Baixo"
2. Usar Shift + Setas para reordenar (custom)
3. Implementar ARIA labels

Exemplo de botões:
```vue
<Button 
  icon="pi pi-arrow-up"
  @click="moveUp(idx)"
  aria-label="Mover para cima"
/>
<Button 
  icon="pi pi-arrow-down"
  @click="moveDown(idx)"
  aria-label="Mover para baixo"
/>
```

### P: Qual é o aria-label do handle?
**R**: Não tem atualmente. Adicione se necessário:
```vue
<div class="drag-handle" aria-label="Arrastar para reordenar">
```

---

## ❓ Perguntas sobre Roadmap

### P: Vocês vão implementar Undo/Redo?
**R**: Não está planned ainda, mas é possível usando:
```typescript
const history = ref([]);
const historyIndex = ref(-1);

function saveToHistory() {
  history.value = history.value.slice(0, historyIndex.value + 1);
  history.value.push(JSON.parse(JSON.stringify(properties.value)));
  historyIndex.value++;
}

function undo() {
  if (historyIndex.value > 0) {
    historyIndex.value--;
    properties.value = JSON.parse(JSON.stringify(history.value[historyIndex.value]));
  }
}
```

### P: Quando virá array virtual para 1000+ itens?
**R**: Não está planneed. Use paginação ou virtualScroller de PrimeVue.

### P: Vocês vão adicionar persistência automática?
**R**: Considere debounce + auto-save:
```typescript
const saveToDebounce = useDebounceFn(saveChanges, 2000);

function onReorder(newOrder) {
  isDirty.value = true;
  saveToDebounce();  // Salva automaticamente após 2s
}
```

---

## ❓ Perguntas sobre Suporte

### P: Funciona em Safari?
**R**: Sim, com vuedraggable 4.0+. Tested em Safari 15+.

### P: Funciona em IE11?
**R**: Não. Suporte apenas para navegadores modernos (Chrome, Firefox, Safari, Edge).

### P: Posso usar com jQuery?
**R**: Não, este é um projeto Vue 3. jQuery não é suportado.

### P: Qual é o licença deste código?
**R**: Mesmo projeto (verificar LICENSE.md).

---

## 📞 Contato & Suporte

Se você não encontrou resposta aqui:
1. Verifique [IMPLEMENTATION_DRAG_DROP.md](IMPLEMENTATION_DRAG_DROP.md)
2. Verifique [TESTING_GUIDE.md](TESTING_GUIDE.md)
3. Procure nos comentários do código
4. Abra uma issue no GitHub

---

**Última Atualização**: 17/02/2026
