This commit is contained in:
Luiz Silva 2026-02-15 15:17:08 -03:00
parent 8a5596e860
commit 57325f6744
100 changed files with 16153 additions and 4623 deletions

View file

@ -72,19 +72,19 @@
</template>
<script lang="ts">
import { defineComponent, PropType, ref, watch } from "vue";
import type { EliTabelaColunasConfig } from "./colunasStorage";
import type { tipoEliColuna } from "./types-eli-tabela";
import { defineComponent, type PropType, ref, watch } from "vue"
import type { EliTabelaColunasConfig } from "./colunasStorage"
import type { tipoEliColuna } from "./types-eli-tabela"
type OrigemLista = "visiveis" | "invisiveis";
type OrigemLista = "visiveis" | "invisiveis"
type DragPayload = {
rotulo: string;
origem: OrigemLista;
index: number;
};
rotulo: string
origem: OrigemLista
index: number
}
const DRAG_MIME = "application/x-eli-tabela-coluna";
const DRAG_MIME = "application/x-eli-tabela-coluna"
export default defineComponent({
name: "EliTabelaModalColunas",
@ -102,80 +102,89 @@ export default defineComponent({
required: true,
},
colunas: {
// biome-ignore lint/suspicious/noExplicitAny: dynamic typing needed
type: Array as PropType<Array<tipoEliColuna<any>>>,
required: true,
},
},
emits: {
fechar() {
return true;
return true
},
salvar(_config: EliTabelaColunasConfig) {
return true;
return true
},
},
setup(props, { emit }) {
const visiveisLocal = ref<string[]>([]);
const invisiveisLocal = ref<string[]>([]);
const visiveisLocal = ref<string[]>([])
const invisiveisLocal = ref<string[]>([])
function sincronizarEstado() {
const todos = props.rotulosColunas;
const todos = props.rotulosColunas
const configTemDados =
(props.configInicial.visiveis?.length ?? 0) > 0 ||
(props.configInicial.invisiveis?.length ?? 0) > 0;
(props.configInicial.invisiveis?.length ?? 0) > 0
const invisiveisPadraoSet = new Set(
props.colunas.filter((c) => c.visivel === false).map((c) => c.rotulo)
);
props.colunas.filter((c) => c.visivel === false).map((c) => c.rotulo),
)
const invisiveisSet = configTemDados
? new Set(props.configInicial.invisiveis ?? [])
: invisiveisPadraoSet;
: invisiveisPadraoSet
const baseVisiveis = todos.filter((r) => !invisiveisSet.has(r));
const baseVisiveis = todos.filter((r) => !invisiveisSet.has(r))
// ordenação: aplica ordem salva (visiveis) e adiciona novas ao final
const ordemSalva = props.configInicial.visiveis ?? [];
const setVis = new Set(baseVisiveis);
const ordenadas: string[] = [];
const ordemSalva = props.configInicial.visiveis ?? []
const setVis = new Set(baseVisiveis)
const ordenadas: string[] = []
for (const r of ordemSalva) {
if (setVis.has(r)) ordenadas.push(r);
if (setVis.has(r)) ordenadas.push(r)
}
for (const r of baseVisiveis) {
if (!ordenadas.includes(r)) ordenadas.push(r);
if (!ordenadas.includes(r)) ordenadas.push(r)
}
visiveisLocal.value = ordenadas;
visiveisLocal.value = ordenadas
// invisíveis: somente as que existem na tabela
invisiveisLocal.value = todos.filter((r) => invisiveisSet.has(r));
invisiveisLocal.value = todos.filter((r) => invisiveisSet.has(r))
}
watch(
() => [props.aberto, props.rotulosColunas, props.configInicial, props.colunas] as const,
() =>
[
props.aberto,
props.rotulosColunas,
props.configInicial,
props.colunas,
] as const,
() => {
if (props.aberto) sincronizarEstado();
if (props.aberto) sincronizarEstado()
},
{ deep: true, immediate: true }
);
{ deep: true, immediate: true },
)
function emitFechar() {
emit("fechar");
emit("fechar")
}
function emitSalvar() {
emit("salvar", {
visiveis: [...visiveisLocal.value],
invisiveis: [...invisiveisLocal.value],
});
})
}
function writeDragData(e: DragEvent, payload: DragPayload) {
try {
e.dataTransfer?.setData(DRAG_MIME, JSON.stringify(payload));
e.dataTransfer?.setData("text/plain", payload.rotulo);
e.dataTransfer!.effectAllowed = "move";
e.dataTransfer?.setData(DRAG_MIME, JSON.stringify(payload))
e.dataTransfer?.setData("text/plain", payload.rotulo)
if (e.dataTransfer) {
e.dataTransfer.effectAllowed = "move"
}
} catch {
// ignore
}
@ -183,72 +192,93 @@ export default defineComponent({
function readDragData(e: DragEvent): DragPayload | null {
try {
const raw = e.dataTransfer?.getData(DRAG_MIME);
if (!raw) return null;
const parsed = JSON.parse(raw);
if (!parsed || typeof parsed.rotulo !== "string" || (parsed.origem !== "visiveis" && parsed.origem !== "invisiveis")) {
return null;
const raw = e.dataTransfer?.getData(DRAG_MIME)
if (!raw) return null
const parsed = JSON.parse(raw)
if (
!parsed ||
typeof parsed.rotulo !== "string" ||
(parsed.origem !== "visiveis" && parsed.origem !== "invisiveis")
) {
return null
}
return parsed as DragPayload;
return parsed as DragPayload
} catch {
return null;
return null
}
}
function removerDaOrigem(payload: DragPayload) {
const origemArr = payload.origem === "visiveis" ? visiveisLocal.value : invisiveisLocal.value;
const idx = origemArr.indexOf(payload.rotulo);
if (idx >= 0) origemArr.splice(idx, 1);
const origemArr =
payload.origem === "visiveis"
? visiveisLocal.value
: invisiveisLocal.value
const idx = origemArr.indexOf(payload.rotulo)
if (idx >= 0) origemArr.splice(idx, 1)
}
function inserirNoDestino(destino: OrigemLista, rotulo: string, index: number | null) {
const arr = destino === "visiveis" ? visiveisLocal.value : invisiveisLocal.value;
function inserirNoDestino(
destino: OrigemLista,
rotulo: string,
index: number | null,
) {
const arr =
destino === "visiveis" ? visiveisLocal.value : invisiveisLocal.value
// remove duplicatas
const existing = arr.indexOf(rotulo);
if (existing >= 0) arr.splice(existing, 1);
const existing = arr.indexOf(rotulo)
if (existing >= 0) arr.splice(existing, 1)
if (index === null || index < 0 || index > arr.length) {
arr.push(rotulo);
arr.push(rotulo)
} else {
arr.splice(index, 0, rotulo);
arr.splice(index, 0, rotulo)
}
}
function onDragStart(e: DragEvent, rotulo: string, origem: OrigemLista, index: number) {
writeDragData(e, { rotulo, origem, index });
function onDragStart(
e: DragEvent,
rotulo: string,
origem: OrigemLista,
index: number,
) {
writeDragData(e, { rotulo, origem, index })
}
function onDropItem(e: DragEvent, destino: OrigemLista, index: number) {
const payload = readDragData(e);
if (!payload) return;
const payload = readDragData(e)
if (!payload) return
// remove da origem e insere no destino na posição do item
removerDaOrigem(payload);
inserirNoDestino(destino, payload.rotulo, index);
removerDaOrigem(payload)
inserirNoDestino(destino, payload.rotulo, index)
// garante que uma coluna não fique nos 2 lados
if (destino === "visiveis") {
const idxInv = invisiveisLocal.value.indexOf(payload.rotulo);
if (idxInv >= 0) invisiveisLocal.value.splice(idxInv, 1);
const idxInv = invisiveisLocal.value.indexOf(payload.rotulo)
if (idxInv >= 0) invisiveisLocal.value.splice(idxInv, 1)
} else {
const idxVis = visiveisLocal.value.indexOf(payload.rotulo);
if (idxVis >= 0) visiveisLocal.value.splice(idxVis, 1);
const idxVis = visiveisLocal.value.indexOf(payload.rotulo)
if (idxVis >= 0) visiveisLocal.value.splice(idxVis, 1)
}
}
function onDropLista(e: DragEvent, destino: OrigemLista, _index: number | null) {
const payload = readDragData(e);
if (!payload) return;
function onDropLista(
e: DragEvent,
destino: OrigemLista,
_index: number | null,
) {
const payload = readDragData(e)
if (!payload) return
removerDaOrigem(payload);
inserirNoDestino(destino, payload.rotulo, null);
removerDaOrigem(payload)
inserirNoDestino(destino, payload.rotulo, null)
if (destino === "visiveis") {
const idxInv = invisiveisLocal.value.indexOf(payload.rotulo);
if (idxInv >= 0) invisiveisLocal.value.splice(idxInv, 1);
const idxInv = invisiveisLocal.value.indexOf(payload.rotulo)
if (idxInv >= 0) invisiveisLocal.value.splice(idxInv, 1)
} else {
const idxVis = visiveisLocal.value.indexOf(payload.rotulo);
if (idxVis >= 0) visiveisLocal.value.splice(idxVis, 1);
const idxVis = visiveisLocal.value.indexOf(payload.rotulo)
if (idxVis >= 0) visiveisLocal.value.splice(idxVis, 1)
}
}
@ -260,9 +290,9 @@ export default defineComponent({
onDragStart,
onDropItem,
onDropLista,
};
}
},
});
})
</script>
<style>