aplicado Filtro
This commit is contained in:
parent
e7357e064a
commit
1e3c4026e8
12 changed files with 1507 additions and 12626 deletions
2
dist/eli-vue.css
vendored
2
dist/eli-vue.css
vendored
File diff suppressed because one or more lines are too long
13786
dist/eli-vue.es.js
vendored
13786
dist/eli-vue.es.js
vendored
File diff suppressed because it is too large
Load diff
72
dist/eli-vue.umd.js
vendored
72
dist/eli-vue.umd.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -7,8 +7,6 @@ import { PropType } from "vue";
|
||||||
import type { EliColuna } from "./types-eli-tabela";
|
import type { EliColuna } from "./types-eli-tabela";
|
||||||
/** Tipos da configuração/contrato da tabela */
|
/** Tipos da configuração/contrato da tabela */
|
||||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
||||||
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
|
||||||
import { operadores as Operadores } from "p-comuns";
|
|
||||||
import { type EliTabelaColunasConfig } from "./colunasStorage";
|
import { type EliTabelaColunasConfig } from "./colunasStorage";
|
||||||
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
/** Configuração principal da tabela (colunas, consulta e ações) */
|
/** Configuração principal da tabela (colunas, consulta e ações) */
|
||||||
|
|
@ -61,66 +59,12 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
modalFiltroAberto: import("vue").Ref<boolean, boolean>;
|
modalFiltroAberto: import("vue").Ref<boolean, boolean>;
|
||||||
filtrosUi: import("vue").Ref<{
|
filtrosUi: import("vue").Ref<{
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: keyof typeof Operadores;
|
|
||||||
entrada: readonly ["texto", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
limiteCaracteres?: number | undefined;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep" | undefined;
|
|
||||||
}] | readonly ["dataHora", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
modo?: "data" | "dataHora" | undefined;
|
|
||||||
limpavel?: boolean | undefined;
|
|
||||||
erro?: boolean | undefined;
|
|
||||||
mensagensErro?: string | string[] | undefined;
|
|
||||||
dica?: string | undefined;
|
|
||||||
dicaPersistente?: boolean | undefined;
|
|
||||||
min?: string | undefined;
|
|
||||||
max?: string | undefined;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade | undefined;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante | undefined;
|
|
||||||
}] | readonly ["numero", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
sufixo?: string | undefined;
|
|
||||||
prefixo?: string | undefined;
|
|
||||||
precisao?: number | undefined;
|
|
||||||
}];
|
|
||||||
valor: any;
|
valor: any;
|
||||||
}[], {
|
}[], {
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: keyof typeof Operadores;
|
|
||||||
entrada: ComponenteEntrada;
|
|
||||||
valor: any;
|
valor: any;
|
||||||
}[] | {
|
}[] | {
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: keyof typeof Operadores;
|
|
||||||
entrada: readonly ["texto", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
limiteCaracteres?: number | undefined;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep" | undefined;
|
|
||||||
}] | readonly ["dataHora", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
modo?: "data" | "dataHora" | undefined;
|
|
||||||
limpavel?: boolean | undefined;
|
|
||||||
erro?: boolean | undefined;
|
|
||||||
mensagensErro?: string | string[] | undefined;
|
|
||||||
dica?: string | undefined;
|
|
||||||
dicaPersistente?: boolean | undefined;
|
|
||||||
min?: string | undefined;
|
|
||||||
max?: string | undefined;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade | undefined;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante | undefined;
|
|
||||||
}] | readonly ["numero", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
sufixo?: string | undefined;
|
|
||||||
prefixo?: string | undefined;
|
|
||||||
precisao?: number | undefined;
|
|
||||||
}];
|
|
||||||
valor: any;
|
valor: any;
|
||||||
}[]>;
|
}[]>;
|
||||||
salvarFiltrosAvancados: (novo: any[]) => void;
|
salvarFiltrosAvancados: (novo: any[]) => void;
|
||||||
|
|
@ -728,9 +672,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
filtrosBase: {
|
filtrosBase: {
|
||||||
type: PropType<Array<{
|
type: PropType<Array<{
|
||||||
|
rotulo: string;
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: Operadores | keyof typeof Operadores;
|
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
||||||
entrada: ComponenteEntrada;
|
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
||||||
}>>;
|
}>>;
|
||||||
required: true;
|
required: true;
|
||||||
};
|
};
|
||||||
|
|
@ -741,7 +686,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
}>, {
|
}>, {
|
||||||
linhas: import("vue").Ref<{
|
linhas: import("vue").Ref<{
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: "in" | "=" | "!=" | ">" | ">=" | "<" | "<=" | "like" | "isNull";
|
|
||||||
entrada: readonly ["texto", {
|
entrada: readonly ["texto", {
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
placeholder?: string | undefined;
|
placeholder?: string | undefined;
|
||||||
|
|
@ -767,15 +711,15 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
prefixo?: string | undefined;
|
prefixo?: string | undefined;
|
||||||
precisao?: number | undefined;
|
precisao?: number | undefined;
|
||||||
}];
|
}];
|
||||||
|
operador: string;
|
||||||
valor: any;
|
valor: any;
|
||||||
}[], {
|
}[], {
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: "in" | "=" | "!=" | ">" | ">=" | "<" | "<=" | "like" | "isNull";
|
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
||||||
entrada: ComponenteEntrada;
|
operador: string;
|
||||||
valor: any;
|
valor: any;
|
||||||
}[] | {
|
}[] | {
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: "in" | "=" | "!=" | ">" | ">=" | "<" | "<=" | "like" | "isNull";
|
|
||||||
entrada: readonly ["texto", {
|
entrada: readonly ["texto", {
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
placeholder?: string | undefined;
|
placeholder?: string | undefined;
|
||||||
|
|
@ -801,11 +745,17 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
prefixo?: string | undefined;
|
prefixo?: string | undefined;
|
||||||
precisao?: number | undefined;
|
precisao?: number | undefined;
|
||||||
}];
|
}];
|
||||||
|
operador: string;
|
||||||
valor: any;
|
valor: any;
|
||||||
}[]>;
|
}[]>;
|
||||||
operadoresDisponiveis: ("in" | "=" | "!=" | ">" | ">=" | "<" | "<=" | "like" | "isNull")[];
|
opcoesParaAdicionar: import("vue").ComputedRef<{
|
||||||
colunasDisponiveis: import("vue").Ref<string[], string[]>;
|
rotulo: string;
|
||||||
componenteEntrada: (entrada: ComponenteEntrada) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
coluna: string | number | symbol;
|
||||||
|
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
||||||
|
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
||||||
|
}[]>;
|
||||||
|
colunaParaAdicionar: import("vue").Ref<string, string>;
|
||||||
|
componenteEntrada: (entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
value: {
|
value: {
|
||||||
type: PropType<string | null | undefined>;
|
type: PropType<string | null | undefined>;
|
||||||
default: undefined;
|
default: undefined;
|
||||||
|
|
@ -1150,12 +1100,18 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
modelValue: string | null;
|
modelValue: string | null;
|
||||||
desabilitado: boolean;
|
desabilitado: boolean;
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
opcoesEntrada: (entrada: ComponenteEntrada) => any;
|
opcoesEntrada: (entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada) => any;
|
||||||
adicionar: () => void;
|
adicionar: () => void;
|
||||||
remover: (idx: number) => void;
|
remover: (idx: number) => void;
|
||||||
emitFechar: () => void;
|
emitFechar: () => void;
|
||||||
emitSalvar: () => void;
|
emitSalvar: () => void;
|
||||||
emitLimpar: () => void;
|
emitLimpar: () => void;
|
||||||
|
rotuloDoFiltro: (f: {
|
||||||
|
rotulo: string;
|
||||||
|
coluna: string | number | symbol;
|
||||||
|
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
||||||
|
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
||||||
|
}) => string;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||||
fechar: () => true;
|
fechar: () => true;
|
||||||
limpar: () => true;
|
limpar: () => true;
|
||||||
|
|
@ -1167,9 +1123,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
filtrosBase: {
|
filtrosBase: {
|
||||||
type: PropType<Array<{
|
type: PropType<Array<{
|
||||||
|
rotulo: string;
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: Operadores | keyof typeof Operadores;
|
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
||||||
entrada: ComponenteEntrada;
|
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
||||||
}>>;
|
}>>;
|
||||||
required: true;
|
required: true;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
import { PropType } from "vue";
|
import { PropType } from "vue";
|
||||||
import { operadores as Operadores } from "p-comuns";
|
|
||||||
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
||||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
||||||
type Operador = keyof typeof Operadores;
|
|
||||||
type FiltroBase<T> = NonNullable<EliTabelaConsulta<T>["filtroAvancado"]>[number];
|
type FiltroBase<T> = NonNullable<EliTabelaConsulta<T>["filtroAvancado"]>[number];
|
||||||
type LinhaFiltro<T> = {
|
type LinhaFiltro<T> = {
|
||||||
coluna: keyof T;
|
coluna: keyof T;
|
||||||
operador: Operador;
|
|
||||||
entrada: ComponenteEntrada;
|
entrada: ComponenteEntrada;
|
||||||
|
operador: string;
|
||||||
valor: any;
|
valor: any;
|
||||||
};
|
};
|
||||||
|
declare function rotuloDoFiltro(f: FiltroBase<any>): string;
|
||||||
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
aberto: {
|
aberto: {
|
||||||
type: BooleanConstructor;
|
type: BooleanConstructor;
|
||||||
|
|
@ -26,7 +25,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
}>, {
|
}>, {
|
||||||
linhas: import("vue").Ref<{
|
linhas: import("vue").Ref<{
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: Operador;
|
|
||||||
entrada: readonly ["texto", {
|
entrada: readonly ["texto", {
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
placeholder?: string | undefined;
|
placeholder?: string | undefined;
|
||||||
|
|
@ -52,10 +50,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
prefixo?: string | undefined;
|
prefixo?: string | undefined;
|
||||||
precisao?: number | undefined;
|
precisao?: number | undefined;
|
||||||
}];
|
}];
|
||||||
|
operador: string;
|
||||||
valor: any;
|
valor: any;
|
||||||
}[], LinhaFiltro<any>[] | {
|
}[], LinhaFiltro<any>[] | {
|
||||||
coluna: string | number | symbol;
|
coluna: string | number | symbol;
|
||||||
operador: Operador;
|
|
||||||
entrada: readonly ["texto", {
|
entrada: readonly ["texto", {
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
placeholder?: string | undefined;
|
placeholder?: string | undefined;
|
||||||
|
|
@ -81,10 +79,16 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
prefixo?: string | undefined;
|
prefixo?: string | undefined;
|
||||||
precisao?: number | undefined;
|
precisao?: number | undefined;
|
||||||
}];
|
}];
|
||||||
|
operador: string;
|
||||||
valor: any;
|
valor: any;
|
||||||
}[]>;
|
}[]>;
|
||||||
operadoresDisponiveis: ("in" | "=" | "!=" | ">" | ">=" | "<" | "<=" | "like" | "isNull")[];
|
opcoesParaAdicionar: import("vue").ComputedRef<{
|
||||||
colunasDisponiveis: import("vue").Ref<string[], string[]>;
|
rotulo: string;
|
||||||
|
coluna: string | number | symbol;
|
||||||
|
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
||||||
|
entrada: ComponenteEntrada;
|
||||||
|
}[]>;
|
||||||
|
colunaParaAdicionar: import("vue").Ref<string, string>;
|
||||||
componenteEntrada: (entrada: ComponenteEntrada) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
componenteEntrada: (entrada: ComponenteEntrada) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
value: {
|
value: {
|
||||||
type: PropType<string | null | undefined>;
|
type: PropType<string | null | undefined>;
|
||||||
|
|
@ -436,6 +440,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
emitFechar: () => void;
|
emitFechar: () => void;
|
||||||
emitSalvar: () => void;
|
emitSalvar: () => void;
|
||||||
emitLimpar: () => void;
|
emitLimpar: () => void;
|
||||||
|
rotuloDoFiltro: typeof rotuloDoFiltro;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||||
fechar: () => true;
|
fechar: () => true;
|
||||||
limpar: () => true;
|
limpar: () => true;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
export type EliTabelaFiltroAvancadoSalvo<T> = Array<{
|
||||||
export type EliTabelaFiltroAvancadoSalvo<T> = NonNullable<EliTabelaConsulta<T>["filtroAvancado"]>;
|
coluna: keyof T;
|
||||||
|
valor: any;
|
||||||
|
}>;
|
||||||
export declare function carregarFiltroAvancado<T>(nomeTabela: string): EliTabelaFiltroAvancadoSalvo<T>;
|
export declare function carregarFiltroAvancado<T>(nomeTabela: string): EliTabelaFiltroAvancadoSalvo<T>;
|
||||||
export declare function salvarFiltroAvancado<T>(nomeTabela: string, filtros: EliTabelaFiltroAvancadoSalvo<T>): void;
|
export declare function salvarFiltroAvancado<T>(nomeTabela: string, filtros: EliTabelaFiltroAvancadoSalvo<T>): void;
|
||||||
export declare function limparFiltroAvancado(nomeTabela: string): void;
|
export declare function limparFiltroAvancado(nomeTabela: string): void;
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ export type EliTabelaConsulta<T> = {
|
||||||
}[];
|
}[];
|
||||||
/** configuração para aplicação dos filtros padrões */
|
/** configuração para aplicação dos filtros padrões */
|
||||||
filtroAvancado?: {
|
filtroAvancado?: {
|
||||||
|
rotulo: string;
|
||||||
coluna: keyof T;
|
coluna: keyof T;
|
||||||
operador: operadores | keyof typeof operadores;
|
operador: operadores | keyof typeof operadores;
|
||||||
entrada: ComponenteEntrada;
|
entrada: ComponenteEntrada;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "eli-vue",
|
"name": "eli-vue",
|
||||||
"version": "0.1.66",
|
"version": "0.1.68",
|
||||||
"private": false,
|
"private": false,
|
||||||
"main": "./dist/eli-vue.umd.js",
|
"main": "./dist/eli-vue.umd.js",
|
||||||
"module": "./dist/eli-vue.es.js",
|
"module": "./dist/eli-vue.es.js",
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,7 @@ import type { EliColuna } from "./types-eli-tabela";
|
||||||
/** Tipos da configuração/contrato da tabela */
|
/** Tipos da configuração/contrato da tabela */
|
||||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
||||||
import type { tipoFiltro } from "./types-eli-tabela";
|
import type { tipoFiltro } from "./types-eli-tabela";
|
||||||
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
// operadores usados no tipo de configuração; o operador aplicado vem travado no filtroAvancado.
|
||||||
import { operadores as Operadores } from "p-comuns";
|
|
||||||
import {
|
import {
|
||||||
carregarConfigColunas,
|
carregarConfigColunas,
|
||||||
salvarConfigColunas,
|
salvarConfigColunas,
|
||||||
|
|
@ -177,14 +176,10 @@ export default defineComponent({
|
||||||
const modalFiltroAberto = ref(false);
|
const modalFiltroAberto = ref(false);
|
||||||
type LinhaFiltroUI<T> = {
|
type LinhaFiltroUI<T> = {
|
||||||
coluna: keyof T;
|
coluna: keyof T;
|
||||||
operador: keyof typeof Operadores;
|
|
||||||
entrada: ComponenteEntrada;
|
|
||||||
valor: any;
|
valor: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
const filtrosUi = ref<Array<LinhaFiltroUI<any>>>(
|
const filtrosUi = ref<Array<LinhaFiltroUI<any>>>(carregarFiltroAvancado<any>(props.tabela.nome) as any);
|
||||||
carregarFiltroAvancado<any>(props.tabela.nome) as any
|
|
||||||
);
|
|
||||||
|
|
||||||
function abrirModalFiltro() {
|
function abrirModalFiltro() {
|
||||||
modalFiltroAberto.value = true;
|
modalFiltroAberto.value = true;
|
||||||
|
|
@ -209,15 +204,22 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
const filtrosAvancadosAtivos = computed<tipoFiltro[]>(() => {
|
const filtrosAvancadosAtivos = computed<tipoFiltro[]>(() => {
|
||||||
// converte UI -> tipoFiltro (p-comuns)
|
// Operador vem travado na definição (`tabela.filtroAvancado`).
|
||||||
|
const base = (props.tabela.filtroAvancado ?? []) as Array<{ coluna: string; operador: any }>;
|
||||||
|
|
||||||
return (filtrosUi.value ?? [])
|
return (filtrosUi.value ?? [])
|
||||||
.filter((f) => f && f.coluna && f.operador)
|
.filter((f) => f && f.coluna !== undefined)
|
||||||
.map((f) => ({
|
.map((f) => {
|
||||||
coluna: String(f.coluna),
|
const b = base.find((x) => String(x.coluna) === String(f.coluna));
|
||||||
operador: f.operador as any,
|
if (!b) return null;
|
||||||
valor: f.valor,
|
|
||||||
// sem OR no primeiro momento
|
return {
|
||||||
})) as tipoFiltro[];
|
coluna: String(b.coluna),
|
||||||
|
operador: b.operador as any,
|
||||||
|
valor: (f as any).valor,
|
||||||
|
} as tipoFiltro;
|
||||||
|
})
|
||||||
|
.filter(Boolean) as tipoFiltro[];
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Alias reativo da prop tabela */
|
/** Alias reativo da prop tabela */
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else class="eli-tabela-modal-filtro__lista">
|
<div v-else class="eli-tabela-modal-filtro__lista">
|
||||||
<div v-for="(linha, idx) in linhas" :key="idx" class="eli-tabela-modal-filtro__linha">
|
<div v-for="(linha, idx) in linhas" :key="String(linha.coluna)" 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 class="eli-tabela-modal-filtro__entrada">
|
<div class="eli-tabela-modal-filtro__entrada">
|
||||||
<component
|
<component
|
||||||
:is="componenteEntrada(linha.entrada)"
|
:is="componenteEntrada(linha.entrada)"
|
||||||
|
|
@ -49,8 +37,19 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="eli-tabela-modal-filtro__acoes">
|
<div class="eli-tabela-modal-filtro__acoes">
|
||||||
<button type="button" class="eli-tabela-modal-filtro__botao" @click="adicionar" :disabled="!filtrosBase.length">
|
<select v-model="colunaParaAdicionar" class="eli-tabela-modal-filtro__select" :disabled="!opcoesParaAdicionar.length">
|
||||||
Adicionar filtro
|
<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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -71,20 +70,17 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType, ref, watch } from "vue";
|
import { computed, defineComponent, PropType, ref, watch } from "vue";
|
||||||
import { operadores as Operadores } from "p-comuns";
|
|
||||||
|
|
||||||
import { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora } from "../EliEntrada";
|
import { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora } from "../EliEntrada";
|
||||||
import type { ComponenteEntrada, TipoEntrada } from "../EliEntrada/tiposEntradas";
|
import type { ComponenteEntrada, TipoEntrada } from "../EliEntrada/tiposEntradas";
|
||||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
||||||
|
|
||||||
type Operador = keyof typeof Operadores;
|
|
||||||
type FiltroBase<T> = NonNullable<EliTabelaConsulta<T>["filtroAvancado"]>[number];
|
type FiltroBase<T> = NonNullable<EliTabelaConsulta<T>["filtroAvancado"]>[number];
|
||||||
|
|
||||||
type LinhaFiltro<T> = {
|
type LinhaFiltro<T> = {
|
||||||
coluna: keyof T;
|
coluna: keyof T;
|
||||||
operador: Operador;
|
|
||||||
entrada: ComponenteEntrada;
|
entrada: ComponenteEntrada;
|
||||||
|
operador: string;
|
||||||
valor: any;
|
valor: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -92,6 +88,11 @@ function isTipoEntrada(v: unknown): v is TipoEntrada {
|
||||||
return v === "texto" || v === "numero" || v === "dataHora";
|
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({
|
export default defineComponent({
|
||||||
name: "EliTabelaModalFiltroAvancado",
|
name: "EliTabelaModalFiltroAvancado",
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -113,9 +114,14 @@ export default defineComponent({
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const linhas = ref<Array<LinhaFiltro<any>>>([]);
|
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) {
|
function componenteEntrada(entrada: ComponenteEntrada) {
|
||||||
const tipo = entrada?.[0];
|
const tipo = entrada?.[0];
|
||||||
|
|
@ -125,12 +131,8 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
function opcoesEntrada(entrada: ComponenteEntrada) {
|
function opcoesEntrada(entrada: ComponenteEntrada) {
|
||||||
const opcoes = entrada?.[1] as any;
|
// o rótulo vem do próprio componente (entrada[1].rotulo)
|
||||||
// garante rotulo para não ficar vazio visualmente dentro do modal
|
return (entrada?.[1] as any) ?? { rotulo: "" };
|
||||||
if (opcoes && typeof opcoes === "object" && !opcoes.rotulo) {
|
|
||||||
return { ...opcoes, rotulo: "Valor" };
|
|
||||||
}
|
|
||||||
return opcoes ?? { rotulo: "Valor" };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function valorInicialPorEntrada(entrada: ComponenteEntrada) {
|
function valorInicialPorEntrada(entrada: ComponenteEntrada) {
|
||||||
|
|
@ -141,13 +143,13 @@ export default defineComponent({
|
||||||
|
|
||||||
function normalizarModelo() {
|
function normalizarModelo() {
|
||||||
const base = props.filtrosBase ?? [];
|
const base = props.filtrosBase ?? [];
|
||||||
colunasDisponiveis.value = base.map((b) => String(b.coluna));
|
|
||||||
|
|
||||||
const modelo = Array.isArray(props.modelo) ? props.modelo : [];
|
const modelo = Array.isArray(props.modelo) ? props.modelo : [];
|
||||||
linhas.value = modelo.map((m: any) => {
|
linhas.value = modelo.map((m: any) => {
|
||||||
const entrada = m.entrada as ComponenteEntrada;
|
// operador vem travado no base
|
||||||
const col = m.coluna as any;
|
const baseItem = base.find((b) => String(b.coluna) === String(m.coluna)) ?? base[0];
|
||||||
const op = (m.operador ?? "=") as Operador;
|
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);
|
const val = m.valor ?? valorInicialPorEntrada(entrada);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -159,26 +161,12 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
|
|
||||||
// se vazio e existe base, adiciona 1 linha default
|
// se vazio e existe base, adiciona 1 linha default
|
||||||
if (!linhas.value.length && base.length) {
|
// não auto-adiciona; usuário escolhe quais filtros quer usar
|
||||||
const b0 = base[0];
|
|
||||||
linhas.value = [
|
|
||||||
{
|
|
||||||
coluna: b0.coluna as any,
|
|
||||||
operador: (b0.operador as any) ?? "=",
|
|
||||||
entrada: b0.entrada,
|
|
||||||
valor: valorInicialPorEntrada(b0.entrada),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// se algum filtro mudou a coluna para valor inválido, ajusta
|
// se algum filtro mudou a coluna para valor inválido, ajusta
|
||||||
for (const l of linhas.value) {
|
for (const l of linhas.value) {
|
||||||
if (!colunasDisponiveis.value.includes(String(l.coluna))) {
|
if (!colunasDisponiveis.value.includes(String(l.coluna))) continue;
|
||||||
l.coluna = (base[0]?.coluna as any) ?? l.coluna;
|
l.operador = String((base.find((b) => String(b.coluna) === String(l.coluna))?.operador ?? "="));
|
||||||
}
|
|
||||||
if (!operadoresDisponiveis.includes(l.operador)) {
|
|
||||||
l.operador = "=";
|
|
||||||
}
|
|
||||||
// sanity
|
// sanity
|
||||||
if (l.entrada && !isTipoEntrada(l.entrada[0])) {
|
if (l.entrada && !isTipoEntrada(l.entrada[0])) {
|
||||||
l.entrada = ["texto", { rotulo: "Valor" }] as any;
|
l.entrada = ["texto", { rotulo: "Valor" }] as any;
|
||||||
|
|
@ -195,14 +183,20 @@ export default defineComponent({
|
||||||
);
|
);
|
||||||
|
|
||||||
function adicionar() {
|
function adicionar() {
|
||||||
if (!props.filtrosBase.length) return;
|
if (!colunaParaAdicionar.value) return;
|
||||||
const b0 = props.filtrosBase[0];
|
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({
|
linhas.value.push({
|
||||||
coluna: b0.coluna as any,
|
coluna: b0.coluna as any,
|
||||||
operador: (b0.operador as any) ?? "=",
|
|
||||||
entrada: b0.entrada,
|
entrada: b0.entrada,
|
||||||
|
operador: String(b0.operador ?? "="),
|
||||||
valor: valorInicialPorEntrada(b0.entrada),
|
valor: valorInicialPorEntrada(b0.entrada),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
colunaParaAdicionar.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function remover(idx: number) {
|
function remover(idx: number) {
|
||||||
|
|
@ -222,8 +216,6 @@ export default defineComponent({
|
||||||
"salvar",
|
"salvar",
|
||||||
linhas.value.map((l) => ({
|
linhas.value.map((l) => ({
|
||||||
coluna: l.coluna,
|
coluna: l.coluna,
|
||||||
operador: l.operador,
|
|
||||||
entrada: l.entrada,
|
|
||||||
valor: l.valor,
|
valor: l.valor,
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
@ -231,15 +223,17 @@ export default defineComponent({
|
||||||
|
|
||||||
return {
|
return {
|
||||||
linhas,
|
linhas,
|
||||||
operadoresDisponiveis,
|
opcoesParaAdicionar,
|
||||||
colunasDisponiveis,
|
colunaParaAdicionar,
|
||||||
componenteEntrada,
|
componenteEntrada,
|
||||||
opcoesEntrada,
|
opcoesEntrada,
|
||||||
adicionar,
|
adicionar,
|
||||||
remover,
|
remover,
|
||||||
|
// exibimos operador fixo só como texto
|
||||||
emitFechar,
|
emitFechar,
|
||||||
emitSalvar,
|
emitSalvar,
|
||||||
emitLimpar,
|
emitLimpar,
|
||||||
|
rotuloDoFiltro,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -312,7 +306,7 @@ export default defineComponent({
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__linha {
|
.eli-tabela-modal-filtro__linha {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 220px 120px 1fr 34px;
|
grid-template-columns: 1fr 34px;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
export type EliTabelaFiltroAvancadoSalvo<T> = Array<{
|
||||||
|
coluna: keyof T
|
||||||
export type EliTabelaFiltroAvancadoSalvo<T> = NonNullable<EliTabelaConsulta<T>["filtroAvancado"]>;
|
valor: any
|
||||||
|
}>;
|
||||||
|
|
||||||
function key(nomeTabela: string) {
|
function key(nomeTabela: string) {
|
||||||
return `eli_tabela:${nomeTabela}:filtro_avancado`;
|
return `eli_tabela:${nomeTabela}:filtro_avancado`;
|
||||||
|
|
|
||||||
|
|
@ -328,16 +328,19 @@ export default defineComponent({
|
||||||
coluna: "empreendedor",
|
coluna: "empreendedor",
|
||||||
operador: "like",
|
operador: "like",
|
||||||
entrada: ["texto", { rotulo: "Empreendedor" }] as ComponenteEntrada,
|
entrada: ["texto", { rotulo: "Empreendedor" }] as ComponenteEntrada,
|
||||||
|
rotulo: 'Empreendedor'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
coluna: "documento",
|
coluna: "documento",
|
||||||
operador: "like",
|
operador: "like",
|
||||||
entrada: ["texto", { rotulo: "Documento", formato: "cpfCnpj" }] as ComponenteEntrada,
|
entrada: ["texto", { rotulo: "Documento", formato: "cpfCnpj" }] as ComponenteEntrada,
|
||||||
|
'rotulo': 'Documento'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
coluna: "email",
|
coluna: "email",
|
||||||
operador: "like",
|
operador: "like",
|
||||||
entrada: ["texto", { rotulo: "E-mail", formato: "email" }] as ComponenteEntrada,
|
entrada: ["texto", { rotulo: "E-mail", formato: "email" }] as ComponenteEntrada,
|
||||||
|
rotulo: 'E-mail'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
consulta: async (parametrosConsulta) => {
|
consulta: async (parametrosConsulta) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue