aplicado Filtro
This commit is contained in:
parent
e7357e064a
commit
1e3c4026e8
12 changed files with 1507 additions and 12626 deletions
|
|
@ -14,19 +14,7 @@
|
|||
</div>
|
||||
|
||||
<div v-else class="eli-tabela-modal-filtro__lista">
|
||||
<div v-for="(linha, idx) in linhas" :key="idx" class="eli-tabela-modal-filtro__linha">
|
||||
<select v-model="linha.coluna" class="eli-tabela-modal-filtro__select">
|
||||
<option v-for="opt in colunasDisponiveis" :key="String(opt)" :value="opt">
|
||||
{{ String(opt) }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<select v-model="linha.operador" class="eli-tabela-modal-filtro__select">
|
||||
<option v-for="op in operadoresDisponiveis" :key="op" :value="op">
|
||||
{{ op }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<div v-for="(linha, idx) in linhas" :key="String(linha.coluna)" class="eli-tabela-modal-filtro__linha">
|
||||
<div class="eli-tabela-modal-filtro__entrada">
|
||||
<component
|
||||
:is="componenteEntrada(linha.entrada)"
|
||||
|
|
@ -49,8 +37,19 @@
|
|||
</div>
|
||||
|
||||
<div class="eli-tabela-modal-filtro__acoes">
|
||||
<button type="button" class="eli-tabela-modal-filtro__botao" @click="adicionar" :disabled="!filtrosBase.length">
|
||||
Adicionar filtro
|
||||
<select v-model="colunaParaAdicionar" class="eli-tabela-modal-filtro__select" :disabled="!opcoesParaAdicionar.length">
|
||||
<option disabled value="">Selecione um filtro…</option>
|
||||
<option v-for="o in opcoesParaAdicionar" :key="String(o.coluna)" :value="String(o.coluna)">
|
||||
{{ rotuloDoFiltro(o) }}
|
||||
</option>
|
||||
</select>
|
||||
<button
|
||||
type="button"
|
||||
class="eli-tabela-modal-filtro__botao"
|
||||
@click="adicionar"
|
||||
:disabled="!colunaParaAdicionar"
|
||||
>
|
||||
Adicionar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -71,20 +70,17 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType, ref, watch } from "vue";
|
||||
import { operadores as Operadores } from "p-comuns";
|
||||
|
||||
import { computed, defineComponent, PropType, ref, watch } from "vue";
|
||||
import { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora } from "../EliEntrada";
|
||||
import type { ComponenteEntrada, TipoEntrada } from "../EliEntrada/tiposEntradas";
|
||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
||||
|
||||
type Operador = keyof typeof Operadores;
|
||||
type FiltroBase<T> = NonNullable<EliTabelaConsulta<T>["filtroAvancado"]>[number];
|
||||
|
||||
type LinhaFiltro<T> = {
|
||||
coluna: keyof T;
|
||||
operador: Operador;
|
||||
entrada: ComponenteEntrada;
|
||||
operador: string;
|
||||
valor: any;
|
||||
};
|
||||
|
||||
|
|
@ -92,6 +88,11 @@ function isTipoEntrada(v: unknown): v is TipoEntrada {
|
|||
return v === "texto" || v === "numero" || v === "dataHora";
|
||||
}
|
||||
|
||||
function rotuloDoFiltro(f: FiltroBase<any>) {
|
||||
const rotulo = (f?.entrada?.[1] as any)?.rotulo;
|
||||
return rotulo ? String(rotulo) : String(f?.coluna ?? "Filtro");
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: "EliTabelaModalFiltroAvancado",
|
||||
props: {
|
||||
|
|
@ -113,9 +114,14 @@ export default defineComponent({
|
|||
setup(props, { emit }) {
|
||||
const linhas = ref<Array<LinhaFiltro<any>>>([]);
|
||||
|
||||
const operadoresDisponiveis = Object.keys(Operadores) as Operador[];
|
||||
const colunaParaAdicionar = ref<string>("");
|
||||
|
||||
const colunasDisponiveis = ref<string[]>([]);
|
||||
const colunasDisponiveis = computed(() => (props.filtrosBase ?? []).map((b) => String(b.coluna)));
|
||||
|
||||
const opcoesParaAdicionar = computed(() => {
|
||||
const usadas = new Set(linhas.value.map((l) => String(l.coluna)));
|
||||
return (props.filtrosBase ?? []).filter((b) => !usadas.has(String(b.coluna)));
|
||||
});
|
||||
|
||||
function componenteEntrada(entrada: ComponenteEntrada) {
|
||||
const tipo = entrada?.[0];
|
||||
|
|
@ -125,12 +131,8 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
function opcoesEntrada(entrada: ComponenteEntrada) {
|
||||
const opcoes = entrada?.[1] as any;
|
||||
// garante rotulo para não ficar vazio visualmente dentro do modal
|
||||
if (opcoes && typeof opcoes === "object" && !opcoes.rotulo) {
|
||||
return { ...opcoes, rotulo: "Valor" };
|
||||
}
|
||||
return opcoes ?? { rotulo: "Valor" };
|
||||
// o rótulo vem do próprio componente (entrada[1].rotulo)
|
||||
return (entrada?.[1] as any) ?? { rotulo: "" };
|
||||
}
|
||||
|
||||
function valorInicialPorEntrada(entrada: ComponenteEntrada) {
|
||||
|
|
@ -141,13 +143,13 @@ export default defineComponent({
|
|||
|
||||
function normalizarModelo() {
|
||||
const base = props.filtrosBase ?? [];
|
||||
colunasDisponiveis.value = base.map((b) => String(b.coluna));
|
||||
|
||||
const modelo = Array.isArray(props.modelo) ? props.modelo : [];
|
||||
linhas.value = modelo.map((m: any) => {
|
||||
const entrada = m.entrada as ComponenteEntrada;
|
||||
const col = m.coluna as any;
|
||||
const op = (m.operador ?? "=") as Operador;
|
||||
// operador vem travado no base
|
||||
const baseItem = base.find((b) => String(b.coluna) === String(m.coluna)) ?? base[0];
|
||||
const entrada = (baseItem?.entrada ?? m.entrada) as ComponenteEntrada;
|
||||
const col = (baseItem?.coluna ?? m.coluna) as any;
|
||||
const op = String(baseItem?.operador ?? "=");
|
||||
const val = m.valor ?? valorInicialPorEntrada(entrada);
|
||||
|
||||
return {
|
||||
|
|
@ -159,26 +161,12 @@ export default defineComponent({
|
|||
});
|
||||
|
||||
// se vazio e existe base, adiciona 1 linha default
|
||||
if (!linhas.value.length && base.length) {
|
||||
const b0 = base[0];
|
||||
linhas.value = [
|
||||
{
|
||||
coluna: b0.coluna as any,
|
||||
operador: (b0.operador as any) ?? "=",
|
||||
entrada: b0.entrada,
|
||||
valor: valorInicialPorEntrada(b0.entrada),
|
||||
},
|
||||
];
|
||||
}
|
||||
// não auto-adiciona; usuário escolhe quais filtros quer usar
|
||||
|
||||
// se algum filtro mudou a coluna para valor inválido, ajusta
|
||||
for (const l of linhas.value) {
|
||||
if (!colunasDisponiveis.value.includes(String(l.coluna))) {
|
||||
l.coluna = (base[0]?.coluna as any) ?? l.coluna;
|
||||
}
|
||||
if (!operadoresDisponiveis.includes(l.operador)) {
|
||||
l.operador = "=";
|
||||
}
|
||||
if (!colunasDisponiveis.value.includes(String(l.coluna))) continue;
|
||||
l.operador = String((base.find((b) => String(b.coluna) === String(l.coluna))?.operador ?? "="));
|
||||
// sanity
|
||||
if (l.entrada && !isTipoEntrada(l.entrada[0])) {
|
||||
l.entrada = ["texto", { rotulo: "Valor" }] as any;
|
||||
|
|
@ -195,14 +183,20 @@ export default defineComponent({
|
|||
);
|
||||
|
||||
function adicionar() {
|
||||
if (!props.filtrosBase.length) return;
|
||||
const b0 = props.filtrosBase[0];
|
||||
if (!colunaParaAdicionar.value) return;
|
||||
const b0 = (props.filtrosBase ?? []).find((b) => String(b.coluna) === String(colunaParaAdicionar.value));
|
||||
if (!b0) return;
|
||||
// evita repetição
|
||||
if (linhas.value.some((l) => String(l.coluna) === String(b0.coluna))) return;
|
||||
|
||||
linhas.value.push({
|
||||
coluna: b0.coluna as any,
|
||||
operador: (b0.operador as any) ?? "=",
|
||||
entrada: b0.entrada,
|
||||
operador: String(b0.operador ?? "="),
|
||||
valor: valorInicialPorEntrada(b0.entrada),
|
||||
});
|
||||
|
||||
colunaParaAdicionar.value = "";
|
||||
}
|
||||
|
||||
function remover(idx: number) {
|
||||
|
|
@ -222,8 +216,6 @@ export default defineComponent({
|
|||
"salvar",
|
||||
linhas.value.map((l) => ({
|
||||
coluna: l.coluna,
|
||||
operador: l.operador,
|
||||
entrada: l.entrada,
|
||||
valor: l.valor,
|
||||
}))
|
||||
);
|
||||
|
|
@ -231,15 +223,17 @@ export default defineComponent({
|
|||
|
||||
return {
|
||||
linhas,
|
||||
operadoresDisponiveis,
|
||||
colunasDisponiveis,
|
||||
opcoesParaAdicionar,
|
||||
colunaParaAdicionar,
|
||||
componenteEntrada,
|
||||
opcoesEntrada,
|
||||
adicionar,
|
||||
remover,
|
||||
// exibimos operador fixo só como texto
|
||||
emitFechar,
|
||||
emitSalvar,
|
||||
emitLimpar,
|
||||
rotuloDoFiltro,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
@ -312,7 +306,7 @@ export default defineComponent({
|
|||
|
||||
.eli-tabela-modal-filtro__linha {
|
||||
display: grid;
|
||||
grid-template-columns: 220px 120px 1fr 34px;
|
||||
grid-template-columns: 1fr 34px;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue