Atualização floresta
This commit is contained in:
parent
0886fd5c3e
commit
2d4d8f8929
103 changed files with 19266 additions and 14160 deletions
139
src/componentes/EliTabela/useColunasOrdenacao.ts
Normal file
139
src/componentes/EliTabela/useColunasOrdenacao.ts
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* useColunasOrdenacao
|
||||
* Composable que encapsula a lógica de drag-and-drop e sincronização de estado
|
||||
* do modal de configuração de colunas da EliTabela.
|
||||
*
|
||||
* Responsável por:
|
||||
* - Sincronizar colunas visíveis/invisíveis com a configuração persistida
|
||||
* - Aplicar ordem salva e adicionar novas colunas ao final
|
||||
* - Gerenciar eventos de arrastar-e-soltar entre as duas listas
|
||||
*
|
||||
* Extraído de `EliTabelaModalColunas.vue` para manter o componente abaixo de 250 linhas.
|
||||
*/
|
||||
import { type Ref, ref, watch } from "vue"
|
||||
import type { EliTabelaColunasConfig } from "./colunasStorage"
|
||||
import type { tipoEliColuna } from "./types-eli-tabela"
|
||||
|
||||
type OrigemLista = "visiveis" | "invisiveis"
|
||||
|
||||
interface UseColunasOrdenacaoOptions {
|
||||
aberto: Ref<boolean>
|
||||
rotulosColunas: Ref<string[]>
|
||||
configInicial: Ref<EliTabelaColunasConfig>
|
||||
// biome-ignore lint/suspicious/noExplicitAny: colunas genéricas — tipo parametrizado no pai
|
||||
colunas: Ref<tipoEliColuna<any>[]>
|
||||
}
|
||||
|
||||
/**
|
||||
* Composable de drag-and-drop para reordenação e alternância de visibilidade de colunas.
|
||||
* Sincroniza automaticamente quando `aberto`, `rotulosColunas`, `configInicial` ou `colunas` mudam.
|
||||
*
|
||||
* @param options.aberto - Ref que controla se o modal está aberto (gatilho de sincronização)
|
||||
* @param options.rotulosColunas - Ref com todos os rótulos de colunas da tabela
|
||||
* @param options.configInicial - Ref com a configuração persistida (visíveis + invisíveis)
|
||||
* @param options.colunas - Ref com a definição completa das colunas (para ler `visivel: false` padrão)
|
||||
* @returns Estado reativo e handlers de drag-and-drop prontos para o template
|
||||
*/
|
||||
export function useColunasOrdenacao({
|
||||
aberto,
|
||||
rotulosColunas,
|
||||
configInicial,
|
||||
colunas,
|
||||
}: UseColunasOrdenacaoOptions) {
|
||||
const visiveisLocal = ref<string[]>([])
|
||||
const invisiveisLocal = ref<string[]>([])
|
||||
const itemSendoArrastado = ref<string | null>(null)
|
||||
|
||||
function sincronizarEstado() {
|
||||
const todos = rotulosColunas.value
|
||||
const configTemDados =
|
||||
(configInicial.value.visiveis?.length ?? 0) > 0 ||
|
||||
(configInicial.value.invisiveis?.length ?? 0) > 0
|
||||
|
||||
const invisiveisPadraoSet = new Set(
|
||||
colunas.value.filter((c) => c.visivel === false).map((c) => c.rotulo),
|
||||
)
|
||||
const invisiveisSet = configTemDados
|
||||
? new Set(configInicial.value.invisiveis ?? [])
|
||||
: invisiveisPadraoSet
|
||||
|
||||
const baseVisiveis = todos.filter((r) => !invisiveisSet.has(r))
|
||||
const ordemSalva = configInicial.value.visiveis ?? []
|
||||
const setVis = new Set(baseVisiveis)
|
||||
const ordenadas: string[] = []
|
||||
|
||||
for (const r of ordemSalva) {
|
||||
if (setVis.has(r)) ordenadas.push(r)
|
||||
}
|
||||
for (const r of baseVisiveis) {
|
||||
if (!ordenadas.includes(r)) ordenadas.push(r)
|
||||
}
|
||||
|
||||
visiveisLocal.value = ordenadas
|
||||
invisiveisLocal.value = todos.filter((r) => invisiveisSet.has(r))
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [aberto.value, rotulosColunas.value, configInicial.value, colunas.value] as const,
|
||||
() => {
|
||||
if (aberto.value) sincronizarEstado()
|
||||
},
|
||||
{ deep: true, immediate: true },
|
||||
)
|
||||
|
||||
function onDragStart(e: DragEvent, rotulo: string) {
|
||||
itemSendoArrastado.value = rotulo
|
||||
if (e.dataTransfer) {
|
||||
e.dataTransfer.setData("text/plain", rotulo)
|
||||
e.dataTransfer.effectAllowed = "move"
|
||||
}
|
||||
}
|
||||
|
||||
function onDragEnd() {
|
||||
itemSendoArrastado.value = null
|
||||
}
|
||||
|
||||
function onDragOverItem(alvoRotulo: string, destino: OrigemLista) {
|
||||
const draggedRotulo = itemSendoArrastado.value
|
||||
if (!draggedRotulo || draggedRotulo === alvoRotulo) return
|
||||
|
||||
const origemVisIdx = visiveisLocal.value.indexOf(draggedRotulo)
|
||||
const origemInvIdx = invisiveisLocal.value.indexOf(draggedRotulo)
|
||||
const origem = origemVisIdx >= 0 ? "visiveis" : origemInvIdx >= 0 ? "invisiveis" : null
|
||||
if (!origem) return
|
||||
|
||||
const origemArr = origem === "visiveis" ? visiveisLocal.value : invisiveisLocal.value
|
||||
const destinoArr = destino === "visiveis" ? visiveisLocal.value : invisiveisLocal.value
|
||||
|
||||
const dragIdx = origemArr.indexOf(draggedRotulo)
|
||||
const alvoIdx = destinoArr.indexOf(alvoRotulo)
|
||||
|
||||
origemArr.splice(dragIdx, 1)
|
||||
destinoArr.splice(alvoIdx, 0, draggedRotulo)
|
||||
}
|
||||
|
||||
function onDragOverLista(destino: OrigemLista) {
|
||||
const draggedRotulo = itemSendoArrastado.value
|
||||
if (!draggedRotulo) return
|
||||
|
||||
const destinoArr = destino === "visiveis" ? visiveisLocal.value : invisiveisLocal.value
|
||||
if (destinoArr[destinoArr.length - 1] === draggedRotulo) return
|
||||
|
||||
const origemVisIdx = visiveisLocal.value.indexOf(draggedRotulo)
|
||||
const origemInvIdx = invisiveisLocal.value.indexOf(draggedRotulo)
|
||||
if (origemVisIdx >= 0) visiveisLocal.value.splice(origemVisIdx, 1)
|
||||
if (origemInvIdx >= 0) invisiveisLocal.value.splice(origemInvIdx, 1)
|
||||
|
||||
destinoArr.push(draggedRotulo)
|
||||
}
|
||||
|
||||
return {
|
||||
visiveisLocal,
|
||||
invisiveisLocal,
|
||||
itemSendoArrastado,
|
||||
onDragStart,
|
||||
onDragEnd,
|
||||
onDragOverItem,
|
||||
onDragOverLista,
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue