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

@ -12,25 +12,25 @@
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import { codigosResposta } from "p-respostas";
import { BadgeCheck, Eye, Pencil, Plus, Trash2 } from "lucide-vue-next";
import { celulaTabela, EliTabela } from "@/componentes/EliTabela";
import type { ComponenteEntrada } from "@/componentes/EliEntrada/tiposEntradas";
import type { tipoEliTabelaConsulta } from "@/componentes/EliTabela";
import type { tipoFiltro } from "@/componentes/EliTabela/types-eli-tabela";
import { BadgeCheck, Eye, Pencil, Plus, Trash2 } from "lucide-vue-next"
import { codigosResposta } from "p-respostas"
import { defineComponent, ref } from "vue"
import type { ComponenteEntrada } from "@/componentes/EliEntrada/tiposEntradas"
import type { tipoEliTabelaConsulta } from "@/componentes/EliTabela"
import { celulaTabela, EliTabela } from "@/componentes/EliTabela"
import type { tipoFiltro } from "@/componentes/EliTabela/types-eli-tabela"
type Linha = {
empreendedor: string;
empreendimento: string;
documento: string;
email: string;
telefone: string;
faturamento: number;
peso_kg: number;
criado_em: string;
atualizado_em: string;
};
empreendedor: string
empreendimento: string
documento: string
email: string
telefone: string
faturamento: number
peso_kg: number
criado_em: string
atualizado_em: string
}
export default defineComponent({
name: "TabelaPlayground",
@ -42,7 +42,7 @@ export default defineComponent({
cor: "#2563eb",
rotulo: "Detalhes",
acao: (linha) => {
console.log("Visualizar detalhes de", linha.empreendedor);
console.log("Visualizar detalhes de", linha.empreendedor)
},
},
{
@ -50,18 +50,19 @@ export default defineComponent({
cor: "#dc2626",
rotulo: "Remover",
acao: (linha) => {
console.log("Remover cadastro de", linha.empreendedor);
console.log("Remover cadastro de", linha.empreendedor)
},
exibir: (linha) => !linha.empreendimento.toLowerCase().includes("café"),
},
];
]
const linhasPadrao = ref<Linha[]>([
{
empreendedor: "Maria Silva",
empreendimento: "Doces da Maria",
documento: "12.345.678/0001-90",
email: "contato.comercial.super.longo@doces-da-maria-exemplo-muito-grande.com.br",
email:
"contato.comercial.super.longo@doces-da-maria-exemplo-muito-grande.com.br",
telefone: "(11) 91234-5678",
faturamento: 12500.5,
peso_kg: 12.4,
@ -288,14 +289,16 @@ export default defineComponent({
criado_em: "2026-01-01T09:00:00-03:00",
atualizado_em: "2026-01-17T09:30:00-03:00",
},
]);
])
// Incrementamos a chave para forçar o EliTabela a recarregar a consulta.
// (Como o componente não expõe um método público de refresh)
const versaoTabelaOk = ref(0);
const versaoTabelaOk = ref(0)
function adicionarLinha() {
const proximo = linhasPadrao.value.length + 1;
// biome-ignore lint/suspicious/noExplicitAny: playground
function adicionarLinha(params?: any) {
if (params) console.log("Adicionar Linha, parametros:", params)
const proximo = linhasPadrao.value.length + 1
linhasPadrao.value.unshift({
empreendedor: `Novo Empreendedor ${proximo}`,
@ -307,42 +310,47 @@ export default defineComponent({
peso_kg: 0,
criado_em: new Date().toISOString(),
atualizado_em: new Date().toISOString(),
});
})
versaoTabelaOk.value++;
versaoTabelaOk.value++
}
const filtrarPorBusca = (linhas: Linha[], texto?: string) => {
const termo = texto?.trim().toLowerCase();
const termo = texto?.trim().toLowerCase()
if (!termo) {
return [...linhas];
return [...linhas]
}
return linhas.filter((linha) => {
const campos = [linha.empreendedor, linha.empreendimento];
return campos.some((valor) => valor.toLowerCase().includes(termo));
});
};
const campos = [linha.empreendedor, linha.empreendimento]
return campos.some((valor) => valor.toLowerCase().includes(termo))
})
}
const compararOperador = (operador: string, valorLinha: any, valorFiltro: any): boolean => {
const compararOperador = (
operador: string,
// biome-ignore lint/suspicious/noExplicitAny: playground
valorLinha: any,
// biome-ignore lint/suspicious/noExplicitAny: playground
valorFiltro: any,
): boolean => {
switch (operador) {
case "=":
return valorLinha == valorFiltro;
return valorLinha == valorFiltro
case "!=":
return valorLinha != valorFiltro;
return valorLinha != valorFiltro
case ">":
return Number(valorLinha) > Number(valorFiltro);
return Number(valorLinha) > Number(valorFiltro)
case ">=":
return Number(valorLinha) >= Number(valorFiltro);
return Number(valorLinha) >= Number(valorFiltro)
case "<":
return Number(valorLinha) < Number(valorFiltro);
return Number(valorLinha) < Number(valorFiltro)
case "<=":
return Number(valorLinha) <= Number(valorFiltro);
return Number(valorLinha) <= Number(valorFiltro)
case "like": {
const a = String(valorLinha ?? "").toLowerCase();
const b = String(valorFiltro ?? "").toLowerCase();
return a.includes(b);
const a = String(valorLinha ?? "").toLowerCase()
const b = String(valorFiltro ?? "").toLowerCase()
return a.includes(b)
}
case "in": {
const arr = Array.isArray(valorFiltro)
@ -350,93 +358,129 @@ export default defineComponent({
: String(valorFiltro ?? "")
.split(",")
.map((s) => s.trim())
.filter(Boolean);
return arr.includes(String(valorLinha));
.filter(Boolean)
return arr.includes(String(valorLinha))
}
case "isNull":
return valorLinha === null || valorLinha === undefined || valorLinha === "";
return (
valorLinha === null || valorLinha === undefined || valorLinha === ""
)
default:
return true;
return true
}
};
}
const filtrarPorFiltrosAvancados = (linhas: Linha[], filtros?: tipoFiltro[]) => {
const lista = [...linhas];
if (!filtros?.length) return lista;
const filtrarPorFiltrosAvancados = (
linhas: Linha[],
filtros?: tipoFiltro[],
) => {
const lista = [...linhas]
if (!filtros?.length) return lista
// biome-ignore lint/suspicious/noExplicitAny: playground
return lista.filter((linha: any) => {
return filtros.every((f) => {
const vLinha = linha?.[String((f as any).coluna)];
return compararOperador(String((f as any).operador), vLinha, (f as any).valor);
});
});
};
// biome-ignore lint/suspicious/noExplicitAny: playground
const vLinha = linha?.[String((f as any).coluna)]
return compararOperador(
// biome-ignore lint/suspicious/noExplicitAny: playground
String((f as any).operador),
vLinha,
// biome-ignore lint/suspicious/noExplicitAny: playground
(f as any).valor,
)
})
})
}
const ordenarLinhas = (linhas: Linha[], parametros?: { coluna_ordem?: keyof Linha; direcao_ordem?: "asc" | "desc" }) => {
if (!parametros?.coluna_ordem) return [...linhas];
const ordenarLinhas = (
linhas: Linha[],
parametros?: {
coluna_ordem?: keyof Linha
direcao_ordem?: "asc" | "desc"
},
) => {
if (!parametros?.coluna_ordem) return [...linhas]
const direcao = parametros.direcao_ordem ?? "asc";
const chave = parametros.coluna_ordem;
const multiplicador = direcao === "asc" ? 1 : -1;
const direcao = parametros.direcao_ordem ?? "asc"
const chave = parametros.coluna_ordem
const multiplicador = direcao === "asc" ? 1 : -1
return [...linhas].sort((a, b) => {
const valorA = a[chave];
const valorB = b[chave];
const valorA = a[chave]
const valorB = b[chave]
return (
multiplicador *
String(valorA ?? "").localeCompare(String(valorB ?? ""), "pt-BR", {
sensitivity: "base",
})
);
});
};
)
})
}
const tabelaOk: tipoEliTabelaConsulta<Linha> = {
nome: 'Exemplo',
nome: "Exemplo",
registros_por_consulta: 10,
mostrarCaixaDeBusca: true,
acoesTabela: [
{
posicao: "superior",
icone: Plus,
cor: "#16a34a",
rotulo: "Novo",
rotulo: "Novo (Superior)",
acao: adicionarLinha,
},
{
posicao: "inferior",
icone: Plus,
cor: "#2563eb",
rotulo: "Novo (Inferior)",
// biome-ignore lint/suspicious/noExplicitAny: playground
acao: (params: any) => {
console.log("Ação inferior clicada com params:", params)
adicionarLinha(params)
},
},
],
colunas: [
{
rotulo: "Empreendedor",
celula: (l) => celulaTabela('textoSimples', { texto: l.empreendedor }),
celula: (l) =>
celulaTabela("textoSimples", { texto: l.empreendedor }),
coluna_ordem: "empreendedor",
visivel: true,
},
{
rotulo: "Empreendimento",
celula: (l) => celulaTabela('textoSimples', { texto: l.empreendimento }),
celula: (l) =>
celulaTabela("textoSimples", { texto: l.empreendimento }),
coluna_ordem: "empreendimento",
visivel: true,
},
{
rotulo: "Documento",
celula: (l) => celulaTabela('textoSimples', { texto: l.documento }),
celula: (l) => celulaTabela("textoSimples", { texto: l.documento }),
coluna_ordem: "documento",
visivel: false,
},
{
rotulo: "E-mail",
celula: (l) => celulaTabela('textoTruncado', {
texto: l.email, acao: () => {
// Exemplo de ação: poderia abrir detalhes
alert(`Clicou em ${l.email}`);
}
}),
celula: (l) =>
celulaTabela("textoTruncado", {
texto: l.email,
acao: () => {
// Exemplo de ação: poderia abrir detalhes
alert(`Clicou em ${l.email}`)
},
}),
coluna_ordem: "email",
visivel: true,
},
{
rotulo: "Telefone",
celula: (l) => celulaTabela('textoSimples', { texto: l.telefone }),
celula: (l) => celulaTabela("textoSimples", { texto: l.telefone }),
coluna_ordem: "telefone",
visivel: true,
},
@ -447,7 +491,8 @@ export default defineComponent({
numero: l.faturamento,
prefixo: "R$",
// Exemplo de ação (clicável)
acao: () => alert(`Faturamento de ${l.empreendedor}: R$ ${l.faturamento}`),
acao: () =>
alert(`Faturamento de ${l.empreendedor}: R$ ${l.faturamento}`),
}),
visivel: true,
},
@ -475,7 +520,7 @@ export default defineComponent({
cor: "primary",
icone: Pencil,
acao: () => {
alert(`Editar ${l.empreendedor}`);
alert(`Editar ${l.empreendedor}`)
},
},
],
@ -508,39 +553,46 @@ export default defineComponent({
coluna: "empreendedor",
operador: "like",
entrada: ["texto", { rotulo: "Empreendedor" }] as ComponenteEntrada,
},
{
coluna: "documento",
operador: "like",
entrada: ["texto", { rotulo: "Documento", formato: "cpfCnpj" }] as ComponenteEntrada,
entrada: [
"texto",
{ rotulo: "Documento", formato: "cpfCnpj" },
] as ComponenteEntrada,
},
{
coluna: "email",
operador: "like",
entrada: ["texto", { rotulo: "E-mail", formato: "email" }] as ComponenteEntrada,
entrada: [
"texto",
{ rotulo: "E-mail", formato: "email" },
] as ComponenteEntrada,
},
],
consulta: async (parametrosConsulta) => {
// Agora a EliTabela envia paginação/ordenação/busca OU filtros avançados para a consulta.
// (busca tem prioridade; quando existe texto_busca, filtros não vêm no payload)
const limite = Math.max(1, Number(parametrosConsulta?.limit ?? 10));
const offset = Math.max(0, Number(parametrosConsulta?.offSet ?? 0));
const limite = Math.max(1, Number(parametrosConsulta?.limit ?? 10))
const offset = Math.max(0, Number(parametrosConsulta?.offSet ?? 0))
// 1) filtra (busca OU filtro avançado)
const base = [...linhasPadrao.value];
const base = [...linhasPadrao.value]
const filtradas = parametrosConsulta?.texto_busca
? filtrarPorBusca(base, parametrosConsulta.texto_busca)
: filtrarPorFiltrosAvancados(base, (parametrosConsulta as any)?.filtros);
: filtrarPorFiltrosAvancados(
base,
// biome-ignore lint/suspicious/noExplicitAny: playground
(parametrosConsulta as any)?.filtros,
)
// 2) ordena
const ordenadas = ordenarLinhas(filtradas, parametrosConsulta);
const ordenadas = ordenarLinhas(filtradas, parametrosConsulta)
// 3) pagina
const valores = ordenadas.slice(offset, offset + limite);
const valores = ordenadas.slice(offset, offset + limite)
return {
cod: codigosResposta.sucesso,
@ -551,9 +603,9 @@ export default defineComponent({
quantidade: ordenadas.length,
valores,
},
};
}
},
};
}
const tabelaVazia: tipoEliTabelaConsulta<Linha> = {
nome: "Exemplo",
@ -570,11 +622,11 @@ export default defineComponent({
quantidade: 0,
valores: [],
},
};
}
},
mensagemVazio: "Nada para mostrar aqui.",
acoesLinha: acoesLinha,
};
}
const tabelaErro: tipoEliTabelaConsulta<Linha> = {
nome: "Exemplo",
@ -589,13 +641,13 @@ export default defineComponent({
eErro: true,
mensagem: "Falha ao buscar dados",
valor: undefined,
};
}
},
};
}
return { tabelaOk, tabelaVazia, tabelaErro, versaoTabelaOk };
return { tabelaOk, tabelaVazia, tabelaErro, versaoTabelaOk }
},
});
})
</script>
<style scoped>