ajustes na tabela de consulta
This commit is contained in:
parent
aea3da6585
commit
1446d6225b
78 changed files with 17921 additions and 17580 deletions
|
|
@ -5,13 +5,25 @@ BASE="https://paiol.idz.one/desenvolvimento/agent-ia"
|
||||||
ERROS=0
|
ERROS=0
|
||||||
|
|
||||||
baixar() {
|
baixar() {
|
||||||
|
TMP=$(mktemp)
|
||||||
echo "baixando $1"
|
echo "baixando $1"
|
||||||
ERRO_CURL="$(curl -sSfL --create-dirs "$1" -o "$2" 2>&1)" || {
|
ERRO_CURL="$(curl -sSfL --create-dirs "$1" -o "$TMP" 2>&1)" || {
|
||||||
echo " ⚠ $1"
|
echo " ⚠ $1"
|
||||||
echo " $ERRO_CURL"
|
echo " $ERRO_CURL"
|
||||||
|
rm -f "$TMP"
|
||||||
ERROS=$((ERROS + 1))
|
ERROS=$((ERROS + 1))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
# Rejeitar arquivos menores que 50 bytes (prováveis erros de proxy/WAF)
|
||||||
|
TAMANHO=$(wc -c < "$TMP" | tr -d ' ')
|
||||||
|
if [ "$TAMANHO" -lt 50 ]; then
|
||||||
|
echo " ⚠ $1 — arquivo muito pequeno ($TAMANHO bytes), ignorado"
|
||||||
|
rm -f "$TMP"
|
||||||
|
ERROS=$((ERROS + 1))
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
mkdir -p "$(dirname "$2")"
|
||||||
|
mv "$TMP" "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ignorar se não auto atualizar
|
# ignorar se não auto atualizar
|
||||||
|
|
@ -27,7 +39,14 @@ fi
|
||||||
baixar "$BASE/rules/carta-principios-agente-azteca.global.md" "$DIR/rules/carta-principios-agente-azteca.global.md"
|
baixar "$BASE/rules/carta-principios-agente-azteca.global.md" "$DIR/rules/carta-principios-agente-azteca.global.md"
|
||||||
baixar "$BASE/rules/escrita-natural.global.md" "$DIR/rules/escrita-natural.global.md"
|
baixar "$BASE/rules/escrita-natural.global.md" "$DIR/rules/escrita-natural.global.md"
|
||||||
baixar "$BASE/rules/typescript-sem-any.global.md" "$DIR/rules/typescript-sem-any.global.md"
|
baixar "$BASE/rules/typescript-sem-any.global.md" "$DIR/rules/typescript-sem-any.global.md"
|
||||||
baixar "$BASE/rules/regras_negocio_md.global.md" "$DIR/rules/regras_negocio_md.global.md"
|
baixar "$BASE/rules/regras-negocio-md.global.md" "$DIR/rules/regras-negocio-md.global.md"
|
||||||
|
baixar "$BASE/rules/zod-validacao-padrao.global.md" "$DIR/rules/zod-validacao-padrao.global.md"
|
||||||
|
baixar "$BASE/rules/limite-linhas.global.md" "$DIR/rules/limite-linhas.global.md"
|
||||||
|
baixar "$BASE/rules/estrutura-vue.global.md" "$DIR/rules/estrutura-vue.global.md"
|
||||||
|
baixar "$BASE/rules/jsdoc-padrao.global.md" "$DIR/rules/jsdoc-padrao.global.md"
|
||||||
|
baixar "$BASE/rules/autonomia-agente.global.md" "$DIR/rules/autonomia-agente.global.md"
|
||||||
|
baixar "$BASE/rules/fronteiras-monorepo.global.md" "$DIR/rules/fronteiras-monorepo.global.md"
|
||||||
|
baixar "$BASE/rules/mensagens-usuario.global.md" "$DIR/rules/mensagens-usuario.global.md"
|
||||||
|
|
||||||
# workflows
|
# workflows
|
||||||
baixar "$BASE/workflows/aprimorar-IA.global.md" "$DIR/workflows/aprimorar-IA.global.md"
|
baixar "$BASE/workflows/aprimorar-IA.global.md" "$DIR/workflows/aprimorar-IA.global.md"
|
||||||
|
|
@ -48,8 +67,11 @@ baixar "$BASE/skills/mapear-codigo-fonte.global/SKILL.md" "$DIR/sk
|
||||||
baixar "$BASE/skills/diagnosticar-erros-build.global/SKILL.md" "$DIR/skills/diagnosticar-erros-build.global/SKILL.md"
|
baixar "$BASE/skills/diagnosticar-erros-build.global/SKILL.md" "$DIR/skills/diagnosticar-erros-build.global/SKILL.md"
|
||||||
baixar "$BASE/skills/documentar-decisao-tecnica.global/SKILL.md" "$DIR/skills/documentar-decisao-tecnica.global/SKILL.md"
|
baixar "$BASE/skills/documentar-decisao-tecnica.global/SKILL.md" "$DIR/skills/documentar-decisao-tecnica.global/SKILL.md"
|
||||||
baixar "$BASE/skills/documentar-regras-negocio.global/SKILL.md" "$DIR/skills/documentar-regras-negocio.global/SKILL.md"
|
baixar "$BASE/skills/documentar-regras-negocio.global/SKILL.md" "$DIR/skills/documentar-regras-negocio.global/SKILL.md"
|
||||||
|
baixar "$BASE/skills/criar-schema-zod.global/SKILL.md" "$DIR/skills/criar-schema-zod.global/SKILL.md"
|
||||||
|
baixar "$BASE/skills/documentar-dominio-modulo.global/SKILL.md" "$DIR/skills/documentar-dominio-modulo.global/SKILL.md"
|
||||||
|
|
||||||
# raiz (.agent)
|
# raiz (.agent)
|
||||||
baixar "$BASE/tools.md" "$DIR/tools.md"
|
baixar "$BASE/tools.md" "$DIR/tools.md"
|
||||||
|
baixar "$BASE/verificar-linhas.sh" "$DIR/verificar-linhas.sh"
|
||||||
|
|
||||||
exit "$ERROS"
|
exit "$ERROS"
|
||||||
60
.agent/rules/autonomia-agente.global.md
Normal file
60
.agent/rules/autonomia-agente.global.md
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
---
|
||||||
|
type: rule
|
||||||
|
name: autonomia-agente
|
||||||
|
description: Define limites de autonomia do agente — o que pode fazer sozinho, o que requer confirmação e o que é proibido
|
||||||
|
scope: global
|
||||||
|
trigger: always_on
|
||||||
|
priority: alta
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Regra: Limites de Autonomia do Agente
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
O agente existe para **ampliar a capacidade humana**, não para substituir decisões. Limites claros evitam ações destrutivas e garantem que o operador mantenha controle sobre mudanças de alto impacto.
|
||||||
|
|
||||||
|
## Ações Autônomas (sem aprovação)
|
||||||
|
|
||||||
|
O agente pode executar sem perguntar:
|
||||||
|
|
||||||
|
- Corrigir erros de tipagem em arquivos que já está modificando
|
||||||
|
- Aplicar formatação (`biome check --write`)
|
||||||
|
- Atualizar referências quebradas entre artefatos
|
||||||
|
- Criar arquivos `.regras-negocio.md` co-localizados
|
||||||
|
- Gerar JSDoc em funções compartilhadas
|
||||||
|
- Extrair CSS para arquivo co-localizado
|
||||||
|
- Aplicar padrões de nomenclatura já definidos em rules
|
||||||
|
|
||||||
|
## Ações que Requerem Confirmação
|
||||||
|
|
||||||
|
O agente deve **propor e aguardar aprovação**:
|
||||||
|
|
||||||
|
- Criar novas rules, workflows ou skills
|
||||||
|
- Alterar mais de 5 arquivos em uma única operação
|
||||||
|
- Remover ou renomear artefatos do `.agent/`
|
||||||
|
- Mudar contratos de API (parâmetros, retornos, rotas)
|
||||||
|
- Alterar schemas Zod compartilhados no pacote `*-comuns`
|
||||||
|
- Propor novas dependências ao `package.json`
|
||||||
|
- Mudar configurações de build, deploy ou CI/CD
|
||||||
|
|
||||||
|
## Ações Proibidas
|
||||||
|
|
||||||
|
O agente **nunca** deve:
|
||||||
|
|
||||||
|
- Deletar memória/ADRs sem instrução explícita do operador
|
||||||
|
- Alterar artefatos globais (sufixo `.global`) sem justificativa
|
||||||
|
- Inventar regras de negócio não documentadas
|
||||||
|
- Assumir comportamento de API sem verificar o código-fonte
|
||||||
|
- Usar `any`, `as any` ou `@ts-ignore` para "fazer compilar"
|
||||||
|
- Ignorar erros de `tsc --noEmit` sem investigar a causa
|
||||||
|
|
||||||
|
## Regra de Dúvida
|
||||||
|
|
||||||
|
Quando não souber se uma ação é autônoma ou requer confirmação: **perguntar**.
|
||||||
|
|
||||||
|
O custo de uma pergunta é zero. O custo de uma ação destrutiva é alto.
|
||||||
|
|
||||||
|
## Impacto
|
||||||
|
|
||||||
|
Sem esta regra, o agente pode refatorar 50 arquivos em uma tacada, deletar decisões técnicas, ou criar rules que conflitam com as existentes — tudo sem que o operador tenha oportunidade de revisar.
|
||||||
|
|
@ -3,9 +3,10 @@ trigger: always_on
|
||||||
type: rule
|
type: rule
|
||||||
name: carta-principios-agente-azteca
|
name: carta-principios-agente-azteca
|
||||||
description: Princípios morais e operacionais que orientam o comportamento de agentes de IA no ecossistema Azteca
|
description: Princípios morais e operacionais que orientam o comportamento de agentes de IA no ecossistema Azteca
|
||||||
version: 1.0
|
version: "1.0"
|
||||||
scope: global
|
scope: global
|
||||||
priority: alta
|
priority: alta
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Carta de Princípios do Agente de IA da Azteca
|
# Carta de Princípios do Agente de IA da Azteca
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,14 @@
|
||||||
---
|
---
|
||||||
trigger: always_on
|
type: rule
|
||||||
description: Garantir escrita natural, fluida e humana em textos técnicos e comerciais, evitando linguagem robótica ou excessivamente genérica.
|
name: escrita-natural
|
||||||
|
trigger: context_match
|
||||||
|
description: Garantir escrita natural, fluida e humana em textos comerciais e de comunicação, evitando linguagem robótica ou excessivamente genérica.
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
ativacao: >
|
||||||
|
Aplicar quando o agente estiver produzindo textos comerciais, de marketing,
|
||||||
|
orçamentos, propostas, reels ou qualquer comunicação voltada ao público externo.
|
||||||
|
NÃO aplicar em documentação técnica (ADRs, rules, JSDoc, regras de negócio).
|
||||||
---
|
---
|
||||||
|
|
||||||
# Regra: Escrita Estratégica e Natural
|
# Regra: Escrita Estratégica e Natural
|
||||||
|
|
|
||||||
86
.agent/rules/estrutura-vue.global.md
Normal file
86
.agent/rules/estrutura-vue.global.md
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
---
|
||||||
|
type: rule
|
||||||
|
name: estrutura-vue
|
||||||
|
description: Padrões obrigatórios de estrutura para componentes Vue 3 (defineComponent, setup, CSS, dispatch)
|
||||||
|
scope: global
|
||||||
|
trigger: file_match
|
||||||
|
globs:
|
||||||
|
- "**/*.vue"
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Regra: Estrutura de Componentes Vue
|
||||||
|
|
||||||
|
## 1. `defineComponent` obrigatório
|
||||||
|
|
||||||
|
Todo componente Vue deve usar `defineComponent`:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'MeuComponente',
|
||||||
|
setup() {
|
||||||
|
// lógica aqui
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. `setup()` não pode ser externo
|
||||||
|
|
||||||
|
O `setup()` deve estar sempre dentro do `.vue`. Nunca delegar para arquivo externo.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// ❌ Proibido — setup esvaziado
|
||||||
|
export default defineComponent({
|
||||||
|
setup(props, { emit }) {
|
||||||
|
return useEliTabela(props, emit) // proxy vazio
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// ✅ Correto — setup com lógica própria
|
||||||
|
export default defineComponent({
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const estado = ref(null)
|
||||||
|
const carregar = async () => { ... }
|
||||||
|
return { estado, carregar }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
> Composables `use*.ts` podem encapsular lógica reutilizável pontual, mas nunca substituir o `setup()`. Se ultrapassar 250 linhas → extrair subcomponentes, CSS ou Dispatch Table.
|
||||||
|
|
||||||
|
## 3. CSS co-localizado
|
||||||
|
|
||||||
|
Separação de estilos em arquivo externo quando o CSS contribui para o total de linhas:
|
||||||
|
|
||||||
|
```
|
||||||
|
MeuComponente.vue
|
||||||
|
MeuComponente.css
|
||||||
|
```
|
||||||
|
|
||||||
|
Importar via `import './MeuComponente.css'` ou `<style src="./MeuComponente.css" />`.
|
||||||
|
|
||||||
|
## 4. Dispatch Table
|
||||||
|
|
||||||
|
Uso de mapa de funções para eliminar `if/else` ou `switch` longos:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// handlers.ts
|
||||||
|
export const acaoHandlers: Record<string, () => void> = {
|
||||||
|
salvar: () => { ... },
|
||||||
|
cancelar: () => { ... },
|
||||||
|
excluir: () => { ... },
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Impacto
|
||||||
|
|
||||||
|
Sem estes padrões, componentes perdem inferência de tipos, lógica fica inauditável em composables externos, e CSS cresce inline sem controle.
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- Rule: `.agent/rules/limite-linhas.global.md`
|
||||||
|
- Rule: `.agent/rules/typescript-sem-any.global.md`
|
||||||
120
.agent/rules/fronteiras-monorepo.global.md
Normal file
120
.agent/rules/fronteiras-monorepo.global.md
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
---
|
||||||
|
type: rule
|
||||||
|
name: fronteiras-monorepo
|
||||||
|
description: Define a convenção de pacotes e regras de importação entre módulos do monorepo
|
||||||
|
scope: global
|
||||||
|
trigger: always_on
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Regra: Fronteiras de Pacote no Monorepo
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
Cada módulo SaaS do ecossistema é organizado em até 4 pacotes dentro de um monorepo. O agente **deve** respeitar as fronteiras de importação entre pacotes para evitar acoplamento indevido.
|
||||||
|
|
||||||
|
## Convenção de Pacotes
|
||||||
|
|
||||||
|
Cada módulo segue a estrutura:
|
||||||
|
|
||||||
|
```
|
||||||
|
<modulo>-back ← Servidor: rotas, serviços, filas, CRON
|
||||||
|
<modulo>-front ← Interface: páginas Vue, componentes, composables
|
||||||
|
<modulo>-comuns ← Compartilhado: tipos, schemas Zod, enums, utils puros
|
||||||
|
<modulo>-migracao ← Banco de dados: migrations, seeds, scripts de carga
|
||||||
|
```
|
||||||
|
|
||||||
|
Nem todo módulo terá os 4 pacotes. O mínimo funcional é `back` + `front` + `comuns`.
|
||||||
|
|
||||||
|
## Regras de Importação
|
||||||
|
|
||||||
|
### Permitido ✅
|
||||||
|
|
||||||
|
```
|
||||||
|
<modulo>-front → pode importar de → <modulo>-comuns
|
||||||
|
<modulo>-back → pode importar de → <modulo>-comuns
|
||||||
|
<modulo>-migracao → pode importar de → <modulo>-comuns
|
||||||
|
```
|
||||||
|
|
||||||
|
### Proibido ❌
|
||||||
|
|
||||||
|
```
|
||||||
|
<modulo>-front ✗ nunca importar de → <modulo>-back
|
||||||
|
<modulo>-back ✗ nunca importar de → <modulo>-front
|
||||||
|
<modulo>-migracao ✗ nunca importar de → <modulo>-front
|
||||||
|
<modulo>-front ✗ nunca importar de → <outro-modulo>-back
|
||||||
|
<outro-modulo> ✗ nunca importar de → <modulo>-back (direto)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Comunicação entre módulos
|
||||||
|
|
||||||
|
Módulos diferentes **nunca** importam código um do outro diretamente. Comunicação entre módulos deve ocorrer via:
|
||||||
|
|
||||||
|
- **API HTTP** (chamada de serviço entre backs)
|
||||||
|
- **Fila** (BullMQ, Redis) para processamento assíncrono
|
||||||
|
- **Banco compartilhado** com schemas/tabelas separados por módulo
|
||||||
|
- **Pacote `*-comuns` compartilhado** apenas para tipos e schemas de contrato
|
||||||
|
|
||||||
|
## O que vive em cada pacote
|
||||||
|
|
||||||
|
### `<modulo>-comuns`
|
||||||
|
|
||||||
|
O pacote comuns é a **única fonte de verdade** para tipos e schemas compartilhados:
|
||||||
|
|
||||||
|
```
|
||||||
|
<modulo>-comuns/src/
|
||||||
|
├── tabelas/ ← schemas Zod por entidade (zEntidadeCriar, etc.)
|
||||||
|
├── enums/ ← enums de domínio do módulo
|
||||||
|
├── tipos/ ← tipos derivados dos schemas
|
||||||
|
└── utils/ ← funções puras sem side-effect
|
||||||
|
```
|
||||||
|
|
||||||
|
**Proibido** no comuns:
|
||||||
|
- Componentes Vue ou React
|
||||||
|
- Código com `import` de Node.js (`fs`, `path`, `http`)
|
||||||
|
- Código com `import` de bibliotecas de frontend (`vue`, `vuetify`)
|
||||||
|
- Lógica de negócio que depende de banco ou serviço externo
|
||||||
|
|
||||||
|
### `<modulo>-back`
|
||||||
|
|
||||||
|
```
|
||||||
|
<modulo>-back/src/
|
||||||
|
├── rotas/ ← endpoints Express/Fastify
|
||||||
|
├── servicos/ ← lógica de negócio
|
||||||
|
├── banco/ ← queries (Knex, Prisma, etc.)
|
||||||
|
├── filas/ ← processadores de fila
|
||||||
|
├── cron/ ← tarefas agendadas
|
||||||
|
└── utils/ ← helpers exclusivos do back
|
||||||
|
```
|
||||||
|
|
||||||
|
### `<modulo>-front`
|
||||||
|
|
||||||
|
```
|
||||||
|
<modulo>-front/src/
|
||||||
|
├── paginas/ ← páginas/views por rota
|
||||||
|
├── componentes/ ← componentes reutilizáveis do módulo
|
||||||
|
├── composables/ ← lógica reutilizável (use*.ts)
|
||||||
|
└── utils/ ← helpers exclusivos do front
|
||||||
|
```
|
||||||
|
|
||||||
|
### `<modulo>-migracao`
|
||||||
|
|
||||||
|
```
|
||||||
|
<modulo>-migracao/src/
|
||||||
|
├── migrations/ ← criação/alteração de tabelas
|
||||||
|
├── seeds/ ← dados iniciais
|
||||||
|
└── scripts/ ← scripts de carga/transformação
|
||||||
|
```
|
||||||
|
|
||||||
|
## Impacto
|
||||||
|
|
||||||
|
Sem esta regra:
|
||||||
|
- Front importa serviço de back (quebra em build de produção)
|
||||||
|
- Módulo A acessa tabelas do Módulo B diretamente (acoplamento oculto)
|
||||||
|
- Schemas ficam duplicados entre back e front
|
||||||
|
- Mudança em um módulo quebra outro sem aviso
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- Rule: `.agent/rules/zod-validacao-padrao.global.md` (schemas no `*-comuns`)
|
||||||
|
- Skill: `.agent/skills/mapear-codigo-fonte.global/SKILL.md`
|
||||||
59
.agent/rules/jsdoc-padrao.global.md
Normal file
59
.agent/rules/jsdoc-padrao.global.md
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
---
|
||||||
|
type: rule
|
||||||
|
name: jsdoc-padrao
|
||||||
|
description: Padrões de documentação em código (JSDoc, casts temporários e TODOs estruturados)
|
||||||
|
scope: global
|
||||||
|
trigger: file_match
|
||||||
|
globs:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/*.tsx"
|
||||||
|
- "**/*.vue"
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Regra: Documentação em Código
|
||||||
|
|
||||||
|
## 1. JSDoc — Princípios
|
||||||
|
|
||||||
|
- **Por que, não o Quê**: documente o raciocínio, não o mecanismo que o TypeScript já expressa.
|
||||||
|
- **Nomenclatura limpa**: confie em nomes expressivos antes de comentários.
|
||||||
|
|
||||||
|
## 2. JSDoc obrigatório em funções compartilhadas
|
||||||
|
|
||||||
|
Toda função central ou de uso compartilhado deve ter cabeçalho JSDoc:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
/**
|
||||||
|
* Busca detalhes da entidade e calcula privilégios aplicáveis.
|
||||||
|
* Não utilizar em processamento em lote para evitar sobrecarga.
|
||||||
|
*
|
||||||
|
* @param tenantId - Identificador do tenant no sistema
|
||||||
|
* @param entityId - ID do registro na base de dados
|
||||||
|
* @returns Objeto consolidado ou `null` se não encontrado
|
||||||
|
*/
|
||||||
|
export const obterDetalhes = async (tenantId: string, entityId: string) => { ... }
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Casts temporários — justificativa obrigatória
|
||||||
|
|
||||||
|
Coerções agressivas requerem comentário explicando o porquê:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Necessário: biblioteca externa não provê tipagem genérica na versão atual
|
||||||
|
const dados = payload.raw as unknown as RespostaFormatada
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. TODOs estruturados
|
||||||
|
|
||||||
|
Dívida técnica ou dúvida de negócio deve seguir formato padronizado:
|
||||||
|
|
||||||
|
- **Tipagem**: `// TODO de tipagem: Criar interface para o retorno da API`
|
||||||
|
- **Negócio**: `// TODO de regra: Validar com Produto se taxa se aplica a clientes antigos`
|
||||||
|
|
||||||
|
## Impacto
|
||||||
|
|
||||||
|
Sem este padrão, funções compartilhadas ficam sem documentação, casts aparecem sem justificativa, e TODOs são inconsistentes e difíceis de buscar.
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- Rule: `.agent/rules/typescript-sem-any.global.md`
|
||||||
66
.agent/rules/limite-linhas.global.md
Normal file
66
.agent/rules/limite-linhas.global.md
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
type: rule
|
||||||
|
name: limite-linhas
|
||||||
|
description: Nenhum arquivo de código pode ultrapassar 250 linhas
|
||||||
|
scope: global
|
||||||
|
trigger: file_match
|
||||||
|
globs:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/*.tsx"
|
||||||
|
- "**/*.vue"
|
||||||
|
- "**/*.css"
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Regra: Limite de 250 Linhas por Arquivo
|
||||||
|
|
||||||
|
## Regra
|
||||||
|
|
||||||
|
Nenhum arquivo `*.vue`, `*.ts`, `*.tsx` ou `*.css` pode ultrapassar **250 linhas**.
|
||||||
|
|
||||||
|
> Validação automática: `.agent/verificar-linhas.sh`
|
||||||
|
|
||||||
|
## Estratégias de Decomposição
|
||||||
|
|
||||||
|
| Situação | Ação |
|
||||||
|
|---|---|
|
||||||
|
| Template longo | Extrair seções como subcomponentes |
|
||||||
|
| CSS extenso | Mover para `<nome>.css` co-localizado |
|
||||||
|
| `setup()` extenso | Extrair subcomponentes, CSS ou Dispatch Table |
|
||||||
|
| Modal/Dialog embutido | Sempre em componente separado (`*Modal.vue`) |
|
||||||
|
| Handlers e dispatch | Extrair para `handlers.ts` ou `dispatch.ts` |
|
||||||
|
|
||||||
|
## Divisão em Pasta
|
||||||
|
|
||||||
|
Quando um componente precisa de múltiplos sub-arquivos, converter em **pasta homônima** com `index.vue`:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Antes
|
||||||
|
ComponenteGrande.vue ← monolítico (+250 linhas)
|
||||||
|
|
||||||
|
# Depois
|
||||||
|
ComponenteGrande/
|
||||||
|
├── index.vue ← orquestração (≤250 linhas)
|
||||||
|
├── SecaoPrincipal.vue ← bloco de template extraído
|
||||||
|
├── SecaoSecundaria.vue ← outro bloco extraído
|
||||||
|
├── componenteGrande.mapeadores.ts ← lógica de eventos
|
||||||
|
└── ComponenteGrande.css ← estilos co-localizados
|
||||||
|
```
|
||||||
|
|
||||||
|
| Arquivo | Responsabilidade |
|
||||||
|
|---|---|
|
||||||
|
| `index.vue` | Orquestração: importa e compõe. Sem lógica densa. |
|
||||||
|
| `Secao*.vue` | Template isolado. Props + eventos. |
|
||||||
|
| `*.mapeadores.ts` | Funções de ação desacopladas. |
|
||||||
|
| `*.css` | Estilos co-localizados. |
|
||||||
|
|
||||||
|
> Importações externas não mudam: `ComponenteGrande/` resolve para `index.vue`.
|
||||||
|
|
||||||
|
## Impacto
|
||||||
|
|
||||||
|
Sem esta regra, arquivos crescem silenciosamente até se tornarem intocáveis — ninguém quer revisar ou refatorar um componente de 800 linhas.
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- Script: `.agent/verificar-linhas.sh`
|
||||||
|
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||||
123
.agent/rules/mensagens-usuario.global.md
Normal file
123
.agent/rules/mensagens-usuario.global.md
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
---
|
||||||
|
type: rule
|
||||||
|
name: mensagens-usuario
|
||||||
|
description: Toda mensagem visível ao usuário final deve ser escrita em linguagem do domínio, sem termos técnicos de TI
|
||||||
|
scope: global
|
||||||
|
trigger: file_match
|
||||||
|
globs:
|
||||||
|
- "**/*.vue"
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/*.tsx"
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Regra: Mensagens Orientadas ao Domínio
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
O usuário final dos módulos SaaS é profissional de **engenharia, ciência ou gestão ambiental**. Ele entende de legislação, processos técnicos e ciência aplicada — mas **não tem obrigação de entender tecnologia**.
|
||||||
|
|
||||||
|
Toda mensagem visível na interface — erro, validação, confirmação, tooltip, empty state, ajuda — deve ser escrita na linguagem do domínio do módulo.
|
||||||
|
|
||||||
|
## Regra
|
||||||
|
|
||||||
|
### 1. Erros de validação devem indicar O QUE preencher, não O QUE falhou
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ ERRADO — linguagem técnica
|
||||||
|
"Campo obrigatório"
|
||||||
|
"Erro de validação"
|
||||||
|
"Formato inválido"
|
||||||
|
"Payload inválido"
|
||||||
|
|
||||||
|
// ✅ CORRETO — linguagem do domínio
|
||||||
|
"Informe a Área do Empreendimento (em hectares)"
|
||||||
|
"Selecione o Tipo de Licença: LP, LI ou LO"
|
||||||
|
"A Data da Vistoria deve ser anterior à data atual"
|
||||||
|
"Informe o CNPJ no formato 00.000.000/0000-00"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Erros de sistema devem ser traduzidos para o usuário
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ ERRADO — erro técnico exposto
|
||||||
|
"Erro 500: Internal Server Error"
|
||||||
|
"Timeout na requisição"
|
||||||
|
"Network Error"
|
||||||
|
"ECONNREFUSED"
|
||||||
|
|
||||||
|
// ✅ CORRETO — mensagem humanizada
|
||||||
|
"Não foi possível salvar. Tente novamente em instantes."
|
||||||
|
"A operação demorou mais que o esperado. Tente novamente."
|
||||||
|
"Sem conexão com o servidor. Verifique sua internet."
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Estados vazios devem explicar o contexto
|
||||||
|
|
||||||
|
Quando uma lista ou tabela está vazia, a mensagem deve orientar o usuário:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ ERRADO — genérico
|
||||||
|
"Nenhum registro encontrado"
|
||||||
|
"Lista vazia"
|
||||||
|
|
||||||
|
// ✅ CORRETO — explica o domínio e orienta
|
||||||
|
"Nenhuma condicionante cadastrada para esta licença."
|
||||||
|
"Nenhum relatório de monitoramento registrado neste período."
|
||||||
|
"Nenhum empreendimento encontrado com os filtros aplicados. Tente ampliar a busca."
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Confirmações devem descrever a consequência
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ ERRADO — genérico
|
||||||
|
"Tem certeza que deseja excluir?"
|
||||||
|
"Confirmar operação?"
|
||||||
|
|
||||||
|
// ✅ CORRETO — descreve o impacto
|
||||||
|
"Excluir esta condicionante? O prazo de cumprimento e os documentos vinculados serão removidos."
|
||||||
|
"Arquivar esta licença? Ela não aparecerá mais nas listagens ativas."
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Labels e placeholders devem usar vocabulário do domínio
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ ERRADO — genérico
|
||||||
|
label: "Nome"
|
||||||
|
placeholder: "Digite aqui"
|
||||||
|
|
||||||
|
// ✅ CORRETO — específico do domínio
|
||||||
|
label: "Razão Social do Empreendedor"
|
||||||
|
placeholder: "Ex: Mineração Vale Verde Ltda."
|
||||||
|
|
||||||
|
label: "Área Total do Empreendimento"
|
||||||
|
placeholder: "Em hectares (ex: 150,5)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Schemas Zod devem ter mensagens de domínio
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ ERRADO — mensagens padrão do Zod
|
||||||
|
const zEmpreendimento = z.object({
|
||||||
|
nome: z.string().min(1), // "String must contain at least 1 character(s)"
|
||||||
|
area: z.number().positive(), // "Number must be greater than 0"
|
||||||
|
})
|
||||||
|
|
||||||
|
// ✅ CORRETO — mensagens customizadas
|
||||||
|
const zEmpreendimento = z.object({
|
||||||
|
nome: z.string().min(1, "Informe o nome do empreendimento"),
|
||||||
|
area: z.number({ invalid_type_error: "A área deve ser um número" })
|
||||||
|
.positive("A área deve ser maior que zero"),
|
||||||
|
cnpj: z.string().regex(/^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/,
|
||||||
|
"CNPJ inválido. Use o formato 00.000.000/0000-00"),
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Impacto
|
||||||
|
|
||||||
|
Sem esta regra, o agente gera mensagens técnicas que confundem gestores ambientais, consultores e técnicos de campo — forçando a equipe de suporte a traduzir erros de sistema para o vocabulário do cliente.
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- Rule: `.agent/rules/zod-validacao-padrao.global.md` (schemas com mensagens customizadas)
|
||||||
|
- Workflow: `.agent/workflows/ux.global.md` (design de interface)
|
||||||
120
.agent/rules/regras-negocio-md.global.md
Normal file
120
.agent/rules/regras-negocio-md.global.md
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
---
|
||||||
|
type: rule
|
||||||
|
name: regras-negocio-md
|
||||||
|
description: Arquivo {modulo}.regras-negocio.md obrigatório para módulos com lógica complexa
|
||||||
|
scope: global
|
||||||
|
trigger: always_on
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Regra: Arquivo `{modulo}.regras-negocio.md` Obrigatório para Módulos com Lógica Complexa
|
||||||
|
|
||||||
|
> **Escopo global** — aplica-se a todos os projetos do ecossistema Azteca.
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
Qualquer arquivo TypeScript que contenha lógica de negócio não-trivial — múltiplas regras de decisão, critérios de bloqueio, estratégias de processamento — deve ter suas regras documentadas em linguagem natural em um arquivo Markdown co-localizado.
|
||||||
|
|
||||||
|
Isso garante que produto, suporte e desenvolvimento possam entender as regras sem precisar ler TypeScript, e que o agente de IA encontre rapidamente os critérios corretos antes de alterar qualquer código.
|
||||||
|
|
||||||
|
## Regra
|
||||||
|
|
||||||
|
**Todo módulo com lógica de negócio não-trivial DEVE ter um arquivo `{modulo}.regras-negocio.md` co-localizado.**
|
||||||
|
|
||||||
|
Considera-se lógica não-trivial qualquer módulo que:
|
||||||
|
- possui 3 ou mais critérios de decisão distintos
|
||||||
|
- realiza eleição/priorização entre registros
|
||||||
|
- aplica diferentes estratégias por tipo de dado
|
||||||
|
- pode resultar em revisão manual (caminho alternativo ao fluxo automático)
|
||||||
|
- é consumido por CRON, worker ou importador automático
|
||||||
|
|
||||||
|
O módulo TypeScript deve conter, na primeira linha do arquivo, a referência:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Regras de negócio: ver {modulo}.regras-negocio.md
|
||||||
|
```
|
||||||
|
|
||||||
|
O arquivo `.md` é a **fonte de verdade**. Os JSDoc do código devem referenciar o `.md`, não duplicá-lo.
|
||||||
|
|
||||||
|
## Estrutura Obrigatória do Arquivo
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Regras de Negócio — [Nome do Módulo]
|
||||||
|
|
||||||
|
Módulo: `_arquivo.ts`
|
||||||
|
Localização: `caminho/relativo/ao/arquivo`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
Por que este módulo existe, qual problema resolve.
|
||||||
|
|
||||||
|
## Critérios de Entrada / Identificação
|
||||||
|
O que aciona o módulo, quais dados recebe, filtros aplicados.
|
||||||
|
|
||||||
|
## Regras de Processamento
|
||||||
|
As regras numeradas em ordem de avaliação.
|
||||||
|
|
||||||
|
## Casos de Revisão Manual (quando aplicável)
|
||||||
|
Quando o processamento automático não pode prosseguir.
|
||||||
|
|
||||||
|
## Estratégia de Fusão / Resultado (quando aplicável)
|
||||||
|
O que o módulo produz, como campos são combinados.
|
||||||
|
|
||||||
|
## Dependências Externas
|
||||||
|
Tabelas, filas, serviços externos tocados pelo módulo.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exemplos
|
||||||
|
|
||||||
|
✅ **Correto** — referência no topo do módulo, regras no `.md`:
|
||||||
|
```typescript
|
||||||
|
// Regras de negócio: ver juntar_execucoes.regras-negocio.md
|
||||||
|
|
||||||
|
import { ... } from "..."
|
||||||
|
|
||||||
|
export const compilarJuntarExecucoes = async (...) => {
|
||||||
|
// implementação conforme regras-negocio.md
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ **Errado** — regras embutidas no código como comentário de bloco:
|
||||||
|
```typescript
|
||||||
|
/**
|
||||||
|
* Regras de negócio:
|
||||||
|
* [x] Pode ter apenas uma execução por data de vencimento.
|
||||||
|
* [x] Se tiver apenas uma execução consolidada → ela é a principal.
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ **Errado** — JSDoc duplicando as regras em vez de referenciar o `.md`:
|
||||||
|
```typescript
|
||||||
|
/**
|
||||||
|
* Retorna false quando:
|
||||||
|
* - vencimentos divergentes
|
||||||
|
* - executada com datas distintas
|
||||||
|
* - vencimento_prorrogado distintos
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Impacto
|
||||||
|
|
||||||
|
Sem este padrão:
|
||||||
|
- Regras de negócio ficam implícitas no código ou em JSDoc que envelhece sem controle
|
||||||
|
- O agente de IA precisa inferir regras do código ao invés de lê-las diretamente
|
||||||
|
- Produto e suporte não conseguem validar o comportamento sem ajuda técnica
|
||||||
|
- Mudanças de regra geram JSDoc desatualizado espalhado pelo código
|
||||||
|
|
||||||
|
## Aplicação
|
||||||
|
|
||||||
|
- Módulos de CRON com lógica de auditoria/fusão
|
||||||
|
- Importadores automáticos (ex: importação de licenças via IA)
|
||||||
|
- Workers de processamento em lote
|
||||||
|
- Qualquer utilitário com lógica de decisão multi-critério
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- Skill: `.agent/skills/documentar-regras-negocio.global/SKILL.md`
|
||||||
|
- Workflow: `.agent/workflows/documentar-regras-negocio.global.md`
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
---
|
---
|
||||||
|
type: rule
|
||||||
|
name: typescript-sem-any
|
||||||
trigger: always_on
|
trigger: always_on
|
||||||
description: Proíbe uso de any, casts inseguros e padroniza uso de enums em código TypeScript
|
description: Proíbe uso de any, casts inseguros e padroniza uso de enums em código TypeScript
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
globs:
|
globs:
|
||||||
- "**/*.ts"
|
- "**/*.ts"
|
||||||
- "**/*.tsx"
|
- "**/*.tsx"
|
||||||
|
|
@ -68,6 +72,6 @@ Se encontrar uma string que represente um valor de domínio do sistema, o agente
|
||||||
|
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
- Skill: `.agent/skills/diagnosticar-erros-build/SKILL.md` (quando erros de tipagem causam falhas de build em cascata)
|
- Skill: `.agent/skills/diagnosticar-erros-build.global/SKILL.md` (quando erros de tipagem causam falhas de build em cascata)
|
||||||
- Workflow: `.agent/workflows/documentar-codigo.global.md` (padrão de documentação para casts temporários)
|
- Workflow: `.agent/workflows/otimizar-codigos.global.md` (padrão de documentação para casts temporários)
|
||||||
|
|
||||||
|
|
|
||||||
315
.agent/rules/zod-validacao-padrao.global.md
Normal file
315
.agent/rules/zod-validacao-padrao.global.md
Normal file
|
|
@ -0,0 +1,315 @@
|
||||||
|
---
|
||||||
|
type: rule
|
||||||
|
name: zod-validacao-padrao
|
||||||
|
description: Estabelece Zod como biblioteca obrigatória de validação em todo o ecossistema Azteca
|
||||||
|
version: "1.0"
|
||||||
|
scope: global
|
||||||
|
priority: alta
|
||||||
|
trigger: always_on
|
||||||
|
globs:
|
||||||
|
- "**/*.ts"
|
||||||
|
- "**/*.tsx"
|
||||||
|
- "**/*.vue"
|
||||||
|
alwaysApply: true
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
references:
|
||||||
|
- .agent/rules/typescript-sem-any.global.md
|
||||||
|
- .agent/skills/criar-schema-zod.global/SKILL.md
|
||||||
|
---
|
||||||
|
|
||||||
|
# Regra: Zod como Validador Padrão
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
Todo projeto do ecossistema Azteca que receba dados externos — API, formulário, webhook, importação, fila, variáveis de ambiente — **deve** validar esses dados com [Zod](https://zod.dev).
|
||||||
|
|
||||||
|
Zod é a única biblioteca de validação autorizada porque:
|
||||||
|
|
||||||
|
- Inferência nativa de tipos TypeScript (`z.infer<>`) — elimina duplicação entre schema e tipo
|
||||||
|
- Bundle pequeno (~13KB gzipped) — viável no frontend
|
||||||
|
- Compartilhável entre back e front via pacotes `*-comuns`
|
||||||
|
- Ecossistema maduro: `zod-to-json-schema`, `@anatine/zod-nestjs`, integração com `tRPC`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Regra
|
||||||
|
|
||||||
|
### 1. Toda entrada externa deve ser validada com Zod
|
||||||
|
|
||||||
|
Entradas externas incluem:
|
||||||
|
|
||||||
|
- **Corpo de requisição** (API REST, webhook, GraphQL)
|
||||||
|
- **Query params e path params**
|
||||||
|
- **Formulários de frontend**
|
||||||
|
- **Dados de fila** (BullMQ, Redis, etc.)
|
||||||
|
- **Arquivos importados** (CSV, JSON, Excel)
|
||||||
|
- **Variáveis de ambiente**
|
||||||
|
- **Respostas de APIs externas** (quando a resposta não é confiável)
|
||||||
|
|
||||||
|
### 2. Schemas devem residir no pacote `*-comuns`
|
||||||
|
|
||||||
|
Para que front e back compartilhem os mesmos schemas, eles devem residir no pacote `<modulo>-comuns`:
|
||||||
|
|
||||||
|
```
|
||||||
|
<modulo>-comuns/src/
|
||||||
|
├── tabelas/
|
||||||
|
│ ├── usuarios/
|
||||||
|
│ │ ├── zUsuarioCriar.ts
|
||||||
|
│ │ ├── zUsuarioEditar.ts
|
||||||
|
│ │ └── index.ts
|
||||||
|
│ ├── empresas/
|
||||||
|
│ │ ├── zEmpresaCriar.ts
|
||||||
|
│ │ └── index.ts
|
||||||
|
│ └── index.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Tipos devem ser derivados dos schemas (nunca o inverso)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ CORRETO — tipo derivado do schema
|
||||||
|
export const zUsuarioCriar = z.object({
|
||||||
|
nome: z.string().min(1),
|
||||||
|
email: z.string().email(),
|
||||||
|
ativo: z.boolean().default(true),
|
||||||
|
})
|
||||||
|
export type tipoUsuarioCriar = z.infer<typeof zUsuarioCriar>
|
||||||
|
|
||||||
|
// ❌ ERRADO — tipo manual separado do schema
|
||||||
|
interface UsuarioCriar {
|
||||||
|
nome: string
|
||||||
|
email: string
|
||||||
|
ativo?: boolean
|
||||||
|
}
|
||||||
|
const zUsuarioCriar = z.object({ ... }) // duplicação!
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Nomenclatura obrigatória de schemas
|
||||||
|
|
||||||
|
| Padrão | Uso | Exemplo |
|
||||||
|
|--------|-----|---------|
|
||||||
|
| `z{Entidade}Criar` | Criação de registro | `zUsuarioCriar` |
|
||||||
|
| `z{Entidade}Editar` | Edição de registro | `zUsuarioEditar` |
|
||||||
|
| `z{Entidade}Filtro` | Filtros de listagem | `zUsuarioFiltro` |
|
||||||
|
| `z{Entidade}Resposta` | Resposta de API | `zUsuarioResposta` |
|
||||||
|
| `z{Entidade}Params` | Parâmetros de rota | `zUsuarioParams` |
|
||||||
|
| `z{Modulo}Config` | Configuração do módulo | `zGeeConfig` |
|
||||||
|
| `z{Modulo}Ambiente` | Variáveis de ambiente | `zBackAmbiente` |
|
||||||
|
|
||||||
|
Prefixo `z` minúsculo + nome em `PascalCase`.
|
||||||
|
|
||||||
|
### 5. Usar `safeParse` em vez de `parse` para erros controlados
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ CORRETO — erro controlado
|
||||||
|
const resultado = zUsuarioCriar.safeParse(dados)
|
||||||
|
if (!resultado.success) {
|
||||||
|
return respostaComuns.erro(resultado.error.issues[0].message)
|
||||||
|
}
|
||||||
|
const usuario = resultado.data // tipado automaticamente
|
||||||
|
|
||||||
|
// ❌ ERRADO — throw não controlado
|
||||||
|
const usuario = zUsuarioCriar.parse(dados) // lança ZodError
|
||||||
|
```
|
||||||
|
|
||||||
|
A exceção é em contextos onde o throw é desejável (middleware global, início de pipeline).
|
||||||
|
|
||||||
|
### 6. Nunca usar validação manual quando Zod resolve
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ ERRADO — validação manual
|
||||||
|
if (!dados.nome || typeof dados.nome !== "string") {
|
||||||
|
return erro("Nome é obrigatório")
|
||||||
|
}
|
||||||
|
if (!dados.email || !dados.email.includes("@")) {
|
||||||
|
return erro("Email inválido")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ CORRETO — Zod faz tudo
|
||||||
|
const resultado = zUsuarioCriar.safeParse(dados)
|
||||||
|
if (!resultado.success) {
|
||||||
|
return erro(resultado.error.issues[0].message)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. Transformações e defaults pertencem ao schema
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ CORRETO — transformação no schema
|
||||||
|
export const zProdutoCriar = z.object({
|
||||||
|
nome: z.string().trim().min(1),
|
||||||
|
preco: z.coerce.number().positive(),
|
||||||
|
ativo: z.boolean().default(true),
|
||||||
|
codigo: z.string().toUpperCase().optional(),
|
||||||
|
tags: z.array(z.string()).default([]),
|
||||||
|
})
|
||||||
|
|
||||||
|
// ❌ ERRADO — transformação manual após validação
|
||||||
|
const produto = zProdutoCriar.parse(dados)
|
||||||
|
produto.nome = produto.nome.trim()
|
||||||
|
produto.codigo = produto.codigo?.toUpperCase()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8. Composição de schemas em vez de duplicação
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ CORRETO — composição
|
||||||
|
const zEndereco = z.object({
|
||||||
|
rua: z.string(),
|
||||||
|
cidade: z.string(),
|
||||||
|
uf: z.string().length(2),
|
||||||
|
})
|
||||||
|
|
||||||
|
const zEmpresaCriar = z.object({
|
||||||
|
nome: z.string(),
|
||||||
|
endereco: zEndereco,
|
||||||
|
})
|
||||||
|
|
||||||
|
const zEmpresaEditar = zEmpresaCriar.partial() // todos opcionais
|
||||||
|
|
||||||
|
const zEmpresaResposta = zEmpresaCriar.extend({
|
||||||
|
codigo: z.string().uuid(),
|
||||||
|
criadoEm: z.string().datetime(),
|
||||||
|
})
|
||||||
|
|
||||||
|
// ❌ ERRADO — copiar campos entre schemas
|
||||||
|
const zEmpresaEditar = z.object({
|
||||||
|
nome: z.string().optional(), // duplicou!
|
||||||
|
endereco: z.object({ // duplicou!
|
||||||
|
rua: z.string().optional(),
|
||||||
|
cidade: z.string().optional(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9. Enums Zod para valores de domínio
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ CORRETO — enum Zod quando os valores vêm de dados externos
|
||||||
|
export const zStatusLicenca = z.enum(["ativa", "vencida", "suspensa", "cancelada"])
|
||||||
|
export type tipoStatusLicenca = z.infer<typeof zStatusLicenca>
|
||||||
|
|
||||||
|
// Usar em outros schemas
|
||||||
|
const zLicencaCriar = z.object({
|
||||||
|
status: zStatusLicenca,
|
||||||
|
// ...
|
||||||
|
})
|
||||||
|
|
||||||
|
// ✅ TAMBÉM CORRETO — TypeScript enum quando já existe no projeto
|
||||||
|
// e o schema referencia o enum
|
||||||
|
import { StatusLicenca } from "./enums"
|
||||||
|
const zLicencaCriar = z.object({
|
||||||
|
status: z.nativeEnum(StatusLicenca),
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10. Bibliotecas proibidas para validação
|
||||||
|
|
||||||
|
| ❌ Proibido | Motivo |
|
||||||
|
|-------------|--------|
|
||||||
|
| `joi` | Não infere tipos TS, bundle pesado |
|
||||||
|
| `yup` | Inferência fraca, API menos ergonômica |
|
||||||
|
| `class-validator` | Decorators, não compartilhável com frontend |
|
||||||
|
| `io-ts` | Verboso, curva de aprendizado alta |
|
||||||
|
| `ajv` (direto) | JSON Schema — usar `zod-to-json-schema` se precisar de JSON Schema |
|
||||||
|
| Validação manual com `if/typeof` | Quando Zod resolve o mesmo caso |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Exemplos
|
||||||
|
|
||||||
|
### API backend (Express)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Correto
|
||||||
|
import { zUsuarioCriar } from "projeto-comuns/tabelas/usuarios"
|
||||||
|
|
||||||
|
app.post("/usuarios", async (req, res) => {
|
||||||
|
const resultado = zUsuarioCriar.safeParse(req.body)
|
||||||
|
if (!resultado.success) {
|
||||||
|
return res.status(400).json({ erro: resultado.error.issues })
|
||||||
|
}
|
||||||
|
const usuario = await criarUsuario(resultado.data)
|
||||||
|
return res.json(usuario)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Webhook com fila
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Correto — valida antes de enfileirar
|
||||||
|
const zPayloadWebhook = z.object({
|
||||||
|
tabela: z.enum(["empreendedores", "empreendimentos", "usuarios"]),
|
||||||
|
dados: z.array(z.unknown()).min(1),
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post("/webhook/:tabela", async (req, res) => {
|
||||||
|
const resultado = zPayloadWebhook.safeParse({
|
||||||
|
tabela: req.params.tabela,
|
||||||
|
dados: req.body,
|
||||||
|
})
|
||||||
|
if (!resultado.success) {
|
||||||
|
return res.status(400).json({ erro: "Payload inválido" })
|
||||||
|
}
|
||||||
|
await fila.add("sync", resultado.data)
|
||||||
|
return res.json({ ok: true })
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Variáveis de ambiente
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Correto — validar no boot da aplicação
|
||||||
|
const zAmbiente = z.object({
|
||||||
|
DATABASE_URL: z.string().url(),
|
||||||
|
REDIS_HOST: z.string().default("localhost"),
|
||||||
|
REDIS_PORT: z.coerce.number().default(6379),
|
||||||
|
BASE_URL: z.string().url(),
|
||||||
|
SESSAO_BACK: z.string().uuid(),
|
||||||
|
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const ambiente = () => zAmbiente.parse(process.env)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend (formulário Vue)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ Correto — schema compartilhado validando antes de enviar
|
||||||
|
import { zUsuarioCriar } from "projeto-comuns/tabelas/usuarios"
|
||||||
|
|
||||||
|
const salvar = async () => {
|
||||||
|
const resultado = zUsuarioCriar.safeParse(formulario.value)
|
||||||
|
if (!resultado.success) {
|
||||||
|
erros.value = resultado.error.flatten().fieldErrors
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await api.post("/usuarios", resultado.data)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Impacto
|
||||||
|
|
||||||
|
Sem esta regra:
|
||||||
|
|
||||||
|
- Cada desenvolvedor escolhe uma estratégia diferente de validação (if/typeof, joi, yup, etc.)
|
||||||
|
- Tipos e schemas ficam dessincronizados — mudança no schema não reflete no tipo e vice-versa
|
||||||
|
- Validações manuais são incompletas e inconsistentes entre endpoints
|
||||||
|
- Código de validação é duplicado entre front e back
|
||||||
|
- Dados inválidos passam despercebidos e corrompem a base
|
||||||
|
|
||||||
|
Com esta regra:
|
||||||
|
|
||||||
|
- Uma única fonte de verdade: o schema Zod
|
||||||
|
- Tipos TypeScript sempre sincronizados via `z.infer<>`
|
||||||
|
- Validação consistente em todos os pontos de entrada
|
||||||
|
- Reutilização entre front, back e workers via pacote `*-comuns`
|
||||||
|
- Erros de validação estruturados e internacionalizáveis
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- Rule: `.agent/rules/typescript-sem-any.global.md` (narrowing com Zod mencionado como alternativa)
|
||||||
|
- Skill: `.agent/skills/criar-schema-zod.global/SKILL.md` (guia prático para criar schemas)
|
||||||
184
.agent/skills/criar-schema-zod.global/SKILL.md
Normal file
184
.agent/skills/criar-schema-zod.global/SKILL.md
Normal file
|
|
@ -0,0 +1,184 @@
|
||||||
|
---
|
||||||
|
name: criar-schema-zod
|
||||||
|
scope: global
|
||||||
|
description: >
|
||||||
|
Guia operacional para criar, organizar e manter schemas de validação Zod em projetos TypeScript.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Skill: Criar Schema Zod
|
||||||
|
|
||||||
|
Use esta skill ao adicionar validação de dados em qualquer ponto de entrada do sistema — API, formulário, webhook, importação, fila ou variáveis de ambiente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 1 — Identificar a Entrada Externa
|
||||||
|
|
||||||
|
Determinar qual dado externo precisa de validação:
|
||||||
|
|
||||||
|
| Tipo de entrada | Onde validar |
|
||||||
|
|---|---|
|
||||||
|
| Corpo de requisição (POST/PUT) | Handler da rota, antes de qualquer lógica |
|
||||||
|
| Query/path params | Handler da rota |
|
||||||
|
| Formulário frontend | Antes de chamar a API |
|
||||||
|
| Dados de fila (BullMQ) | No processador da fila |
|
||||||
|
| Arquivo importado (CSV/JSON) | No parser, linha a linha |
|
||||||
|
| Variáveis de ambiente | No boot da aplicação |
|
||||||
|
| Resposta de API externa | Após receber a resposta |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 2 — Localizar ou Criar o Schema no Pacote Comuns
|
||||||
|
|
||||||
|
Schemas compartilhados vivem no pacote `*-comuns`:
|
||||||
|
|
||||||
|
```
|
||||||
|
projeto-comuns/src/tabelas/
|
||||||
|
├── usuarios/
|
||||||
|
│ ├── zUsuarioCriar.ts
|
||||||
|
│ ├── zUsuarioEditar.ts
|
||||||
|
│ └── index.ts
|
||||||
|
└── index.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.1. Verificar se já existe
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rg "z{NomeDaEntidade}" --include='*.ts' -l
|
||||||
|
```
|
||||||
|
|
||||||
|
Se já existir → reutilizar ou compor a partir dele (`.extend()`, `.pick()`, `.partial()`).
|
||||||
|
|
||||||
|
### 2.2. Criar o schema
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
export const zUsuarioCriar = z.object({
|
||||||
|
nome: z.string().trim().min(1, "Nome é obrigatório"),
|
||||||
|
email: z.string().email("E-mail inválido"),
|
||||||
|
ativo: z.boolean().default(true),
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3. Nomenclatura obrigatória
|
||||||
|
|
||||||
|
| Padrão | Uso |
|
||||||
|
|---|---|
|
||||||
|
| `z{Entidade}Criar` | Criação |
|
||||||
|
| `z{Entidade}Editar` | Edição (geralmente `.partial()`) |
|
||||||
|
| `z{Entidade}Filtro` | Filtros de listagem |
|
||||||
|
| `z{Entidade}Resposta` | Resposta de API |
|
||||||
|
| `z{Entidade}Params` | Parâmetros de rota |
|
||||||
|
| `z{Modulo}Config` | Configuração |
|
||||||
|
| `z{Modulo}Ambiente` | Variáveis de ambiente |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 3 — Derivar o Tipo com `z.infer<>`
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export type tipoUsuarioCriar = z.infer<typeof zUsuarioCriar>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nunca** criar um `interface` ou `type` manual separado do schema. O tipo **sempre** deriva do schema.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 4 — Implementar `safeParse` no Ponto de Entrada
|
||||||
|
|
||||||
|
### Backend (Express)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { zUsuarioCriar } from "projeto-comuns/tabelas/usuarios"
|
||||||
|
|
||||||
|
app.post("/usuarios", async (req, res) => {
|
||||||
|
const resultado = zUsuarioCriar.safeParse(req.body)
|
||||||
|
if (!resultado.success) {
|
||||||
|
return res.status(400).json({ erro: resultado.error.issues[0].message })
|
||||||
|
}
|
||||||
|
const usuario = await criarUsuario(resultado.data)
|
||||||
|
return res.json(usuario)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend (Vue)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { zUsuarioCriar } from "projeto-comuns/tabelas/usuarios"
|
||||||
|
|
||||||
|
const salvar = async () => {
|
||||||
|
const resultado = zUsuarioCriar.safeParse(formulario.value)
|
||||||
|
if (!resultado.success) {
|
||||||
|
erros.value = resultado.error.flatten().fieldErrors
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await api.post("/usuarios", resultado.data)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Variáveis de ambiente
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const zAmbiente = z.object({
|
||||||
|
DATABASE_URL: z.string().url(),
|
||||||
|
REDIS_HOST: z.string().default("localhost"),
|
||||||
|
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Aqui o throw é desejável — a app não deve subir com env inválido
|
||||||
|
export const ambiente = () => zAmbiente.parse(process.env)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 5 — Compor Schemas Derivados
|
||||||
|
|
||||||
|
Quando precisar de variações do mesmo schema, **compor** em vez de duplicar:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Schema base
|
||||||
|
const zProduto = z.object({
|
||||||
|
nome: z.string().trim().min(1),
|
||||||
|
preco: z.coerce.number().positive(),
|
||||||
|
categoria: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Edição: todos os campos opcionais
|
||||||
|
const zProdutoEditar = zProduto.partial()
|
||||||
|
|
||||||
|
// Resposta: base + campos gerados
|
||||||
|
const zProdutoResposta = zProduto.extend({
|
||||||
|
codigo: z.string().uuid(),
|
||||||
|
criadoEm: z.string().datetime(),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Filtro: subset de campos opcionais
|
||||||
|
const zProdutoFiltro = zProduto.pick({ categoria: true }).partial()
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 6 — Validar Tipagem
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx tsc --noEmit
|
||||||
|
```
|
||||||
|
|
||||||
|
Zero erros = concluído.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checklist Final
|
||||||
|
|
||||||
|
- [ ] O schema está no pacote `*-comuns` (quando compartilhado entre front/back)?
|
||||||
|
- [ ] O tipo é derivado do schema com `z.infer<>`?
|
||||||
|
- [ ] A validação usa `safeParse` (exceto em boot/middleware)?
|
||||||
|
- [ ] A nomenclatura segue o padrão `z{Entidade}{Acao}`?
|
||||||
|
- [ ] Transformações (trim, coerce, default) estão no schema, não no handler?
|
||||||
|
- [ ] Schemas derivados usam composição (.partial, .extend, .pick), não duplicação?
|
||||||
|
- [ ] `tsc --noEmit` passa sem erros?
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- Rule: `.agent/rules/zod-validacao-padrao.global.md`
|
||||||
|
- Rule: `.agent/rules/typescript-sem-any.global.md`
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
name: diagnosticar-erros-build
|
name: diagnosticar-erros-build
|
||||||
scope: global
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
description: >
|
description: >
|
||||||
Guia operacional para diagnosticar e resolver erros de build em cascata em monorepos TypeScript.
|
Guia operacional para diagnosticar e resolver erros de build em cascata em monorepos TypeScript.
|
||||||
---
|
---
|
||||||
|
|
@ -181,5 +182,5 @@ pnpm install && pnpm build
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
- Rules: `.agent/rules/typescript-sem-any.global.md`
|
- Rules: `.agent/rules/typescript-sem-any.global.md`
|
||||||
- Workflow: `.agent/workflows/documentar-codigo.global.md`
|
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||||
- Skill: `.agent/skills/mapear-codigo-fonte/SKILL.md`
|
- Skill: `.agent/skills/mapear-codigo-fonte.global/SKILL.md`
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
name: documentar-decisao-tecnica
|
name: documentar-decisao-tecnica
|
||||||
scope: global
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
description: >
|
description: >
|
||||||
Guia operacional para registrar decisões técnicas e arquiteturais como ADRs (Architecture Decision Records).
|
Guia operacional para registrar decisões técnicas e arquiteturais como ADRs (Architecture Decision Records).
|
||||||
---
|
---
|
||||||
|
|
@ -157,4 +158,4 @@ Antes de considerar completo:
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
- Workflow: `.agent/workflows/aprimorar-IA.global.md` (seção de classificação de artefatos)
|
- Workflow: `.agent/workflows/aprimorar-IA.global.md` (seção de classificação de artefatos)
|
||||||
- Workflow: `.agent/workflows/documentar-codigo.global.md`
|
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||||
|
|
|
||||||
131
.agent/skills/documentar-dominio-modulo.global/SKILL.md
Normal file
131
.agent/skills/documentar-dominio-modulo.global/SKILL.md
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
---
|
||||||
|
name: documentar-dominio-modulo
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
|
description: >
|
||||||
|
Guia para documentar o domínio científico/técnico de cada módulo SaaS,
|
||||||
|
garantindo que o agente compreenda a terminologia e as regras do domínio
|
||||||
|
ao gerar código, texto e interface.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Skill: Documentar Domínio de um Módulo
|
||||||
|
|
||||||
|
Use esta skill ao iniciar um novo módulo SaaS ou ao perceber que o agente não conhece o vocabulário e as regras do domínio que o módulo aborda.
|
||||||
|
|
||||||
|
Cada módulo opera em uma disciplina diferente da ciência/gestão ambiental (licenciamento, gases de efeito estufa, resíduos, projetos, etc.). O agente precisa de uma **base factual do domínio** para gerar labels, mensagens, regras de negócio e textos comerciais corretos.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 1 — Identificar o Domínio do Módulo
|
||||||
|
|
||||||
|
Determinar qual área da ciência/gestão o módulo aborda:
|
||||||
|
|
||||||
|
| Exemplo de módulo | Domínio |
|
||||||
|
|---|---|
|
||||||
|
| Licenciamento | Licenciamento ambiental (LP, LI, LO, condicionantes) |
|
||||||
|
| GEE | Gases de Efeito Estufa (inventário, emissões, fatores) |
|
||||||
|
| Resíduos | Gestão de resíduos sólidos (PGRS, MTR, classificação) |
|
||||||
|
| Outorga | Outorga de uso de recursos hídricos |
|
||||||
|
| Flora/Fauna | Monitoramento de biodiversidade |
|
||||||
|
| Projetos | Gestão de projetos ambientais e consultorias |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 2 — Criar o Arquivo de Domínio
|
||||||
|
|
||||||
|
Criar em `.agent/memoria/dominio-<modulo>.md`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Domínio: <Nome do Módulo>
|
||||||
|
|
||||||
|
## Área de Conhecimento
|
||||||
|
Breve descrição da disciplina (1-3 linhas).
|
||||||
|
|
||||||
|
## Glossário do Módulo
|
||||||
|
|
||||||
|
| Termo | Definição | Sigla |
|
||||||
|
|---|---|---|
|
||||||
|
| Licença Prévia | Autorização para planejamento do empreendimento | LP |
|
||||||
|
| Licença de Instalação | Autorização para início das obras | LI |
|
||||||
|
| ... | ... | ... |
|
||||||
|
|
||||||
|
## Entidades Principais
|
||||||
|
|
||||||
|
Lista das entidades de negócio do módulo com descrição e relações:
|
||||||
|
|
||||||
|
- **Empreendimento**: unidade física onde ocorre a atividade potencialmente poluidora
|
||||||
|
- **Licença**: autorização ambiental vinculada a um empreendimento
|
||||||
|
- **Condicionante**: obrigação imposta pelo órgão ambiental na licença
|
||||||
|
- ...
|
||||||
|
|
||||||
|
## Legislação Aplicável
|
||||||
|
|
||||||
|
| Norma | Descrição | Relevância |
|
||||||
|
|---|---|---|
|
||||||
|
| Lei 6.938/1981 | Política Nacional do Meio Ambiente | Base legal do licenciamento |
|
||||||
|
| Resolução CONAMA 237/1997 | Regulamenta o licenciamento ambiental | Tipos de licença, prazos |
|
||||||
|
| ... | ... | ... |
|
||||||
|
|
||||||
|
## Regras de citação legal
|
||||||
|
- Formato: "Resolução CONAMA nº 237/1997, art. 8º, inciso I"
|
||||||
|
- Toda sigla na primeira ocorrência com nome por extenso
|
||||||
|
- Legislação federal > estadual > municipal (hierarquia)
|
||||||
|
|
||||||
|
## Fluxos do Domínio
|
||||||
|
|
||||||
|
Descrever os processos-chave que o módulo implementa:
|
||||||
|
|
||||||
|
1. Solicitação de licença → Análise técnica → Emissão → Monitoramento
|
||||||
|
2. Cadastro de condicionante → Acompanhamento de prazo → Cumprimento
|
||||||
|
|
||||||
|
## Vocabulário de Interface
|
||||||
|
|
||||||
|
Termos que devem ser usados em labels, botões e mensagens:
|
||||||
|
|
||||||
|
| Contexto | ❌ Genérico | ✅ Correto para o módulo |
|
||||||
|
|---|---|---|
|
||||||
|
| Campo de nome | "Nome" | "Razão Social do Empreendedor" |
|
||||||
|
| Status | "Ativo/Inativo" | "Vigente/Vencida/Suspensa" |
|
||||||
|
| Ação principal | "Criar novo" | "Solicitar nova licença" |
|
||||||
|
| Lista vazia | "Nenhum registro" | "Nenhuma licença cadastrada" |
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 3 — Validar com o Operador
|
||||||
|
|
||||||
|
Antes de consolidar:
|
||||||
|
|
||||||
|
- [ ] Os termos do glossário estão corretos para o contexto do módulo?
|
||||||
|
- [ ] As entidades cobrem os conceitos centrais?
|
||||||
|
- [ ] A legislação listada é a principal (não exaustiva)?
|
||||||
|
- [ ] O vocabulário de interface reflete como o usuário fala no dia a dia?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PASSO 4 — Conectar com as Rules
|
||||||
|
|
||||||
|
Após documentar o domínio:
|
||||||
|
|
||||||
|
1. Verificar se labels e mensagens no código usam o vocabulário definido (rule `mensagens-usuario.global.md`)
|
||||||
|
2. Verificar se schemas Zod têm mensagens de erro no idioma do domínio (rule `zod-validacao-padrao.global.md`)
|
||||||
|
3. Verificar se os arquivos `.ajuda.md` usam termos do glossário (workflow `adicionar-ajuda.global.md`)
|
||||||
|
4. Verificar se textos comerciais citam a legislação corretamente (workflow `comercial.global.md`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checklist Final
|
||||||
|
|
||||||
|
- [ ] Arquivo `dominio-<modulo>.md` criado em `.agent/memoria/`?
|
||||||
|
- [ ] Glossário com pelo menos os 10 termos centrais do módulo?
|
||||||
|
- [ ] Entidades principais listadas com descrição?
|
||||||
|
- [ ] Legislação base documentada com formato de citação?
|
||||||
|
- [ ] Vocabulário de interface definido (labels, status, ações, empty states)?
|
||||||
|
- [ ] Operador validou a terminologia?
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- Rule: `.agent/rules/mensagens-usuario.global.md`
|
||||||
|
- Rule: `.agent/rules/regras-negocio-md.global.md`
|
||||||
|
- Workflow: `.agent/workflows/comercial.global.md`
|
||||||
|
- Workflow: `.agent/workflows/adicionar-ajuda.global.md`
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
---
|
---
|
||||||
name: documentar-regras-negocio.global
|
name: documentar-regras-negocio
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
description: >
|
description: >
|
||||||
Guia operacional para criar, preencher e manter arquivos {modulo}.regras-negocio.md
|
Guia operacional para criar, preencher e manter arquivos {modulo}.regras-negocio.md
|
||||||
co-localizados com módulos TypeScript de lógica de negócio complexa.
|
co-localizados com módulos TypeScript de lógica de negócio complexa.
|
||||||
|
|
@ -206,7 +208,5 @@ Percorrer cada regra listada no `.md` e verificar que há código correspondente
|
||||||
|
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
- Rule: `.agent/rules/regras_negocio_md.global.md`
|
- Rule: `.agent/rules/regras-negocio-md.global.md`
|
||||||
- Workflow: `.agent/workflows/documentar-regras-negocio.global.md`
|
- Workflow: `.agent/workflows/documentar-regras-negocio.global.md`
|
||||||
- Skill: `.agent/skills/consultar-banco-knex/SKILL.md` (orderBy em whereIn)
|
|
||||||
- ADR: `.agent/memoria/adr-003-crons-complexos-compilacao-execucao.md`
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
name: mapear-codigo-fonte
|
name: mapear-codigo-fonte
|
||||||
scope: global
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
description: >
|
description: >
|
||||||
Guia operacional para mapear, navegar e compreender a estrutura de um monorepo TypeScript.
|
Guia operacional para mapear, navegar e compreender a estrutura de um monorepo TypeScript.
|
||||||
---
|
---
|
||||||
|
|
@ -156,4 +157,4 @@ Descrever como os dados fluem entre pacotes.
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
- Rules: `.agent/rules/typescript-sem-any.global.md`
|
- Rules: `.agent/rules/typescript-sem-any.global.md`
|
||||||
- Workflow: `.agent/workflows/documentar-codigo.global.md`
|
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ Para instalar as ferramentas base de forma ágil e em lote, copie os blocos de c
|
||||||
```bash
|
```bash
|
||||||
# 1. Atualizar e instalar ferramentas base do sistema
|
# 1. Atualizar e instalar ferramentas base do sistema
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y ripgrep fd-find jq shellcheck bat tree httpie gh
|
sudo apt-get install -y ripgrep fd-find jq shellcheck bat tree eza httpie gh
|
||||||
|
|
||||||
# 2. Instalar ferramentas em Node
|
# 2. Instalar ferramentas em Node
|
||||||
npm install -g @ast-grep/cli @biomejs/biome
|
npm install -g @ast-grep/cli @biomejs/biome
|
||||||
|
|
|
||||||
41
.agent/verificar-linhas.sh
Normal file
41
.agent/verificar-linhas.sh
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# comando sh ../.agent/verificar-linhas.sh || exit 1
|
||||||
|
|
||||||
|
LIMITE=250
|
||||||
|
|
||||||
|
RAIZ=$(cd "$(dirname "$0")/.." && pwd)
|
||||||
|
|
||||||
|
RESULTADO=$(
|
||||||
|
find "$RAIZ" \
|
||||||
|
-type d \( \
|
||||||
|
-name node_modules -o \
|
||||||
|
-name .git -o \
|
||||||
|
-name dist -o \
|
||||||
|
-name build \
|
||||||
|
\) -prune \
|
||||||
|
-o \
|
||||||
|
-type f \( \
|
||||||
|
-name "*.ts" -o \
|
||||||
|
-name "*.tsx" -o \
|
||||||
|
-name "*.vue" -o \
|
||||||
|
-name "*.css" \
|
||||||
|
\) \
|
||||||
|
-print | while IFS= read -r arquivo; do
|
||||||
|
linhas=$(wc -l < "$arquivo" | tr -d ' ')
|
||||||
|
if [ "$linhas" -gt "$LIMITE" ]; then
|
||||||
|
relativo="${arquivo#$RAIZ/}"
|
||||||
|
printf "%5s linhas -> %s\n" "$linhas" "$relativo"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ -n "$RESULTADO" ]; then
|
||||||
|
echo "$RESULTADO"
|
||||||
|
VIOLACOES=$(printf '%s\n' "$RESULTADO" | wc -l | tr -d ' ')
|
||||||
|
printf "\n❌ %s arquivo(s) violam o limite de %s linhas.\n" "$VIOLACOES" "$LIMITE"
|
||||||
|
printf "\n Resolva usando o arquivo: .agent/workflows/otimizar-codigos.global.md\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "✅ Todos os arquivos dentro do limite de %s linhas.\n" "$LIMITE"
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: adicionar-ajuda
|
||||||
description: Adicionar ou atualizar botão de ajuda e documentação em telas (Frontend)
|
description: Adicionar ou atualizar botão de ajuda e documentação em telas (Frontend)
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Adicionar Ajuda em Telas
|
# Workflow: Adicionar Ajuda em Telas
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: aprimorar-IA
|
||||||
description: Consolidar aprendizados da conversa atual e evoluir continuamente as regras, skills e fluxos da aplicação
|
description: Consolidar aprendizados da conversa atual e evoluir continuamente as regras, skills e fluxos da aplicação
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Aprimorar Conhecimento da Aplicação
|
# Workflow: Aprimorar Conhecimento da Aplicação
|
||||||
|
|
@ -74,7 +78,7 @@ Para cada item identificado, classificar obrigatoriamente:
|
||||||
### Estrutura obrigatória:
|
### Estrutura obrigatória:
|
||||||
|
|
||||||
- Um arquivo = um único assunto.
|
- Um arquivo = um único assunto.
|
||||||
- Nome claro em `snake_case`.
|
- Nome claro em `kebab-case`.
|
||||||
- Limite máximo: ~10.000 caracteres.
|
- Limite máximo: ~10.000 caracteres.
|
||||||
|
|
||||||
### É obrigatório:
|
### É obrigatório:
|
||||||
|
|
@ -196,105 +200,64 @@ Exemplos de skills de projeto:
|
||||||
Sempre que decisões críticas sobre a arquitetura da aplicação ou o contexto do domínio precisarem ser arquivadas temporária ou permanentemente de maneira descritiva (e não diretamente injetável em código ou regra de lint):
|
Sempre que decisões críticas sobre a arquitetura da aplicação ou o contexto do domínio precisarem ser arquivadas temporária ou permanentemente de maneira descritiva (e não diretamente injetável em código ou regra de lint):
|
||||||
|
|
||||||
* Registre o novo documento no formato adequado mantendo a pasta limpa em `.agent/memoria/`.
|
* Registre o novo documento no formato adequado mantendo a pasta limpa em `.agent/memoria/`.
|
||||||
* Exemplo: Manter diário de pendências (`diario_pendencias_modulo_x.md`) ou Arquivo de Registro de Decisão Arquitetural (`adr-001-migracao-nuxt-4.md`).
|
* Exemplo: Manter diário de pendências (`diario-pendencias-modulo-x.md`) ou ADR (`adr-001-migracao-nuxt-4.md`).
|
||||||
* Atenção! Tudo que puder ser abstraído para um formato técnico estrito/guiado, deve virar **Skill** ou **Rule**. Use a Memória apenas como extensão de base factual.
|
* Atenção! Tudo que puder ser abstraído para formato técnico estrito deve virar **Skill** ou **Rule**. Use a Memória apenas como extensão de base factual.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6️⃣ Revisão Global de TODO o Sistema de Conhecimento (OBRIGATÓRIA E INEGOCIÁVEL)
|
## 6️⃣ Revisão de Impacto (Dirigida por Grafo)
|
||||||
|
|
||||||
Esta é a etapa mais crítica.
|
Quando um artefato é alterado, a revisão deve ser **dirigida**, não exaustiva.
|
||||||
|
|
||||||
Sempre que qualquer alteração ocorrer, é **OBRIGATÓRIO revisar TODO o sistema de conhecimento**, incluindo:
|
### Processo:
|
||||||
|
|
||||||
* **TODOS os arquivos em `.agent/rules/`**
|
1. Identificar o artefato alterado
|
||||||
* **TODOS os arquivos em `.agent/workflows/`**
|
2. Consultar a seção `Referências` do artefato para encontrar dependentes diretos
|
||||||
* **TODOS os arquivos em `.agent/skills/`**
|
3. Verificar consistência APENAS entre o artefato alterado e seus dependentes
|
||||||
* **TODOS os arquivos em `.agent/memoria/`**
|
4. Se uma inconsistência for encontrada, propagar para o próximo nível
|
||||||
|
|
||||||
|
### Regras de escopo:
|
||||||
|
|
||||||
|
| Se alterou... | Revisar... |
|
||||||
|
|---|---|
|
||||||
|
| Uma **Rule** | Workflows e skills que a **referenciam** |
|
||||||
|
| Um **Workflow** | Skills que o **referenciam** |
|
||||||
|
| Uma **Skill** | Rules e workflows na seção Referências |
|
||||||
|
| **Memória/ADR** | Nada — memória é registro, não dependência |
|
||||||
|
|
||||||
### É PROIBIDO:
|
### É PROIBIDO:
|
||||||
|
|
||||||
* Atualizar apenas um arquivo isolado.
|
* Revisar artefatos **sem relação** com a mudança
|
||||||
* Assumir que o impacto é local.
|
* Afirmar que "tudo foi revisado" sem listar quais artefatos foram verificados
|
||||||
* Ignorar arquivos existentes.
|
* Criar artefatos sem verificar se já existe um com o mesmo escopo
|
||||||
* Criar artefatos sem validar o restante do sistema.
|
|
||||||
|
### A revisão DEVE verificar:
|
||||||
|
|
||||||
|
* Não existem regras conflitantes entre o artefato alterado e seus dependentes
|
||||||
|
* Referências cruzadas continuam válidas (arquivos existem, nomes corretos)
|
||||||
|
* Skills refletem fielmente as rules que referenciam
|
||||||
|
* Não há duplicação de conteúdo entre artefatos
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### A revisão DEVE obrigatoriamente verificar:
|
## 7⃣ Verificação Final (Checklist obrigatório)
|
||||||
|
|
||||||
#### Consistência
|
|
||||||
|
|
||||||
* Não existem regras conflitantes.
|
|
||||||
* Não existem interpretações ambíguas.
|
|
||||||
* Skills refletem fielmente as rules e workflows atuais.
|
|
||||||
|
|
||||||
#### Atualização
|
|
||||||
|
|
||||||
* Nenhuma rule está desatualizada.
|
|
||||||
* Nenhum workflow usa regra antiga.
|
|
||||||
* Nenhuma skill contém padrões obsoletos.
|
|
||||||
|
|
||||||
#### Não duplicação
|
|
||||||
|
|
||||||
* Não existem regras repetidas em arquivos diferentes.
|
|
||||||
* Conteúdos redundantes foram consolidados.
|
|
||||||
* Skills referenciam rules (não copiam o conteúdo).
|
|
||||||
|
|
||||||
#### Propagação de impacto
|
|
||||||
|
|
||||||
* Toda mudança foi refletida em:
|
|
||||||
|
|
||||||
* Rules relacionadas
|
|
||||||
* Workflows relacionados
|
|
||||||
* Skills relacionadas
|
|
||||||
* Memória afetada pela mudança (ADRs, Diários)
|
|
||||||
|
|
||||||
#### Coerência estrutural
|
|
||||||
|
|
||||||
* Nomes de arquivos continuam válidos.
|
|
||||||
* Assuntos estão bem separados.
|
|
||||||
* Arquivos grandes foram divididos.
|
|
||||||
* Skills estão organizadas em diretórios individuais.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Regras obrigatórias desta etapa:
|
|
||||||
|
|
||||||
* **Toda alteração é considerada global até prova contrária.**
|
|
||||||
* **Se uma rule muda, todos os workflows e skills relacionados DEVEM ser revisados.**
|
|
||||||
* **Se um workflow muda, todas as rules e skills relacionadas DEVEM ser revisadas.**
|
|
||||||
* **Se uma skill muda, as rules e workflows que ela referencia DEVEM ser verificados.**
|
|
||||||
* **Atualizações de contexto devem garantir que toda a memória conflitante seja suprimida ou tagueada.**
|
|
||||||
* **Nenhuma inconsistência pode permanecer.**
|
|
||||||
* **Nenhuma duplicação é aceitável.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7️⃣ Verificação Final (Checklist obrigatório)
|
|
||||||
|
|
||||||
Só é permitido encerrar se TODOS forem verdadeiros:
|
Só é permitido encerrar se TODOS forem verdadeiros:
|
||||||
|
|
||||||
* [ ] Todas as rules foram revisadas
|
* [ ] Artefatos dependentes do alterado foram revisados
|
||||||
* [ ] Todos os workflows foram revisados
|
* [ ] Não existe conflito entre artefatos revisados
|
||||||
* [ ] Todas as skills foram revisadas
|
|
||||||
* [ ] Não existe conflito entre artefatos
|
|
||||||
* [ ] Não existe duplicação de conteúdo
|
* [ ] Não existe duplicação de conteúdo
|
||||||
* [ ] Nenhuma regra ficou implícita
|
* [ ] Nenhuma regra ficou implícita
|
||||||
* [ ] Todas as mudanças foram propagadas (rules ↔ workflows ↔ skills)
|
* [ ] Referências cruzadas estão válidas
|
||||||
* [ ] Estrutura está organizada por assunto
|
* [ ] Estrutura está organizada por assunto
|
||||||
* [ ] Nenhum arquivo excede ~10k caracteres
|
|
||||||
* [ ] Workflows refletem fielmente as rules atuais
|
|
||||||
* [ ] Skills referenciam (não duplicam) rules
|
* [ ] Skills referenciam (não duplicam) rules
|
||||||
* [ ] O sistema está consistente como um todo
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚠️ Regra Suprema
|
## ⚠️ Regra Suprema
|
||||||
|
|
||||||
> Se existir qualquer dúvida, conflito, duplicação ou inconsistência,
|
> Se existir qualquer dúvida, conflito ou inconsistência
|
||||||
|
> entre o artefato alterado e seus dependentes,
|
||||||
> o trabalho é considerado **INCOMPLETO**.
|
> o trabalho é considerado **INCOMPLETO**.
|
||||||
|
|
||||||
Não existe atualização parcial.
|
A revisão é dirigida, não opcional.
|
||||||
Não existe impacto local.
|
|
||||||
Não existe exceção.
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: atualizar-agente
|
||||||
description: Aplica atualizações globais para o agente de IA
|
description: Aplica atualizações globais para o agente de IA
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Atualizar Agente Global
|
# Workflow: Atualizar Agente Global
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: comercial
|
||||||
description: Criar uma descrição comercial das funcionalidades e do sistema
|
description: Criar uma descrição comercial das funcionalidades e do sistema
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Criar Descrição Comercial
|
# Workflow: Criar Descrição Comercial
|
||||||
|
|
@ -137,4 +141,4 @@ O arquivo `./COMERCIAL/<nome-do-modulo>.md` deve seguir esta estrutura:
|
||||||
- Regra global: `.agent/rules/escrita-natural.global.md` (padrão obrigatório de redação)
|
- Regra global: `.agent/rules/escrita-natural.global.md` (padrão obrigatório de redação)
|
||||||
- Workflow: `.agent/workflows/orcamento.global.md` (texto para documentos de orçamento e proposta — apresentação + lista de funcionalidades)
|
- Workflow: `.agent/workflows/orcamento.global.md` (texto para documentos de orçamento e proposta — apresentação + lista de funcionalidades)
|
||||||
- Workflow: `.agent/workflows/marketing.global.md` (peças de marketing digital — LinkedIn, Instagram, WhatsApp, E-mail)
|
- Workflow: `.agent/workflows/marketing.global.md` (peças de marketing digital — LinkedIn, Instagram, WhatsApp, E-mail)
|
||||||
- Workflow: `.agent/workflows/documentar-codigo.global.md` (para documentação técnica, não comercial)
|
- Workflow: `.agent/workflows/otimizar-codigos.global.md` (para documentação técnica, não comercial)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: criar-fluxograma
|
||||||
description: Criar ou atualizar uma página de fluxograma interativo em qualquer sistema
|
description: Criar ou atualizar uma página de fluxograma interativo em qualquer sistema
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Criar Fluxograma de Decisões
|
# Workflow: Criar Fluxograma de Decisões
|
||||||
|
|
@ -181,5 +185,5 @@ Caso contrário, seguir os passos acima para criar a primeira implementação.
|
||||||
|
|
||||||
## Referências
|
## Referências
|
||||||
|
|
||||||
- Workflow: `.agent/workflows/documentar-codigo.global.md`
|
- Workflow: `.agent/workflows/otimizar-codigos.global.md`
|
||||||
- Skill: `.agent/skills/documentar-decisao-tecnica/SKILL.md` (para decisões que geram fluxogramas)
|
- Skill: `.agent/skills/documentar-decisao-tecnica.global/SKILL.md` (para decisões que geram fluxogramas)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: documentar-regras-negocio
|
||||||
description: Criar ou atualizar o arquivo {modulo}.regras-negocio.md co-localizado com um módulo TypeScript e garantir consistência entre código e documentação
|
description: Criar ou atualizar o arquivo {modulo}.regras-negocio.md co-localizado com um módulo TypeScript e garantir consistência entre código e documentação
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Documentar Regras de Negócio de um Módulo
|
# Workflow: Documentar Regras de Negócio de um Módulo
|
||||||
|
|
@ -86,7 +90,7 @@ Para cada regra listada no `.md`:
|
||||||
|
|
||||||
// turbo
|
// turbo
|
||||||
```bash
|
```bash
|
||||||
cd e-licencie-back && node_modules/.bin/tsc --noEmit
|
npx tsc --noEmit
|
||||||
```
|
```
|
||||||
|
|
||||||
Zero erros = concluído.
|
Zero erros = concluído.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: marketing
|
||||||
description: Criar peças de marketing digital para funcionalidades e módulos do sistema
|
description: Criar peças de marketing digital para funcionalidades e módulos do sistema
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Criar Peças de Marketing
|
# Workflow: Criar Peças de Marketing
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: orcamento
|
||||||
description: Criar texto de orçamento pronto para copiar e colar em peças de orçamento/proposta
|
description: Criar texto de orçamento pronto para copiar e colar em peças de orçamento/proposta
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Criar Texto de Orçamento
|
# Workflow: Criar Texto de Orçamento
|
||||||
|
|
|
||||||
|
|
@ -1,221 +1,76 @@
|
||||||
---
|
---
|
||||||
description: Otimizar código e documentar padrões de qualidade (estrutura, limites, JSDoc e tipagem)
|
type: workflow
|
||||||
|
name: otimizar-codigos
|
||||||
|
description: Processo de refatoração e validação de qualidade de código
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# Workflow: Qualidade e Otimização de Código
|
||||||
|
|
||||||
# Workflow: Qualidade e Documentação de Código
|
|
||||||
|
|
||||||
## 🎯 Objetivo
|
## 🎯 Objetivo
|
||||||
|
|
||||||
Unificar as regras de **estrutura de arquivos**, **otimização** e **documentação** em um único fluxo de referência para o projeto `eli-vue`.
|
Aplicar as rules de qualidade do ecossistema Azteca em código existente ou novo, garantindo que todos os padrões sejam cumpridos antes de finalizar uma tarefa.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1️⃣ Limite de Linhas por Arquivo
|
## Passos
|
||||||
|
|
||||||
Nenhum arquivo `*.vue`, `*.ts` ou `*.tsx` pode ultrapassar **250 linhas**.
|
### 1. Verificar limite de linhas
|
||||||
|
|
||||||
Essa regra existe para facilitar a leitura humana, a revisão de código e a manutenção a longo prazo.
|
```bash
|
||||||
|
sh .agent/verificar-linhas.sh
|
||||||
> O script `scripts/check-vue-linhas.sh` valida automaticamente os arquivos `.vue` no `prebuild`.
|
|
||||||
|
|
||||||
**Estratégias quando o limite se aproxima:**
|
|
||||||
|
|
||||||
| Situação | Ação |
|
|
||||||
|---|---|
|
|
||||||
| Template longo | Extrair seções como subcomponentes |
|
|
||||||
| CSS extenso | Mover para `<nome>.css` co-localizado |
|
|
||||||
| `setup()` extenso | Extrair subcomponentes, CSS ou Dispatch Table |
|
|
||||||
| Modal/Dialog embutido | Sempre em componente separado (`*Modal.vue`) |
|
|
||||||
| Handlers e dispatch | Extrair para `handlers.ts` ou `dispatch.ts` |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2️⃣ Estrutura de Componentes Vue
|
|
||||||
|
|
||||||
### `defineComponent` obrigatório
|
|
||||||
|
|
||||||
Todo componente Vue deve usar `defineComponent` para garantir inferência de tipos correta e consistência.
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent } from 'vue'
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'MeuComponente',
|
|
||||||
setup() {
|
|
||||||
// lógica aqui
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Por que é importante:**
|
Se houver violações, aplicar estratégias da rule `limite-linhas.global.md`:
|
||||||
- Inferência de tipos TypeScript correta dentro do componente
|
- Extrair subcomponentes, mover CSS, usar Dispatch Table
|
||||||
- Reconhecimento por ferramentas de análise estática e IDEs
|
- Se necessário, converter em pasta com `index.vue`
|
||||||
- Compatível com Options API e Composition API com `setup()`
|
|
||||||
- Padronização entre todos os componentes do projeto
|
|
||||||
|
|
||||||
---
|
### 2. Validar estrutura Vue
|
||||||
|
|
||||||
### `setup()` não pode ser externo
|
Para cada componente `.vue` modificado, verificar conforme `estrutura-vue.global.md`:
|
||||||
|
- `defineComponent` presente?
|
||||||
|
- `setup()` contém lógica própria (não delegada)?
|
||||||
|
- CSS extenso foi movido para arquivo co-localizado?
|
||||||
|
|
||||||
O `setup()` deve estar sempre dentro do componente `.vue`. Não é permitido extrair ou delegar o `setup` para nenhum arquivo externo.
|
### 3. Documentar código
|
||||||
|
|
||||||
```ts
|
Para cada função compartilhada criada/modificada, aplicar `jsdoc-padrao.global.md`:
|
||||||
// ❌ Proibido — setup delegado inteiramente para arquivo externo
|
- JSDoc com `@param` e `@returns`?
|
||||||
// useEliTabela.ts
|
- Casts temporários têm comentário justificando?
|
||||||
export function useEliTabela(props, emit) { ... }
|
- TODOs no formato padronizado?
|
||||||
|
|
||||||
// EliTabela.vue
|
### 4. Validar tipagem
|
||||||
export default defineComponent({
|
|
||||||
setup(props, { emit }) {
|
```bash
|
||||||
return useEliTabela(props, emit) // setup é apenas um proxy vazio
|
npx tsc --noEmit
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```ts
|
Zero erros = prosseguir. Se houver erros, aplicar `typescript-sem-any.global.md` — nunca resolver com `any`.
|
||||||
// ✅ Correto — setup com lógica própria dentro do componente
|
|
||||||
// EliTabela.vue
|
|
||||||
export default defineComponent({
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const estado = ref(null)
|
|
||||||
const carregar = async () => { ... }
|
|
||||||
return { estado, carregar }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
> Composables `use*.ts` podem encapsular lógica reutilizável pontual (ex: `useFormatador`, `usePermissao`), mas nunca substituir ou esvaziar o `setup()` do componente. Se o componente ultrapassar 250 linhas, a solução é extrair subcomponentes, mover CSS ou usar Dispatch Table — não esvaziar o `setup`.
|
### 5. Formatar
|
||||||
|
|
||||||
---
|
```bash
|
||||||
|
npx biome check --write .
|
||||||
### Desassociação de CSS
|
|
||||||
|
|
||||||
A separação de estilos em arquivo externo é permitida e recomendada quando o CSS contribui significativamente para o total de linhas.
|
|
||||||
|
|
||||||
**Padrão de nomenclatura:**
|
|
||||||
|
|
||||||
```
|
|
||||||
MeuComponente.vue
|
|
||||||
MeuComponente.css
|
|
||||||
```
|
|
||||||
|
|
||||||
O `.vue` importa o arquivo CSS no script:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import './MeuComponente.css'
|
|
||||||
```
|
|
||||||
|
|
||||||
Ou via tag `<style>`:
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<style src="./MeuComponente.css" />
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Dispatch Table em Arquivo Separado
|
## Checklist Final
|
||||||
|
|
||||||
O uso de Dispatch Table (mapa de funções) em arquivos separados é bem-vindo para eliminar blocos longos de `if/else` ou `switch`.
|
- [ ] `verificar-linhas.sh` passa sem violações?
|
||||||
|
- [ ] Componentes Vue usam `defineComponent`?
|
||||||
|
- [ ] Funções compartilhadas têm JSDoc?
|
||||||
|
- [ ] Casts temporários estão justificados?
|
||||||
|
- [ ] `tsc --noEmit` zero erros?
|
||||||
|
- [ ] `biome check` sem problemas?
|
||||||
|
|
||||||
```ts
|
## Rules Aplicadas
|
||||||
// handlers.ts
|
|
||||||
export const acaoHandlers: Record<string, () => void> = {
|
|
||||||
salvar: () => { ... },
|
|
||||||
cancelar: () => { ... },
|
|
||||||
excluir: () => { ... },
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
Este workflow orquestra a verificação das seguintes rules:
|
||||||
// MeuComponente.vue
|
|
||||||
import { acaoHandlers } from './handlers'
|
|
||||||
|
|
||||||
function executar(acao: string) {
|
- `.agent/rules/limite-linhas.global.md` — máximo 250 linhas
|
||||||
acaoHandlers[acao]?.()
|
- `.agent/rules/estrutura-vue.global.md` — defineComponent, setup, CSS, dispatch
|
||||||
}
|
- `.agent/rules/jsdoc-padrao.global.md` — JSDoc, casts, TODOs
|
||||||
```
|
- `.agent/rules/typescript-sem-any.global.md` — proibição de any
|
||||||
|
- `.agent/rules/zod-validacao-padrao.global.md` — validação de entradas externas
|
||||||
---
|
|
||||||
|
|
||||||
## 3️⃣ Documentação em Código (JSDoc)
|
|
||||||
|
|
||||||
### Princípios básicos
|
|
||||||
|
|
||||||
- **Por que, não o Quê**: Documente o raciocínio por trás da decisão arquitetural, não o mecanismo óbvio que o TypeScript já expressa.
|
|
||||||
- **Nomenclatura limpa**: Confie na auto-documentação de nomes expressivos antes de escrever comentários de texto livre.
|
|
||||||
|
|
||||||
### Funções compartilhadas — JSDoc obrigatório
|
|
||||||
|
|
||||||
Toda função central ou de uso compartilhado (frontend, backend, mobile ou bibliotecas comuns) deve ter cabeçalho em `JSDoc`.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
/**
|
|
||||||
* Busca os detalhes de uma entidade baseando-se no ID fornecido e calcula privilégios aplicáveis.
|
|
||||||
* Não utilizar em fluxos de processamento em lote para evitar sobrecarga de requisições.
|
|
||||||
*
|
|
||||||
* @param tenantId - Identificador único do cliente/tenant no sistema
|
|
||||||
* @param entityId - ID exclusivo identificando o registro na base de dados
|
|
||||||
* @returns Retorna o objeto consolidado com dados ou `null` caso não seja encontrado
|
|
||||||
*/
|
|
||||||
export const obterDetalhesEntidade = async (tenantId: string, entityId: string) => { ... }
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4️⃣ Casts Temporários e Exceções de Tipagem
|
|
||||||
|
|
||||||
Devido à política **TypeScript sem any**, coerções agressivas requerem justificativa obrigatória em comentário.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Necessário cast duplo pois a biblioteca externa não provê tipagem genérica adequada na versão atual
|
|
||||||
const dados = payload.raw as unknown as RespostaFormatada
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5️⃣ TODOs Estruturados
|
|
||||||
|
|
||||||
Toda dívida técnica ou dúvida de negócio deixada em código deve seguir o formato `// TODO`:
|
|
||||||
|
|
||||||
- **Tipagem**: `// TODO de tipagem: Criar interface estrita para o retorno da API de listagem`
|
|
||||||
- **Negócio**: `// TODO de regra: Validar com Produto se a taxa adicional se aplica a clientes antigos`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6️⃣ Resumo das Regras
|
|
||||||
|
|
||||||
| Regra | Permitido | Proibido |
|
|
||||||
|---|---|---|
|
|
||||||
| Tamanho de arquivo | Até 250 linhas | Acima de 250 linhas |
|
|
||||||
| `defineComponent` | Obrigatório em todo `.vue` | Componentes sem `defineComponent` |
|
|
||||||
| `setup()` externo | — | Proibido em qualquer forma |
|
|
||||||
| CSS externo | `<nome>.css` vinculado ao `.vue` | CSS inline quando ultrapassa o limite |
|
|
||||||
| Dispatch Table | Em arquivo separado | — |
|
|
||||||
| JSDoc | Obrigatório em funções compartilhadas | Omitir em funções de uso amplo |
|
|
||||||
| Casts `as any` | Com `biome-ignore` justificado | Sem comentário explicativo |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7️⃣ Checklist de Validação
|
|
||||||
|
|
||||||
Antes de concluir qualquer refatoração ou adição de código:
|
|
||||||
|
|
||||||
- [ ] O arquivo resultante tem menos de 250 linhas?
|
|
||||||
- [ ] Funções compartilhadas têm `JSDoc` com `@param` e `@returns`?
|
|
||||||
- [ ] Casts temporários têm comentário justificando?
|
|
||||||
- [ ] TODOs estão no formato padronizado?
|
|
||||||
- [ ] A documentação explica o **porquê**, não apenas o **o quê**?
|
|
||||||
- [ ] `defineComponent` está presente em todo componente `.vue`?
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Referências
|
|
||||||
|
|
||||||
- Script: `scripts/check-vue-linhas.sh` (validação automática de tamanho)
|
|
||||||
- Rule: `.agent/rules/vue-limite-linhas.global.md` (política de limite de linhas)
|
|
||||||
- Rule: `.agent/rules/typescript-sem-any.global.md` (política de tipagem)
|
|
||||||
- Skill: `.agent/skills/documentar-decisao-tecnica/SKILL.md` (ADRs para decisões arquiteturais)
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: reels
|
||||||
description: Criar cadeia de roteiros de Reels para divulgação de funcionalidades e módulos
|
description: Criar cadeia de roteiros de Reels para divulgação de funcionalidades e módulos
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Criar Roteiros de Reels
|
# Workflow: Criar Roteiros de Reels
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
---
|
---
|
||||||
|
type: workflow
|
||||||
|
name: ux
|
||||||
description: Revisar e otimizar UX de componentes e telas Vue (Frontend)
|
description: Revisar e otimizar UX de componentes e telas Vue (Frontend)
|
||||||
|
scope: global
|
||||||
|
updatedAt: "2026-06-01"
|
||||||
---
|
---
|
||||||
|
|
||||||
# Workflow: Revisão de UX
|
# Workflow: Revisão de UX
|
||||||
|
|
@ -191,44 +195,8 @@ import { Filter, Plus, X, Trash2, Eye } from "@lucide/vue"
|
||||||
|
|
||||||
**Catálogo de referência**: https://lucide.dev/icons — buscar pelo nome do ícone em inglês.
|
**Catálogo de referência**: https://lucide.dev/icons — buscar pelo nome do ícone em inglês.
|
||||||
|
|
||||||
#### CSS do projeto
|
> Os tokens CSS estão documentados nas tabelas da seção **Paleta de Cores Institucional** acima.
|
||||||
|
> No código, usar `var(--token, #fallback)` — sempre com fallback hardcoded em componentes de biblioteca.
|
||||||
```css
|
|
||||||
/* Escala primária — Verde floresta */
|
|
||||||
--cor-eli-primaria-bg: #EEF3D0;
|
|
||||||
--cor-eli-primaria-zebra: #F6F9E8;
|
|
||||||
--cor-eli-primaria-suave: #BFC99C;
|
|
||||||
--cor-eli-primaria-clara: #D4E290;
|
|
||||||
--cor-eli-primaria-media: #ADCC44;
|
|
||||||
--cor-eli-primaria-acao: #8AAF00;
|
|
||||||
--cor-eli-primaria: #688C00;
|
|
||||||
--cor-eli-primaria-escura: #4A6500;
|
|
||||||
--cor-eli-primaria-texto: #2E3F00;
|
|
||||||
|
|
||||||
/* Escala de apoio — Âmbar terroso */
|
|
||||||
--cor-eli-alerta-bg: #FAF3DF;
|
|
||||||
--cor-eli-alerta-clara: #F5DC8A;
|
|
||||||
--cor-eli-alerta: #DDB847;
|
|
||||||
--cor-eli-alerta-forte: #8C6A00;
|
|
||||||
|
|
||||||
/* Escala neutra — Cinza musgo */
|
|
||||||
--cor-eli-fundo: #F2F3EE;
|
|
||||||
--cor-eli-borda: #D5D8CC;
|
|
||||||
--cor-eli-borda-forte: #B5BAA8;
|
|
||||||
--cor-eli-neutro: #5E6553;
|
|
||||||
--cor-eli-neutro-escuro: #3E4436;
|
|
||||||
--cor-eli-superficie: #FFFFFF;
|
|
||||||
|
|
||||||
/* Semânticas */
|
|
||||||
--cor-eli-sucesso: #2E7D32;
|
|
||||||
--cor-eli-sucesso-bg: #E8F5E9;
|
|
||||||
--cor-eli-erro: #C62828;
|
|
||||||
--cor-eli-erro-bg: #FFEBEE;
|
|
||||||
--cor-eli-info: #1565C0;
|
|
||||||
--cor-eli-info-bg: #E3F2FD;
|
|
||||||
```
|
|
||||||
|
|
||||||
> **⚠️ Regra crítica para componentes distribuídos como biblioteca**: todo token CSS novo (`--cor-eli-primaria-zebra`, `--cor-eli-primaria-suave`, etc.) deve ter **fallback hardcoded** no CSS do componente: `var(--token, #valorhex)`. Projetos destino podem não ter a versão mais recente do `design-tokens.css` e a variável resolverá como `undefined`, tornando a propriedade invisível.
|
|
||||||
|
|
||||||
- Classes devem seguir BEM: `eli-componente__elemento--modificador`
|
- Classes devem seguir BEM: `eli-componente__elemento--modificador`
|
||||||
- Evitar `!important` — resolver especificidade via seletor mais específico
|
- Evitar `!important` — resolver especificidade via seletor mais específico
|
||||||
|
|
|
||||||
6271
dist/eli-vue.es.js
vendored
6271
dist/eli-vue.es.js
vendored
File diff suppressed because one or more lines are too long
104
dist/eli-vue.umd.js
vendored
104
dist/eli-vue.umd.js
vendored
File diff suppressed because one or more lines are too long
1361
dist/types/componentes/EliEntrada/EliEntradaConfirmacao.vue.d.ts
vendored
Normal file
1361
dist/types/componentes/EliEntrada/EliEntradaConfirmacao.vue.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -187,14 +187,14 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
onInput?: ((_v: string | null) => any) | undefined;
|
onInput?: ((_v: string | null) => any) | undefined;
|
||||||
|
"onUpdate:modelValue"?: ((_v: string | null) => any) | undefined;
|
||||||
|
onBlur?: (() => any) | undefined;
|
||||||
"onUpdate:value"?: ((_v: string | null) => any) | undefined;
|
"onUpdate:value"?: ((_v: string | null) => any) | undefined;
|
||||||
onChange?: ((_v: string | null) => any) | undefined;
|
onChange?: ((_v: string | null) => any) | undefined;
|
||||||
"onUpdate:modelValue"?: ((_v: string | null) => any) | undefined;
|
onFocus?: (() => any) | undefined;
|
||||||
onAlterar?: ((_v: string | null) => any) | undefined;
|
onAlterar?: ((_v: string | null) => any) | undefined;
|
||||||
onFoco?: (() => any) | undefined;
|
onFoco?: (() => any) | undefined;
|
||||||
onDesfoco?: (() => any) | undefined;
|
onDesfoco?: (() => any) | undefined;
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
}>, {
|
||||||
modo: "data" | "dataHora" | undefined;
|
modo: "data" | "dataHora" | undefined;
|
||||||
limpavel: boolean;
|
limpavel: boolean;
|
||||||
|
|
@ -206,6 +206,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
max: string | undefined;
|
max: string | undefined;
|
||||||
densidade: CampoDensidade;
|
densidade: CampoDensidade;
|
||||||
variante: CampoVariante;
|
variante: CampoVariante;
|
||||||
|
desabilitado: boolean;
|
||||||
opcoes: {
|
opcoes: {
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
|
@ -225,5 +226,4 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
modelValue: string | null;
|
modelValue: string | null;
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
desabilitado: boolean;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>, {
|
}>, {
|
||||||
attrs: import("vue").Attrs;
|
attrs: import("vue").Attrs;
|
||||||
emit: ((event: "input", _v: number | null | undefined) => void) & ((event: "update:value", _v: number | null | undefined) => void) & ((event: "change", _v: number | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
emit: ((event: "input", _v: number | null | undefined) => void) & ((event: "blur") => void) & ((event: "update:value", _v: number | null | undefined) => void) & ((event: "change", _v: number | null | undefined) => void) & ((event: "focus") => void);
|
||||||
displayValue: import("vue").Ref<string, string>;
|
displayValue: import("vue").Ref<string, string>;
|
||||||
isInteiro: import("vue").ComputedRef<boolean>;
|
isInteiro: import("vue").ComputedRef<boolean>;
|
||||||
onUpdateModelValue: (texto: string) => void;
|
onUpdateModelValue: (texto: string) => void;
|
||||||
|
|
@ -39,10 +39,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
onInput?: ((_v: number | null | undefined) => any) | undefined;
|
onInput?: ((_v: number | null | undefined) => any) | undefined;
|
||||||
|
onBlur?: (() => any) | undefined;
|
||||||
"onUpdate:value"?: ((_v: number | null | undefined) => any) | undefined;
|
"onUpdate:value"?: ((_v: number | null | undefined) => any) | undefined;
|
||||||
onChange?: ((_v: number | null | undefined) => any) | undefined;
|
onChange?: ((_v: number | null | undefined) => any) | undefined;
|
||||||
onFocus?: (() => any) | undefined;
|
onFocus?: (() => any) | undefined;
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
}>, {
|
||||||
value: number | null | undefined;
|
value: number | null | undefined;
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>, {
|
}>, {
|
||||||
attrs: import("vue").Attrs;
|
attrs: import("vue").Attrs;
|
||||||
emit: ((event: "input", _v: string | null | undefined) => void) & ((event: "update:value", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
emit: ((event: "input", _v: string | null | undefined) => void) & ((event: "blur") => void) & ((event: "update:value", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void);
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||||
"update:value": (_v: EntradaParagrafo["value"]) => true;
|
"update:value": (_v: EntradaParagrafo["value"]) => true;
|
||||||
|
|
@ -33,10 +33,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
||||||
|
onBlur?: (() => any) | undefined;
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
||||||
onFocus?: (() => any) | undefined;
|
onFocus?: (() => any) | undefined;
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
}>, {
|
||||||
value: string | null | undefined;
|
value: string | null | undefined;
|
||||||
}, {}, {
|
}, {}, {
|
||||||
|
|
@ -1290,7 +1290,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
} & import("vue").ComponentCustomProperties & import("vuetify/lib/util/defineComponent.mjs").GenericProps<{
|
} & import("vue").ComponentCustomProperties & import("vuetify/lib/util/defineComponent.mjs").GenericProps<{
|
||||||
modelValue?: unknown;
|
modelValue?: unknown;
|
||||||
"onUpdate:modelValue"?: ((value: unknown) => void) | undefined;
|
"onUpdate:modelValue"?: ((value: unknown) => void) | undefined;
|
||||||
}, import("vuetify/lib/components/VInput/VInput.mjs").VInputSlots>, "name" | "color" | "disabled" | "error" | "label" | "style" | "class" | keyof import("vue").VNodeProps | "modelValue" | "onUpdate:modelValue" | "centerAffix" | "density" | "direction" | "errorMessages" | "focused" | "glow" | "hideSpinButtons" | "maxErrors" | "messages" | "persistentHint" | "readonly" | "rules" | "theme" | "onUpdate:focused" | "validateOn" | "validationValue" | "maxWidth" | "minWidth" | "width" | "id" | "appendIcon" | "baseColor" | "iconColor" | "prependIcon" | "hideDetails" | "hint" | "onClick:prepend" | "onClick:append" | "$children" | "v-slot:append" | "v-slot:default" | "v-slot:details" | "v-slot:message" | "v-slot:prepend" | "v-slots">, `$${any}`> & {
|
}, import("vuetify/lib/components/VInput/VInput.mjs").VInputSlots>, "name" | "color" | "disabled" | "error" | "label" | "style" | "class" | keyof import("vue").VNodeProps | "centerAffix" | "density" | "direction" | "errorMessages" | "focused" | "glow" | "hideSpinButtons" | "maxErrors" | "messages" | "persistentHint" | "readonly" | "rules" | "theme" | "onUpdate:focused" | "validateOn" | "validationValue" | "maxWidth" | "minWidth" | "width" | "id" | "appendIcon" | "baseColor" | "iconColor" | "prependIcon" | "hideDetails" | "hint" | "onClick:prepend" | "onClick:append" | "$children" | "modelValue" | "onUpdate:modelValue" | "v-slot:append" | "v-slot:default" | "v-slot:details" | "v-slot:message" | "v-slot:prepend" | "v-slots">, `$${any}`> & {
|
||||||
_allExposed: {
|
_allExposed: {
|
||||||
reset: () => Promise<void>;
|
reset: () => Promise<void>;
|
||||||
resetValidation: () => Promise<void>;
|
resetValidation: () => Promise<void>;
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
10024
dist/types/componentes/EliEntrada/EliEntradaSelecaoMultipla.vue.d.ts
vendored
Normal file
10024
dist/types/componentes/EliEntrada/EliEntradaSelecaoMultipla.vue.d.ts
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -15,7 +15,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>, {
|
}>, {
|
||||||
attrs: import("vue").Attrs;
|
attrs: import("vue").Attrs;
|
||||||
emit: ((event: "input", _v: string | null | undefined) => void) & ((event: "update:value", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
emit: ((event: "input", _v: string | null | undefined) => void) & ((event: "blur") => void) & ((event: "update:value", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void);
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
inputMode: import("vue").ComputedRef<string | undefined>;
|
||||||
|
|
@ -39,10 +39,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
||||||
|
onBlur?: (() => any) | undefined;
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
||||||
onFocus?: (() => any) | undefined;
|
onFocus?: (() => any) | undefined;
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
}>, {
|
||||||
value: string | null | undefined;
|
value: string | null | undefined;
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
|
|
|
||||||
4
dist/types/componentes/EliEntrada/index.d.ts
vendored
4
dist/types/componentes/EliEntrada/index.d.ts
vendored
|
|
@ -1,7 +1,9 @@
|
||||||
|
import EliEntradaConfirmacao from "./EliEntradaConfirmacao.vue";
|
||||||
import EliEntradaDataHora from "./EliEntradaDataHora.vue";
|
import EliEntradaDataHora from "./EliEntradaDataHora.vue";
|
||||||
import EliEntradaNumero from "./EliEntradaNumero.vue";
|
import EliEntradaNumero from "./EliEntradaNumero.vue";
|
||||||
import EliEntradaParagrafo from "./EliEntradaParagrafo.vue";
|
import EliEntradaParagrafo from "./EliEntradaParagrafo.vue";
|
||||||
import EliEntradaSelecao from "./EliEntradaSelecao.vue";
|
import EliEntradaSelecao from "./EliEntradaSelecao.vue";
|
||||||
|
import EliEntradaSelecaoMultipla from "./EliEntradaSelecaoMultipla.vue";
|
||||||
import EliEntradaTexto from "./EliEntradaTexto.vue";
|
import EliEntradaTexto from "./EliEntradaTexto.vue";
|
||||||
export type { PadroesEntradas, TipoEntrada } from "./tiposEntradas";
|
export type { PadroesEntradas, TipoEntrada } from "./tiposEntradas";
|
||||||
export { EliEntradaDataHora, EliEntradaNumero, EliEntradaParagrafo, EliEntradaSelecao, EliEntradaTexto, };
|
export { EliEntradaConfirmacao, EliEntradaDataHora, EliEntradaNumero, EliEntradaParagrafo, EliEntradaSelecao, EliEntradaSelecaoMultipla, EliEntradaTexto, };
|
||||||
|
|
|
||||||
12030
dist/types/componentes/EliEntrada/registryEliEntradas.d.ts
vendored
12030
dist/types/componentes/EliEntrada/registryEliEntradas.d.ts
vendored
File diff suppressed because one or more lines are too long
|
|
@ -131,6 +131,45 @@ export type PadroesEntradas = {
|
||||||
/** Variante do v-text-field (Vuetify). */
|
/** Variante do v-text-field (Vuetify). */
|
||||||
variante?: import("../../tipos").CampoVariante;
|
variante?: import("../../tipos").CampoVariante;
|
||||||
}>;
|
}>;
|
||||||
|
selecaoMultipla: tipoPadraoEntrada<string[] | null | undefined, {
|
||||||
|
/**
|
||||||
|
* Carrega os itens da seleção (sincrono ou async).
|
||||||
|
* - Cada item precisa ter uma chave estável (value) e um rótulo (title).
|
||||||
|
*/
|
||||||
|
itens: () => {
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[] | Promise<{
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[]>;
|
||||||
|
/** Se true, mostra ícone para limpar o valor (Vuetify clearable). */
|
||||||
|
limpavel?: boolean;
|
||||||
|
/** Estado de erro (visual). */
|
||||||
|
erro?: boolean;
|
||||||
|
/** Mensagens de erro. */
|
||||||
|
mensagensErro?: string | string[];
|
||||||
|
/** Texto de apoio. */
|
||||||
|
dica?: string;
|
||||||
|
/** Mantém a dica sempre visível. */
|
||||||
|
dicaPersistente?: boolean;
|
||||||
|
/** Densidade do campo (Vuetify). */
|
||||||
|
densidade?: import("../../tipos").CampoDensidade;
|
||||||
|
/** Variante do v-text-field (Vuetify). */
|
||||||
|
variante?: import("../../tipos").CampoVariante;
|
||||||
|
}>;
|
||||||
|
confirmacao: tipoPadraoEntrada<boolean, {
|
||||||
|
/** Cor do switch quando ativo (Vuetify color). */
|
||||||
|
cor?: string;
|
||||||
|
/** Se true, desabilita a interação. */
|
||||||
|
desabilitado?: boolean;
|
||||||
|
/** Texto exibido ao lado do switch quando ativo. */
|
||||||
|
rotuloAtivo?: string;
|
||||||
|
/** Texto exibido ao lado do switch quando inativo. */
|
||||||
|
rotuloInativo?: string;
|
||||||
|
/** Densidade do campo (Vuetify). */
|
||||||
|
densidade?: import("../../tipos").CampoDensidade;
|
||||||
|
}>;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* União dos tipos de entrada suportados.
|
* União dos tipos de entrada suportados.
|
||||||
|
|
|
||||||
423
dist/types/componentes/EliTabela/EliTabela.vue.d.ts
vendored
423
dist/types/componentes/EliTabela/EliTabela.vue.d.ts
vendored
|
|
@ -96,6 +96,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
modalFiltroAberto: import("vue").Ref<boolean, boolean>;
|
modalFiltroAberto: import("vue").Ref<boolean, boolean>;
|
||||||
exibirFiltroAvancado: import("vue").ComputedRef<boolean>;
|
exibirFiltroAvancado: import("vue").ComputedRef<boolean>;
|
||||||
filtrosAvancadosAtivos: import("vue").ComputedRef<import("p-comuns").tipoFiltroDeltaColunaTipada<any>[]>;
|
filtrosAvancadosAtivos: import("vue").ComputedRef<import("p-comuns").tipoFiltroDeltaColunaTipada<any>[]>;
|
||||||
|
filtrosAtivosResumo: import("vue").ComputedRef<{
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: string[];
|
||||||
|
}>;
|
||||||
abrirModalFiltro: () => void;
|
abrirModalFiltro: () => void;
|
||||||
fecharModalFiltro: () => void;
|
fecharModalFiltro: () => void;
|
||||||
limparFiltrosAvancados: () => void;
|
limparFiltrosAvancados: () => void;
|
||||||
|
|
@ -191,6 +195,17 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
required: false;
|
required: false;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
};
|
};
|
||||||
|
filtrosAtivosResumo: {
|
||||||
|
type: PropType<{
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: string[];
|
||||||
|
}>;
|
||||||
|
required: false;
|
||||||
|
default: () => {
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: never[];
|
||||||
|
};
|
||||||
|
};
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: StringConstructor;
|
type: StringConstructor;
|
||||||
required: true;
|
required: true;
|
||||||
|
|
@ -210,6 +225,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>, {
|
}>, {
|
||||||
temAcoesCabecalho: import("vue").ComputedRef<boolean>;
|
temAcoesCabecalho: import("vue").ComputedRef<boolean>;
|
||||||
|
tooltipFiltro: import("vue").ComputedRef<string>;
|
||||||
emitBuscar: (texto: string) => void;
|
emitBuscar: (texto: string) => void;
|
||||||
emitColunas: () => void;
|
emitColunas: () => void;
|
||||||
emitFiltroAvancado: () => void;
|
emitFiltroAvancado: () => void;
|
||||||
|
|
@ -232,6 +248,17 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
required: false;
|
required: false;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
};
|
};
|
||||||
|
filtrosAtivosResumo: {
|
||||||
|
type: PropType<{
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: string[];
|
||||||
|
}>;
|
||||||
|
required: false;
|
||||||
|
default: () => {
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: never[];
|
||||||
|
};
|
||||||
|
};
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: StringConstructor;
|
type: StringConstructor;
|
||||||
required: true;
|
required: true;
|
||||||
|
|
@ -256,6 +283,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
}>, {
|
}>, {
|
||||||
exibirBotaoColunas: boolean;
|
exibirBotaoColunas: boolean;
|
||||||
exibirBotaoFiltroAvancado: boolean;
|
exibirBotaoFiltroAvancado: boolean;
|
||||||
|
filtrosAtivosResumo: {
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: string[];
|
||||||
|
};
|
||||||
}, {}, {
|
}, {}, {
|
||||||
Columns3: import("@lucide/vue").LucideIcon;
|
Columns3: import("@lucide/vue").LucideIcon;
|
||||||
EliTabelaCaixaDeBusca: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
EliTabelaCaixaDeBusca: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
|
|
@ -995,6 +1026,31 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dicaPersistente?: boolean | undefined;
|
dicaPersistente?: boolean | undefined;
|
||||||
densidade?: import("../..").CampoDensidade | undefined;
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
variante?: import("../..").CampoVariante | undefined;
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["selecaoMultipla", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
itens: () => {
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[] | Promise<{
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[]>;
|
||||||
|
limpavel?: boolean | undefined;
|
||||||
|
erro?: boolean | undefined;
|
||||||
|
mensagensErro?: string | string[] | undefined;
|
||||||
|
dica?: string | undefined;
|
||||||
|
dicaPersistente?: boolean | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["confirmacao", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
cor?: string | undefined;
|
||||||
|
desabilitado?: boolean | undefined;
|
||||||
|
rotuloAtivo?: string | undefined;
|
||||||
|
rotuloInativo?: string | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
}];
|
}];
|
||||||
valor: unknown;
|
valor: unknown;
|
||||||
}[], import("./useFiltroAvancado").LinhaFiltro[] | {
|
}[], import("./useFiltroAvancado").LinhaFiltro[] | {
|
||||||
|
|
@ -1052,357 +1108,44 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dicaPersistente?: boolean | undefined;
|
dicaPersistente?: boolean | undefined;
|
||||||
densidade?: import("../..").CampoDensidade | undefined;
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
variante?: import("../..").CampoVariante | undefined;
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["selecaoMultipla", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
itens: () => {
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[] | Promise<{
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[]>;
|
||||||
|
limpavel?: boolean | undefined;
|
||||||
|
erro?: boolean | undefined;
|
||||||
|
mensagensErro?: string | string[] | undefined;
|
||||||
|
dica?: string | undefined;
|
||||||
|
dicaPersistente?: boolean | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["confirmacao", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
cor?: string | undefined;
|
||||||
|
desabilitado?: boolean | undefined;
|
||||||
|
rotuloAtivo?: string | undefined;
|
||||||
|
rotuloInativo?: string | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
}];
|
}];
|
||||||
valor: unknown;
|
valor: unknown;
|
||||||
}[]>;
|
}[]>;
|
||||||
opcoesParaAdicionar: import("vue").ComputedRef<{
|
opcoesParaAdicionar: import("vue").ComputedRef<{
|
||||||
chave: string;
|
chave: string;
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
filtro: (valor: unknown) => import("p-comuns").tipoFiltroDeltaColunaTipada<"small" | "length" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "toString" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "codePointAt" | "endsWith" | "normalize" | "repeat" | "startsWith" | "anchor" | "big" | "blink" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "link" | "strike" | "sub" | "sup" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "valueOf"> | undefined;
|
filtro: (valor: unknown) => Pick<import("p-comuns").tipoCondicaoFiltroDeltaTipado<"small" | "length" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "toString" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "codePointAt" | "endsWith" | "normalize" | "repeat" | "startsWith" | "anchor" | "big" | "blink" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "link" | "strike" | "sub" | "sup" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "valueOf">, "valor" | "coluna" | "operador"> | undefined;
|
||||||
entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada;
|
entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada;
|
||||||
}[]>;
|
}[]>;
|
||||||
chaveParaAdicionar: import("vue").Ref<string, string>;
|
chaveParaAdicionar: import("vue").Ref<string, string>;
|
||||||
formulaCustomizada: import("vue").Ref<string, string>;
|
formulaCustomizada: import("vue").Ref<string, string>;
|
||||||
formulaGerada: import("vue").ComputedRef<string>;
|
formulaGerada: import("vue").ComputedRef<string>;
|
||||||
componenteEntrada: (entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
componenteEntrada: (entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada) => import("vue").Component;
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<import("../..").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<import("../..").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: import("vue").Attrs;
|
|
||||||
valor: import("vue").WritableComputedRef<string, string>;
|
|
||||||
tipoInput: import("vue").ComputedRef<"date" | "datetime-local">;
|
|
||||||
minLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
maxLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
opcoesEfetivas: import("vue").ComputedRef<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
}>;
|
|
||||||
desabilitadoEfetivo: import("vue").ComputedRef<boolean>;
|
|
||||||
emitCompatFocus: () => void;
|
|
||||||
emitCompatBlur: () => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null) => true;
|
|
||||||
input: (_v: string | null) => true;
|
|
||||||
change: (_v: string | null) => true;
|
|
||||||
"update:modelValue": (_v: string | null) => true;
|
|
||||||
alterar: (_v: string | null) => true;
|
|
||||||
foco: () => true;
|
|
||||||
desfoco: () => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<import("../..").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<import("../..").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onInput?: ((_v: string | null) => any) | undefined;
|
|
||||||
"onUpdate:value"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null) => any) | undefined;
|
|
||||||
"onUpdate:modelValue"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onAlterar?: ((_v: string | null) => any) | undefined;
|
|
||||||
onFoco?: (() => any) | undefined;
|
|
||||||
onDesfoco?: (() => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
modo: "data" | "dataHora" | undefined;
|
|
||||||
limpavel: boolean;
|
|
||||||
erro: boolean;
|
|
||||||
mensagensErro: string | string[];
|
|
||||||
dica: string;
|
|
||||||
dicaPersistente: boolean;
|
|
||||||
min: string | undefined;
|
|
||||||
max: string | undefined;
|
|
||||||
densidade: import("../..").CampoDensidade;
|
|
||||||
variante: import("../..").CampoVariante;
|
|
||||||
opcoes: {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
};
|
|
||||||
value: string | null | undefined;
|
|
||||||
modelValue: string | null;
|
|
||||||
rotulo: string;
|
|
||||||
placeholder: string;
|
|
||||||
desabilitado: boolean;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: import("vue").Attrs;
|
|
||||||
emit: ((event: "input", _v: number | null | undefined) => void) & ((event: "update:value", _v: number | null | undefined) => void) & ((event: "change", _v: number | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
displayValue: import("vue").Ref<string, string>;
|
|
||||||
isInteiro: import("vue").ComputedRef<boolean>;
|
|
||||||
onUpdateModelValue: (texto: string) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: number | null | undefined) => true;
|
|
||||||
input: (_v: number | null | undefined) => true;
|
|
||||||
change: (_v: number | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onInput?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
"onUpdate:value"?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: number | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: import("vue").Attrs;
|
|
||||||
emit: ((event: "input", _v: string | null | undefined) => void) & ((event: "update:value", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
|
||||||
onInput: (e: Event) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null | undefined) => true;
|
|
||||||
input: (_v: string | null | undefined) => true;
|
|
||||||
change: (_v: string | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: string | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
opcoesEntrada: (entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada) => {
|
opcoesEntrada: (entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada) => {
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,17 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
required: false;
|
required: false;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
};
|
};
|
||||||
|
filtrosAtivosResumo: {
|
||||||
|
type: PropType<{
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: string[];
|
||||||
|
}>;
|
||||||
|
required: false;
|
||||||
|
default: () => {
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: never[];
|
||||||
|
};
|
||||||
|
};
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: StringConstructor;
|
type: StringConstructor;
|
||||||
required: true;
|
required: true;
|
||||||
|
|
@ -35,6 +46,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>, {
|
}>, {
|
||||||
temAcoesCabecalho: import("vue").ComputedRef<boolean>;
|
temAcoesCabecalho: import("vue").ComputedRef<boolean>;
|
||||||
|
tooltipFiltro: import("vue").ComputedRef<string>;
|
||||||
emitBuscar: (texto: string) => void;
|
emitBuscar: (texto: string) => void;
|
||||||
emitColunas: () => void;
|
emitColunas: () => void;
|
||||||
emitFiltroAvancado: () => void;
|
emitFiltroAvancado: () => void;
|
||||||
|
|
@ -57,6 +69,17 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
required: false;
|
required: false;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
};
|
};
|
||||||
|
filtrosAtivosResumo: {
|
||||||
|
type: PropType<{
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: string[];
|
||||||
|
}>;
|
||||||
|
required: false;
|
||||||
|
default: () => {
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: never[];
|
||||||
|
};
|
||||||
|
};
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: StringConstructor;
|
type: StringConstructor;
|
||||||
required: true;
|
required: true;
|
||||||
|
|
@ -81,6 +104,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
}>, {
|
}>, {
|
||||||
exibirBotaoColunas: boolean;
|
exibirBotaoColunas: boolean;
|
||||||
exibirBotaoFiltroAvancado: boolean;
|
exibirBotaoFiltroAvancado: boolean;
|
||||||
|
filtrosAtivosResumo: {
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: string[];
|
||||||
|
};
|
||||||
}, {}, {
|
}, {}, {
|
||||||
Columns3: import("@lucide/vue").LucideIcon;
|
Columns3: import("@lucide/vue").LucideIcon;
|
||||||
EliTabelaCaixaDeBusca: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
EliTabelaCaixaDeBusca: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,31 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dicaPersistente?: boolean | undefined;
|
dicaPersistente?: boolean | undefined;
|
||||||
densidade?: import("../..").CampoDensidade | undefined;
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
variante?: import("../..").CampoVariante | undefined;
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["selecaoMultipla", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
itens: () => {
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[] | Promise<{
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[]>;
|
||||||
|
limpavel?: boolean | undefined;
|
||||||
|
erro?: boolean | undefined;
|
||||||
|
mensagensErro?: string | string[] | undefined;
|
||||||
|
dica?: string | undefined;
|
||||||
|
dicaPersistente?: boolean | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["confirmacao", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
cor?: string | undefined;
|
||||||
|
desabilitado?: boolean | undefined;
|
||||||
|
rotuloAtivo?: string | undefined;
|
||||||
|
rotuloInativo?: string | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
}];
|
}];
|
||||||
valor: unknown;
|
valor: unknown;
|
||||||
}[], import("./useFiltroAvancado").LinhaFiltro[] | {
|
}[], import("./useFiltroAvancado").LinhaFiltro[] | {
|
||||||
|
|
@ -138,357 +163,44 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dicaPersistente?: boolean | undefined;
|
dicaPersistente?: boolean | undefined;
|
||||||
densidade?: import("../..").CampoDensidade | undefined;
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
variante?: import("../..").CampoVariante | undefined;
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["selecaoMultipla", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
itens: () => {
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[] | Promise<{
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[]>;
|
||||||
|
limpavel?: boolean | undefined;
|
||||||
|
erro?: boolean | undefined;
|
||||||
|
mensagensErro?: string | string[] | undefined;
|
||||||
|
dica?: string | undefined;
|
||||||
|
dicaPersistente?: boolean | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["confirmacao", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
cor?: string | undefined;
|
||||||
|
desabilitado?: boolean | undefined;
|
||||||
|
rotuloAtivo?: string | undefined;
|
||||||
|
rotuloInativo?: string | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
}];
|
}];
|
||||||
valor: unknown;
|
valor: unknown;
|
||||||
}[]>;
|
}[]>;
|
||||||
opcoesParaAdicionar: import("vue").ComputedRef<{
|
opcoesParaAdicionar: import("vue").ComputedRef<{
|
||||||
chave: string;
|
chave: string;
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
filtro: (valor: unknown) => import("p-comuns").tipoFiltroDeltaColunaTipada<"small" | "length" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "toString" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "codePointAt" | "endsWith" | "normalize" | "repeat" | "startsWith" | "anchor" | "big" | "blink" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "link" | "strike" | "sub" | "sup" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "valueOf"> | undefined;
|
filtro: (valor: unknown) => Pick<import("p-comuns").tipoCondicaoFiltroDeltaTipado<"small" | "length" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "toString" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "codePointAt" | "endsWith" | "normalize" | "repeat" | "startsWith" | "anchor" | "big" | "blink" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "link" | "strike" | "sub" | "sup" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "valueOf">, "valor" | "coluna" | "operador"> | undefined;
|
||||||
entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada;
|
entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada;
|
||||||
}[]>;
|
}[]>;
|
||||||
chaveParaAdicionar: import("vue").Ref<string, string>;
|
chaveParaAdicionar: import("vue").Ref<string, string>;
|
||||||
formulaCustomizada: import("vue").Ref<string, string>;
|
formulaCustomizada: import("vue").Ref<string, string>;
|
||||||
formulaGerada: import("vue").ComputedRef<string>;
|
formulaGerada: import("vue").ComputedRef<string>;
|
||||||
componenteEntrada: (entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
componenteEntrada: (entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada) => import("vue").Component;
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<import("../..").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<import("../..").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: import("vue").Attrs;
|
|
||||||
valor: import("vue").WritableComputedRef<string, string>;
|
|
||||||
tipoInput: import("vue").ComputedRef<"date" | "datetime-local">;
|
|
||||||
minLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
maxLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
opcoesEfetivas: import("vue").ComputedRef<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
}>;
|
|
||||||
desabilitadoEfetivo: import("vue").ComputedRef<boolean>;
|
|
||||||
emitCompatFocus: () => void;
|
|
||||||
emitCompatBlur: () => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null) => true;
|
|
||||||
input: (_v: string | null) => true;
|
|
||||||
change: (_v: string | null) => true;
|
|
||||||
"update:modelValue": (_v: string | null) => true;
|
|
||||||
alterar: (_v: string | null) => true;
|
|
||||||
foco: () => true;
|
|
||||||
desfoco: () => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<import("../..").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<import("../..").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onInput?: ((_v: string | null) => any) | undefined;
|
|
||||||
"onUpdate:value"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null) => any) | undefined;
|
|
||||||
"onUpdate:modelValue"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onAlterar?: ((_v: string | null) => any) | undefined;
|
|
||||||
onFoco?: (() => any) | undefined;
|
|
||||||
onDesfoco?: (() => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
modo: "data" | "dataHora" | undefined;
|
|
||||||
limpavel: boolean;
|
|
||||||
erro: boolean;
|
|
||||||
mensagensErro: string | string[];
|
|
||||||
dica: string;
|
|
||||||
dicaPersistente: boolean;
|
|
||||||
min: string | undefined;
|
|
||||||
max: string | undefined;
|
|
||||||
densidade: import("../..").CampoDensidade;
|
|
||||||
variante: import("../..").CampoVariante;
|
|
||||||
opcoes: {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
};
|
|
||||||
value: string | null | undefined;
|
|
||||||
modelValue: string | null;
|
|
||||||
rotulo: string;
|
|
||||||
placeholder: string;
|
|
||||||
desabilitado: boolean;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: import("vue").Attrs;
|
|
||||||
emit: ((event: "input", _v: number | null | undefined) => void) & ((event: "update:value", _v: number | null | undefined) => void) & ((event: "change", _v: number | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
displayValue: import("vue").Ref<string, string>;
|
|
||||||
isInteiro: import("vue").ComputedRef<boolean>;
|
|
||||||
onUpdateModelValue: (texto: string) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: number | null | undefined) => true;
|
|
||||||
input: (_v: number | null | undefined) => true;
|
|
||||||
change: (_v: number | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onInput?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
"onUpdate:value"?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: number | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: import("vue").Attrs;
|
|
||||||
emit: ((event: "input", _v: string | null | undefined) => void) & ((event: "update:value", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
|
||||||
onInput: (e: Event) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null | undefined) => true;
|
|
||||||
input: (_v: string | null | undefined) => true;
|
|
||||||
change: (_v: string | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: string | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
opcoesEntrada: (entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada) => {
|
opcoesEntrada: (entrada: import("../EliEntrada/tiposEntradas").ComponenteEntrada) => {
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { LucideIcon } from "@lucide/vue";
|
import type { LucideIcon } from "@lucide/vue";
|
||||||
import type { tipoFiltroDeltaColunaTipada } from "p-comuns";
|
import type { tipoCondicaoFiltroDeltaTipado, tipoFiltroDeltaColunaTipada } from "p-comuns";
|
||||||
import type { tipoResposta } from "p-respostas";
|
import type { tipoResposta } from "p-respostas";
|
||||||
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
||||||
import type { tiposTabelaCelulas, tipoTabelaCelula } from "./celulas/tiposTabelaCelulas";
|
import type { tiposTabelaCelulas, tipoTabelaCelula } from "./celulas/tiposTabelaCelulas";
|
||||||
|
|
@ -136,8 +136,8 @@ export type tipoEliTabelaConsulta<T> = {
|
||||||
chave: string;
|
chave: string;
|
||||||
/** Rótulo exibido no select de adicionar filtro */
|
/** Rótulo exibido no select de adicionar filtro */
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
/** vai gerar filtro e mescla com os filtros já existentes */
|
/** vai gerar filtro e mescla com os filtros já existentes , id é gerado de forma altomatica para esse local*/
|
||||||
filtro: (valor: unknown) => tipoFiltroDeltaColunaTipada<Extract<keyof T, string>> | undefined;
|
filtro: (valor: unknown) => Pick<tipoCondicaoFiltroDeltaTipado<Extract<keyof T, string>>, "coluna" | "operador" | "valor"> | undefined;
|
||||||
/** componente de entrada que vai receber o valor para o filtro */
|
/** componente de entrada que vai receber o valor para o filtro */
|
||||||
entrada: ComponenteEntrada;
|
entrada: ComponenteEntrada;
|
||||||
}[];
|
}[];
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,10 @@ export declare function useEliTabela(props: {
|
||||||
modalFiltroAberto: import("vue").Ref<boolean, boolean>;
|
modalFiltroAberto: import("vue").Ref<boolean, boolean>;
|
||||||
exibirFiltroAvancado: import("vue").ComputedRef<boolean>;
|
exibirFiltroAvancado: import("vue").ComputedRef<boolean>;
|
||||||
filtrosAvancadosAtivos: import("vue").ComputedRef<import("p-comuns").tipoFiltroDeltaColunaTipada<any>[]>;
|
filtrosAvancadosAtivos: import("vue").ComputedRef<import("p-comuns").tipoFiltroDeltaColunaTipada<any>[]>;
|
||||||
|
filtrosAtivosResumo: import("vue").ComputedRef<{
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: string[];
|
||||||
|
}>;
|
||||||
abrirModalFiltro: () => void;
|
abrirModalFiltro: () => void;
|
||||||
fecharModalFiltro: () => void;
|
fecharModalFiltro: () => void;
|
||||||
limparFiltrosAvancados: () => void;
|
limparFiltrosAvancados: () => void;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,10 @@ export declare function useEliTabelaFiltrosAvancados(props: PropsFiltros, pagina
|
||||||
modalFiltroAberto: Ref<boolean, boolean>;
|
modalFiltroAberto: Ref<boolean, boolean>;
|
||||||
exibirFiltroAvancado: import("vue").ComputedRef<boolean>;
|
exibirFiltroAvancado: import("vue").ComputedRef<boolean>;
|
||||||
filtrosAvancadosAtivos: import("vue").ComputedRef<tipoFiltroDeltaColunaTipada<any>[]>;
|
filtrosAvancadosAtivos: import("vue").ComputedRef<tipoFiltroDeltaColunaTipada<any>[]>;
|
||||||
|
filtrosAtivosResumo: import("vue").ComputedRef<{
|
||||||
|
quantidade: number;
|
||||||
|
rotulos: string[];
|
||||||
|
}>;
|
||||||
abrirModalFiltro: () => void;
|
abrirModalFiltro: () => void;
|
||||||
fecharModalFiltro: () => void;
|
fecharModalFiltro: () => void;
|
||||||
limparFiltrosAvancados: () => void;
|
limparFiltrosAvancados: () => void;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
* Extraído de `EliTabelaModalFiltroAvancado.vue` para manter o componente abaixo de 250 linhas.
|
* Extraído de `EliTabelaModalFiltroAvancado.vue` para manter o componente abaixo de 250 linhas.
|
||||||
*/
|
*/
|
||||||
import { type Ref } from "vue";
|
import { type Component, type Ref } from "vue";
|
||||||
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
||||||
import type { tipoEliTabelaConsulta } from "./types-eli-tabela";
|
import type { tipoEliTabelaConsulta } from "./types-eli-tabela";
|
||||||
export type FiltroBase<T> = NonNullable<tipoEliTabelaConsulta<T>["filtroAvancado"]>[number];
|
export type FiltroBase<T> = NonNullable<tipoEliTabelaConsulta<T>["filtroAvancado"]>[number];
|
||||||
|
|
@ -112,6 +112,31 @@ export declare function useFiltroAvancado({ aberto, filtrosBase, modelo, modeloF
|
||||||
dicaPersistente?: boolean | undefined;
|
dicaPersistente?: boolean | undefined;
|
||||||
densidade?: import("../..").CampoDensidade | undefined;
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
variante?: import("../..").CampoVariante | undefined;
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["selecaoMultipla", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
itens: () => {
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[] | Promise<{
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[]>;
|
||||||
|
limpavel?: boolean | undefined;
|
||||||
|
erro?: boolean | undefined;
|
||||||
|
mensagensErro?: string | string[] | undefined;
|
||||||
|
dica?: string | undefined;
|
||||||
|
dicaPersistente?: boolean | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["confirmacao", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
cor?: string | undefined;
|
||||||
|
desabilitado?: boolean | undefined;
|
||||||
|
rotuloAtivo?: string | undefined;
|
||||||
|
rotuloInativo?: string | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
}];
|
}];
|
||||||
valor: unknown;
|
valor: unknown;
|
||||||
}[], LinhaFiltro[] | {
|
}[], LinhaFiltro[] | {
|
||||||
|
|
@ -169,357 +194,44 @@ export declare function useFiltroAvancado({ aberto, filtrosBase, modelo, modeloF
|
||||||
dicaPersistente?: boolean | undefined;
|
dicaPersistente?: boolean | undefined;
|
||||||
densidade?: import("../..").CampoDensidade | undefined;
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
variante?: import("../..").CampoVariante | undefined;
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["selecaoMultipla", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
itens: () => {
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[] | Promise<{
|
||||||
|
chave: string;
|
||||||
|
rotulo: string;
|
||||||
|
}[]>;
|
||||||
|
limpavel?: boolean | undefined;
|
||||||
|
erro?: boolean | undefined;
|
||||||
|
mensagensErro?: string | string[] | undefined;
|
||||||
|
dica?: string | undefined;
|
||||||
|
dicaPersistente?: boolean | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
|
variante?: import("../..").CampoVariante | undefined;
|
||||||
|
}] | readonly ["confirmacao", {
|
||||||
|
rotulo: string;
|
||||||
|
placeholder?: string | undefined;
|
||||||
|
cor?: string | undefined;
|
||||||
|
desabilitado?: boolean | undefined;
|
||||||
|
rotuloAtivo?: string | undefined;
|
||||||
|
rotuloInativo?: string | undefined;
|
||||||
|
densidade?: import("../..").CampoDensidade | undefined;
|
||||||
}];
|
}];
|
||||||
valor: unknown;
|
valor: unknown;
|
||||||
}[]>;
|
}[]>;
|
||||||
opcoesParaAdicionar: import("vue").ComputedRef<{
|
opcoesParaAdicionar: import("vue").ComputedRef<{
|
||||||
chave: string;
|
chave: string;
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
filtro: (valor: unknown) => import("p-comuns").tipoFiltroDeltaColunaTipada<"small" | "length" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "toString" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "codePointAt" | "endsWith" | "normalize" | "repeat" | "startsWith" | "anchor" | "big" | "blink" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "link" | "strike" | "sub" | "sup" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "valueOf"> | undefined;
|
filtro: (valor: unknown) => Pick<import("p-comuns").tipoCondicaoFiltroDeltaTipado<"small" | "length" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "toString" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "codePointAt" | "endsWith" | "normalize" | "repeat" | "startsWith" | "anchor" | "big" | "blink" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "link" | "strike" | "sub" | "sup" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "valueOf">, "valor" | "coluna" | "operador"> | undefined;
|
||||||
entrada: ComponenteEntrada;
|
entrada: ComponenteEntrada;
|
||||||
}[]>;
|
}[]>;
|
||||||
chaveParaAdicionar: Ref<string, string>;
|
chaveParaAdicionar: Ref<string, string>;
|
||||||
formulaCustomizada: Ref<string, string>;
|
formulaCustomizada: Ref<string, string>;
|
||||||
formulaGerada: import("vue").ComputedRef<string>;
|
formulaGerada: import("vue").ComputedRef<string>;
|
||||||
componenteEntrada: (entrada: ComponenteEntrada) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
componenteEntrada: (entrada: ComponenteEntrada) => Component;
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: import("vue").PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: import("vue").PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: import("vue").PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: import("vue").PropType<import("../..").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: import("vue").PropType<import("../..").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: import("vue").PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: import("vue").PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: import("vue").Attrs;
|
|
||||||
valor: import("vue").WritableComputedRef<string, string>;
|
|
||||||
tipoInput: import("vue").ComputedRef<"date" | "datetime-local">;
|
|
||||||
minLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
maxLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
opcoesEfetivas: import("vue").ComputedRef<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
}>;
|
|
||||||
desabilitadoEfetivo: import("vue").ComputedRef<boolean>;
|
|
||||||
emitCompatFocus: () => void;
|
|
||||||
emitCompatBlur: () => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null) => true;
|
|
||||||
input: (_v: string | null) => true;
|
|
||||||
change: (_v: string | null) => true;
|
|
||||||
"update:modelValue": (_v: string | null) => true;
|
|
||||||
alterar: (_v: string | null) => true;
|
|
||||||
foco: () => true;
|
|
||||||
desfoco: () => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: import("vue").PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: import("vue").PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: import("vue").PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: import("vue").PropType<import("../..").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: import("vue").PropType<import("../..").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: import("vue").PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: import("vue").PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onInput?: ((_v: string | null) => any) | undefined;
|
|
||||||
"onUpdate:value"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null) => any) | undefined;
|
|
||||||
"onUpdate:modelValue"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onAlterar?: ((_v: string | null) => any) | undefined;
|
|
||||||
onFoco?: (() => any) | undefined;
|
|
||||||
onDesfoco?: (() => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
modo: "data" | "dataHora" | undefined;
|
|
||||||
limpavel: boolean;
|
|
||||||
erro: boolean;
|
|
||||||
mensagensErro: string | string[];
|
|
||||||
dica: string;
|
|
||||||
dicaPersistente: boolean;
|
|
||||||
min: string | undefined;
|
|
||||||
max: string | undefined;
|
|
||||||
densidade: import("../..").CampoDensidade;
|
|
||||||
variante: import("../..").CampoVariante;
|
|
||||||
opcoes: {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../..").CampoDensidade;
|
|
||||||
variante?: import("../..").CampoVariante;
|
|
||||||
};
|
|
||||||
value: string | null | undefined;
|
|
||||||
modelValue: string | null;
|
|
||||||
rotulo: string;
|
|
||||||
placeholder: string;
|
|
||||||
desabilitado: boolean;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: import("vue").Attrs;
|
|
||||||
emit: ((event: "input", _v: number | null | undefined) => void) & ((event: "update:value", _v: number | null | undefined) => void) & ((event: "change", _v: number | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
displayValue: Ref<string, string>;
|
|
||||||
isInteiro: import("vue").ComputedRef<boolean>;
|
|
||||||
onUpdateModelValue: (texto: string) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: number | null | undefined) => true;
|
|
||||||
input: (_v: number | null | undefined) => true;
|
|
||||||
change: (_v: number | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onInput?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
"onUpdate:value"?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: number | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: import("vue").Attrs;
|
|
||||||
emit: ((event: "input", _v: string | null | undefined) => void) & ((event: "update:value", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
|
||||||
onInput: (e: Event) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null | undefined) => true;
|
|
||||||
input: (_v: string | null | undefined) => true;
|
|
||||||
change: (_v: string | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: string | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
opcoesEntrada: (entrada: ComponenteEntrada) => {
|
opcoesEntrada: (entrada: ComponenteEntrada) => {
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ declare const __VLS_export: import("vue").DefineComponent<{}, {
|
||||||
};
|
};
|
||||||
}>, {
|
}>, {
|
||||||
attrs: import("vue").Attrs;
|
attrs: import("vue").Attrs;
|
||||||
emit: ((event: "input", _v: string | null | undefined) => void) & ((event: "update:value", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
emit: ((event: "input", _v: string | null | undefined) => void) & ((event: "blur") => void) & ((event: "update:value", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void);
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
inputMode: import("vue").ComputedRef<string | undefined>;
|
||||||
|
|
@ -182,10 +182,10 @@ declare const __VLS_export: import("vue").DefineComponent<{}, {
|
||||||
};
|
};
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
||||||
|
onBlur?: (() => any) | undefined;
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
||||||
onFocus?: (() => any) | undefined;
|
onFocus?: (() => any) | undefined;
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
}>, {
|
||||||
value: string | null | undefined;
|
value: string | null | undefined;
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "eli-vue",
|
"name": "eli-vue",
|
||||||
"version": "0.1.184",
|
"version": "0.1.187",
|
||||||
"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",
|
||||||
|
|
@ -15,10 +15,10 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"biome": "pnpm exec biome check --write",
|
"biome": "pnpm exec biome check --write",
|
||||||
"check": "pnpm run biome && npx tsc --noEmit",
|
"check": "pnpm run biome && npx tsc --noEmit",
|
||||||
"prebuild": "npm version patch --no-git-tag-version && bash scripts/check-linhas.sh",
|
"prebuild": "npm version patch --no-git-tag-version",
|
||||||
"build:types": "vue-tsc -p tsconfig.build.json --declaration --emitDeclarationOnly",
|
"build:types": "vue-tsc -p tsconfig.build.json --declaration --emitDeclarationOnly",
|
||||||
"build": "pnpm run biome && vite build && npm run build:types",
|
"build": "sh ./.agent/verificar-linhas.sh || exit 1 && pnpm run biome && vite build && npm run build:types",
|
||||||
"dev": "pnpm run biome && pnpm run fechar && vite",
|
"dev": "sh ./.agent/verificar-linhas.sh || exit 1 && pnpm run biome && pnpm run fechar && vite",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"fechar": "fuser -k 5555/tcp || true"
|
"fechar": "fuser -k 5555/tcp || true"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
30
pnpm-lock.yaml
generated
30
pnpm-lock.yaml
generated
|
|
@ -22,10 +22,10 @@ importers:
|
||||||
version: 1.11.21
|
version: 1.11.21
|
||||||
p-comuns:
|
p-comuns:
|
||||||
specifier: git+https://git2.idz.one/publico/_comuns.git
|
specifier: git+https://git2.idz.one/publico/_comuns.git
|
||||||
version: git+https://git2.idz.one/publico/_comuns.git#4aa775266f009b085dd9067e47a3206792812863(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3)
|
version: git+https://git2.idz.one/publico/_comuns.git#48125b53699708bc3747015dfda380473c1298d8(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3)
|
||||||
p-respostas:
|
p-respostas:
|
||||||
specifier: git+https://git2.idz.one/publico/_respostas.git
|
specifier: git+https://git2.idz.one/publico/_respostas.git
|
||||||
version: git+https://git2.idz.one/publico/_respostas.git#9aa36bcba98de8efd9babec6ab84099da5d46234(p-comuns@git+https://git2.idz.one/publico/_comuns.git#4aa775266f009b085dd9067e47a3206792812863(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3))(zod@4.4.3)
|
version: git+https://git2.idz.one/publico/_respostas.git#9aa36bcba98de8efd9babec6ab84099da5d46234(p-comuns@git+https://git2.idz.one/publico/_comuns.git#48125b53699708bc3747015dfda380473c1298d8(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3))(zod@4.4.3)
|
||||||
uuid:
|
uuid:
|
||||||
specifier: ^13.0.0
|
specifier: ^13.0.0
|
||||||
version: 13.0.2
|
version: 13.0.2
|
||||||
|
|
@ -1272,9 +1272,9 @@ packages:
|
||||||
resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==}
|
resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
p-comuns@git+https://git2.idz.one/publico/_comuns.git#4aa775266f009b085dd9067e47a3206792812863:
|
p-comuns@git+https://git2.idz.one/publico/_comuns.git#48125b53699708bc3747015dfda380473c1298d8:
|
||||||
resolution: {commit: 4aa775266f009b085dd9067e47a3206792812863, repo: https://git2.idz.one/publico/_comuns.git, type: git}
|
resolution: {commit: 48125b53699708bc3747015dfda380473c1298d8, repo: https://git2.idz.one/publico/_comuns.git, type: git}
|
||||||
version: 0.342.0
|
version: 0.346.0
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
dayjs: ^1.11.18
|
dayjs: ^1.11.18
|
||||||
uuid: ^11.1.0
|
uuid: ^11.1.0
|
||||||
|
|
@ -1483,6 +1483,10 @@ packages:
|
||||||
resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
|
resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
||||||
|
tinyglobby@0.2.17:
|
||||||
|
resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
|
||||||
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
||||||
tmpl@1.0.5:
|
tmpl@1.0.5:
|
||||||
resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
|
resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
|
||||||
|
|
||||||
|
|
@ -2040,7 +2044,7 @@ snapshots:
|
||||||
hermes-parser: 0.33.3
|
hermes-parser: 0.33.3
|
||||||
invariant: 2.2.4
|
invariant: 2.2.4
|
||||||
nullthrows: 1.1.1
|
nullthrows: 1.1.1
|
||||||
tinyglobby: 0.2.16
|
tinyglobby: 0.2.17
|
||||||
yargs: 17.7.2
|
yargs: 17.7.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
@ -3034,15 +3038,15 @@ snapshots:
|
||||||
is-wsl: 2.2.0
|
is-wsl: 2.2.0
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
p-comuns@git+https://git2.idz.one/publico/_comuns.git#4aa775266f009b085dd9067e47a3206792812863(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3):
|
p-comuns@git+https://git2.idz.one/publico/_comuns.git#48125b53699708bc3747015dfda380473c1298d8(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
dayjs: 1.11.21
|
dayjs: 1.11.21
|
||||||
uuid: 13.0.2
|
uuid: 13.0.2
|
||||||
zod: 4.4.3
|
zod: 4.4.3
|
||||||
|
|
||||||
p-respostas@git+https://git2.idz.one/publico/_respostas.git#9aa36bcba98de8efd9babec6ab84099da5d46234(p-comuns@git+https://git2.idz.one/publico/_comuns.git#4aa775266f009b085dd9067e47a3206792812863(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3))(zod@4.4.3):
|
p-respostas@git+https://git2.idz.one/publico/_respostas.git#9aa36bcba98de8efd9babec6ab84099da5d46234(p-comuns@git+https://git2.idz.one/publico/_comuns.git#48125b53699708bc3747015dfda380473c1298d8(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3))(zod@4.4.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
p-comuns: git+https://git2.idz.one/publico/_comuns.git#4aa775266f009b085dd9067e47a3206792812863(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3)
|
p-comuns: git+https://git2.idz.one/publico/_comuns.git#48125b53699708bc3747015dfda380473c1298d8(dayjs@1.11.21)(uuid@13.0.2)(zod@4.4.3)
|
||||||
zod: 4.4.3
|
zod: 4.4.3
|
||||||
|
|
||||||
parseurl@1.3.3:
|
parseurl@1.3.3:
|
||||||
|
|
@ -3136,7 +3140,7 @@ snapshots:
|
||||||
scheduler: 0.27.0
|
scheduler: 0.27.0
|
||||||
semver: 7.8.1
|
semver: 7.8.1
|
||||||
stacktrace-parser: 0.1.11
|
stacktrace-parser: 0.1.11
|
||||||
tinyglobby: 0.2.16
|
tinyglobby: 0.2.17
|
||||||
whatwg-fetch: 3.6.20
|
whatwg-fetch: 3.6.20
|
||||||
ws: 7.5.11
|
ws: 7.5.11
|
||||||
yargs: 17.7.2
|
yargs: 17.7.2
|
||||||
|
|
@ -3320,6 +3324,12 @@ snapshots:
|
||||||
fdir: 6.5.0(picomatch@4.0.4)
|
fdir: 6.5.0(picomatch@4.0.4)
|
||||||
picomatch: 4.0.4
|
picomatch: 4.0.4
|
||||||
|
|
||||||
|
tinyglobby@0.2.17:
|
||||||
|
dependencies:
|
||||||
|
fdir: 6.5.0(picomatch@4.0.4)
|
||||||
|
picomatch: 4.0.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
tmpl@1.0.5:
|
tmpl@1.0.5:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# check-linhas.sh
|
|
||||||
# Garante que nenhum arquivo *.vue, *.ts ou *.tsx ultrapasse o limite de linhas definido.
|
|
||||||
# Executado automaticamente no prebuild via package.json.
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
LIMITE=250
|
|
||||||
|
|
||||||
# Arquivos isentos permanentes (gerados, dados de teste, etc.)
|
|
||||||
# Formato: caminho relativo a partir da raiz do projeto
|
|
||||||
ISENTOS=(
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
RAIZ="$(cd "$(dirname "$0")/.." && pwd)"
|
|
||||||
ERROS=0
|
|
||||||
|
|
||||||
while IFS= read -r arquivo; do
|
|
||||||
relativo="${arquivo#$RAIZ/}"
|
|
||||||
|
|
||||||
# Verifica se está na lista de isentos
|
|
||||||
isento=false
|
|
||||||
for i in "${ISENTOS[@]}"; do
|
|
||||||
if [ "$relativo" = "$i" ]; then
|
|
||||||
isento=true
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if $isento; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
linhas=$(wc -l < "$arquivo")
|
|
||||||
if [ "$linhas" -gt "$LIMITE" ]; then
|
|
||||||
echo "❌ $relativo ($linhas linhas) — limite: $LIMITE"
|
|
||||||
ERROS=$((ERROS + 1))
|
|
||||||
fi
|
|
||||||
done < <(find "$RAIZ/src" \( -name "*.vue" -o -name "*.ts" -o -name "*.tsx" \) -not -path "*/node_modules/*")
|
|
||||||
|
|
||||||
if [ "$ERROS" -gt 0 ]; then
|
|
||||||
echo ""
|
|
||||||
echo "⚠️ $ERROS arquivo(s) ultrapassam o limite de $LIMITE linhas."
|
|
||||||
echo " Estratégias: subcomponentes, composables use*.ts, ou separar CSS."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Todos os arquivos (*.vue, *.ts, *.tsx) estão dentro do limite de $LIMITE linhas."
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# check-vue-linhas.sh
|
|
||||||
# Garante que nenhum arquivo *.vue ultrapasse o limite de linhas definido.
|
|
||||||
#
|
|
||||||
# Arquivos listados em ISENTOS são legados em processo de refatoração —
|
|
||||||
# cada um deve ser quebrado em componentes menores antes de ser removido daqui.
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
LIMITE=250
|
|
||||||
|
|
||||||
# Todos os arquivos *.vue devem respeitar o limite.
|
|
||||||
# Não existem isentos.
|
|
||||||
ISENTOS=()
|
|
||||||
|
|
||||||
RAIZ="$(cd "$(dirname "$0")/.." && pwd)"
|
|
||||||
ERROS=0
|
|
||||||
|
|
||||||
# Constrói padrão grep para os isentos
|
|
||||||
isentos_grep=""
|
|
||||||
for isento in "${ISENTOS[@]}"; do
|
|
||||||
if [ -n "$isentos_grep" ]; then
|
|
||||||
isentos_grep="${isentos_grep}\|${isento}"
|
|
||||||
else
|
|
||||||
isentos_grep="${isento}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
while IFS= read -r arquivo; do
|
|
||||||
relativo="${arquivo#$RAIZ/}"
|
|
||||||
|
|
||||||
# Verifica se está na lista de isentos
|
|
||||||
isento=false
|
|
||||||
for i in "${ISENTOS[@]}"; do
|
|
||||||
if [ "$relativo" = "$i" ]; then
|
|
||||||
isento=true
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if $isento; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
linhas=$(wc -l < "$arquivo")
|
|
||||||
if [ "$linhas" -gt "$LIMITE" ]; then
|
|
||||||
echo "❌ $relativo ($linhas linhas) — limite: $LIMITE"
|
|
||||||
ERROS=$((ERROS + 1))
|
|
||||||
fi
|
|
||||||
done < <(find "$RAIZ/src" -name "*.vue" -not -path "*/node_modules/*")
|
|
||||||
|
|
||||||
if [ "$ERROS" -gt 0 ]; then
|
|
||||||
echo ""
|
|
||||||
echo "⚠️ $ERROS arquivo(s) Vue ultrapassam o limite de $LIMITE linhas."
|
|
||||||
echo " Quebre em componentes menores antes de fazer build."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Todos os arquivos Vue estão dentro do limite de $LIMITE linhas."
|
|
||||||
62
src/componentes/EliEntrada/EliEntradaConfirmacao.vue
Normal file
62
src/componentes/EliEntrada/EliEntradaConfirmacao.vue
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
<template>
|
||||||
|
<v-switch
|
||||||
|
v-model="localValue"
|
||||||
|
:label="rotuloExibido"
|
||||||
|
:color="opcoes?.cor ?? 'primary'"
|
||||||
|
:disabled="Boolean(opcoes?.desabilitado)"
|
||||||
|
:density="opcoes?.densidade ?? 'comfortable'"
|
||||||
|
hide-details
|
||||||
|
v-bind="attrs"
|
||||||
|
@focus="() => emit('focus')"
|
||||||
|
@blur="() => emit('blur')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent, type PropType } from "vue"
|
||||||
|
import { VSwitch } from "vuetify/components"
|
||||||
|
import type { PadroesEntradas } from "./tiposEntradas"
|
||||||
|
|
||||||
|
type EntradaConfirmacao = PadroesEntradas["confirmacao"]
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "EliEntradaConfirmacao",
|
||||||
|
components: { VSwitch },
|
||||||
|
inheritAttrs: false,
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Boolean as PropType<EntradaConfirmacao["value"]>,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
opcoes: {
|
||||||
|
type: Object as PropType<EntradaConfirmacao["opcoes"]>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: {
|
||||||
|
"update:value": (_v: EntradaConfirmacao["value"]) => true,
|
||||||
|
input: (_v: EntradaConfirmacao["value"]) => true,
|
||||||
|
change: (_v: EntradaConfirmacao["value"]) => true,
|
||||||
|
focus: () => true,
|
||||||
|
blur: () => true,
|
||||||
|
},
|
||||||
|
setup(props, { attrs, emit }) {
|
||||||
|
const localValue = computed<EntradaConfirmacao["value"]>({
|
||||||
|
get: () => props.value,
|
||||||
|
set: (v) => {
|
||||||
|
emit("update:value", v)
|
||||||
|
emit("input", v)
|
||||||
|
emit("change", v)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const rotuloExibido = computed(() => {
|
||||||
|
if (localValue.value && props.opcoes?.rotuloAtivo) return props.opcoes.rotuloAtivo
|
||||||
|
if (!localValue.value && props.opcoes?.rotuloInativo) return props.opcoes.rotuloInativo
|
||||||
|
return props.opcoes?.rotulo ?? ""
|
||||||
|
})
|
||||||
|
|
||||||
|
return { attrs, emit, localValue, rotuloExibido }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
95
src/componentes/EliEntrada/EliEntradaSelecaoMultipla.vue
Normal file
95
src/componentes/EliEntrada/EliEntradaSelecaoMultipla.vue
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
<template>
|
||||||
|
<v-select
|
||||||
|
v-model="localValue"
|
||||||
|
:label="opcoes?.rotulo"
|
||||||
|
:placeholder="opcoes?.placeholder"
|
||||||
|
:items="itens"
|
||||||
|
item-title="rotulo"
|
||||||
|
item-value="chave"
|
||||||
|
:loading="carregando"
|
||||||
|
:disabled="carregando"
|
||||||
|
:menu-props="{ maxHeight: 320, zIndex: 99999 }"
|
||||||
|
:clearable="Boolean(opcoes?.limpavel)"
|
||||||
|
:error="Boolean(opcoes?.erro)"
|
||||||
|
:error-messages="opcoes?.mensagensErro"
|
||||||
|
:hint="opcoes?.dica"
|
||||||
|
:persistent-hint="Boolean(opcoes?.dicaPersistente)"
|
||||||
|
:density="opcoes?.densidade ?? 'comfortable'"
|
||||||
|
:variant="opcoes?.variante ?? 'outlined'"
|
||||||
|
multiple
|
||||||
|
chips
|
||||||
|
closable-chips
|
||||||
|
v-bind="attrs"
|
||||||
|
@focus="() => emit('focus')"
|
||||||
|
@blur="() => emit('blur')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent, onMounted, type PropType, ref, watch } from "vue"
|
||||||
|
import { VSelect } from "vuetify/components"
|
||||||
|
import type { PadroesEntradas } from "./tiposEntradas"
|
||||||
|
|
||||||
|
type EntradaSelecaoMultipla = PadroesEntradas["selecaoMultipla"]
|
||||||
|
type ItemSelecao = { chave: string; rotulo: string }
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "EliEntradaSelecaoMultipla",
|
||||||
|
components: { VSelect },
|
||||||
|
inheritAttrs: false,
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: [Array, null] as unknown as PropType<EntradaSelecaoMultipla["value"]>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
opcoes: {
|
||||||
|
type: Object as PropType<EntradaSelecaoMultipla["opcoes"]>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: {
|
||||||
|
"update:value": (_v: EntradaSelecaoMultipla["value"]) => true,
|
||||||
|
input: (_v: EntradaSelecaoMultipla["value"]) => true,
|
||||||
|
change: (_v: EntradaSelecaoMultipla["value"]) => true,
|
||||||
|
focus: () => true,
|
||||||
|
blur: () => true,
|
||||||
|
},
|
||||||
|
setup(props, { attrs, emit }) {
|
||||||
|
const itens = ref<ItemSelecao[]>([])
|
||||||
|
const carregando = ref(false)
|
||||||
|
|
||||||
|
const localValue = computed<EntradaSelecaoMultipla["value"]>({
|
||||||
|
get: () => props.value ?? [],
|
||||||
|
set: (v) => {
|
||||||
|
const valor = Array.isArray(v) ? v : []
|
||||||
|
emit("update:value", valor)
|
||||||
|
emit("input", valor)
|
||||||
|
emit("change", valor)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
async function carregarItens() {
|
||||||
|
carregando.value = true
|
||||||
|
try {
|
||||||
|
const resultado = await props.opcoes.itens()
|
||||||
|
itens.value = [...(Array.isArray(resultado) ? resultado : [])]
|
||||||
|
} finally {
|
||||||
|
carregando.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.opcoes.itens,
|
||||||
|
() => {
|
||||||
|
void carregarItens()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
void carregarItens()
|
||||||
|
})
|
||||||
|
|
||||||
|
return { attrs, emit, localValue, itens, carregando }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
|
import EliEntradaConfirmacao from "./EliEntradaConfirmacao.vue"
|
||||||
import EliEntradaDataHora from "./EliEntradaDataHora.vue"
|
import EliEntradaDataHora from "./EliEntradaDataHora.vue"
|
||||||
import EliEntradaNumero from "./EliEntradaNumero.vue"
|
import EliEntradaNumero from "./EliEntradaNumero.vue"
|
||||||
import EliEntradaParagrafo from "./EliEntradaParagrafo.vue"
|
import EliEntradaParagrafo from "./EliEntradaParagrafo.vue"
|
||||||
import EliEntradaSelecao from "./EliEntradaSelecao.vue"
|
import EliEntradaSelecao from "./EliEntradaSelecao.vue"
|
||||||
|
import EliEntradaSelecaoMultipla from "./EliEntradaSelecaoMultipla.vue"
|
||||||
import EliEntradaTexto from "./EliEntradaTexto.vue"
|
import EliEntradaTexto from "./EliEntradaTexto.vue"
|
||||||
|
|
||||||
export type { PadroesEntradas, TipoEntrada } from "./tiposEntradas"
|
export type { PadroesEntradas, TipoEntrada } from "./tiposEntradas"
|
||||||
export {
|
export {
|
||||||
|
EliEntradaConfirmacao,
|
||||||
EliEntradaDataHora,
|
EliEntradaDataHora,
|
||||||
EliEntradaNumero,
|
EliEntradaNumero,
|
||||||
EliEntradaParagrafo,
|
EliEntradaParagrafo,
|
||||||
EliEntradaSelecao,
|
EliEntradaSelecao,
|
||||||
|
EliEntradaSelecaoMultipla,
|
||||||
EliEntradaTexto,
|
EliEntradaTexto,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
import type { Component } from "vue"
|
import type { Component } from "vue"
|
||||||
|
import EliEntradaConfirmacao from "./EliEntradaConfirmacao.vue"
|
||||||
import EliEntradaDataHora from "./EliEntradaDataHora.vue"
|
import EliEntradaDataHora from "./EliEntradaDataHora.vue"
|
||||||
import EliEntradaNumero from "./EliEntradaNumero.vue"
|
import EliEntradaNumero from "./EliEntradaNumero.vue"
|
||||||
import EliEntradaParagrafo from "./EliEntradaParagrafo.vue"
|
import EliEntradaParagrafo from "./EliEntradaParagrafo.vue"
|
||||||
import EliEntradaSelecao from "./EliEntradaSelecao.vue"
|
import EliEntradaSelecao from "./EliEntradaSelecao.vue"
|
||||||
|
import EliEntradaSelecaoMultipla from "./EliEntradaSelecaoMultipla.vue"
|
||||||
import EliEntradaTexto from "./EliEntradaTexto.vue"
|
import EliEntradaTexto from "./EliEntradaTexto.vue"
|
||||||
|
|
||||||
import type { TipoEntrada } from "./tiposEntradas"
|
import type { TipoEntrada } from "./tiposEntradas"
|
||||||
|
|
@ -17,10 +19,12 @@ import type { TipoEntrada } from "./tiposEntradas"
|
||||||
* 2. Adicionar a chave em `TipoEntrada` (tiposEntradas.ts)
|
* 2. Adicionar a chave em `TipoEntrada` (tiposEntradas.ts)
|
||||||
* 3. Registrar aqui no mapa
|
* 3. Registrar aqui no mapa
|
||||||
*/
|
*/
|
||||||
export const registryTabelaCelulas = {
|
export const registryTabelaCelulas: Record<TipoEntrada, Component> = {
|
||||||
texto: EliEntradaTexto,
|
texto: EliEntradaTexto,
|
||||||
numero: EliEntradaNumero,
|
numero: EliEntradaNumero,
|
||||||
dataHora: EliEntradaDataHora,
|
dataHora: EliEntradaDataHora,
|
||||||
paragrafo: EliEntradaParagrafo,
|
paragrafo: EliEntradaParagrafo,
|
||||||
selecao: EliEntradaSelecao,
|
selecao: EliEntradaSelecao,
|
||||||
} as const satisfies Record<TipoEntrada, Component>
|
selecaoMultipla: EliEntradaSelecaoMultipla,
|
||||||
|
confirmacao: EliEntradaConfirmacao,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,60 @@ export type PadroesEntradas = {
|
||||||
variante?: import("../../tipos").CampoVariante
|
variante?: import("../../tipos").CampoVariante
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
selecaoMultipla: tipoPadraoEntrada<
|
||||||
|
string[] | null | undefined,
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Carrega os itens da seleção (sincrono ou async).
|
||||||
|
* - Cada item precisa ter uma chave estável (value) e um rótulo (title).
|
||||||
|
*/
|
||||||
|
itens: () =>
|
||||||
|
| { chave: string; rotulo: string }[]
|
||||||
|
| Promise<{ chave: string; rotulo: string }[]>
|
||||||
|
|
||||||
|
/** Se true, mostra ícone para limpar o valor (Vuetify clearable). */
|
||||||
|
limpavel?: boolean
|
||||||
|
|
||||||
|
/** Estado de erro (visual). */
|
||||||
|
erro?: boolean
|
||||||
|
|
||||||
|
/** Mensagens de erro. */
|
||||||
|
mensagensErro?: string | string[]
|
||||||
|
|
||||||
|
/** Texto de apoio. */
|
||||||
|
dica?: string
|
||||||
|
|
||||||
|
/** Mantém a dica sempre visível. */
|
||||||
|
dicaPersistente?: boolean
|
||||||
|
|
||||||
|
/** Densidade do campo (Vuetify). */
|
||||||
|
densidade?: import("../../tipos").CampoDensidade
|
||||||
|
|
||||||
|
/** Variante do v-text-field (Vuetify). */
|
||||||
|
variante?: import("../../tipos").CampoVariante
|
||||||
|
}
|
||||||
|
>
|
||||||
|
|
||||||
|
confirmacao: tipoPadraoEntrada<
|
||||||
|
boolean,
|
||||||
|
{
|
||||||
|
/** Cor do switch quando ativo (Vuetify color). */
|
||||||
|
cor?: string
|
||||||
|
|
||||||
|
/** Se true, desabilita a interação. */
|
||||||
|
desabilitado?: boolean
|
||||||
|
|
||||||
|
/** Texto exibido ao lado do switch quando ativo. */
|
||||||
|
rotuloAtivo?: string
|
||||||
|
|
||||||
|
/** Texto exibido ao lado do switch quando inativo. */
|
||||||
|
rotuloInativo?: string
|
||||||
|
|
||||||
|
/** Densidade do campo (Vuetify). */
|
||||||
|
densidade?: import("../../tipos").CampoDensidade
|
||||||
|
}
|
||||||
|
>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "./EliTabelaAcoes.css";
|
||||||
|
@import "./EliTabelaSelecao.css";
|
||||||
.eli-tabela {
|
.eli-tabela {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +134,6 @@
|
||||||
background: rgba(0, 0, 0, 0.03);
|
background: rgba(0, 0, 0, 0.03);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.eli-tabela--erro {
|
.eli-tabela--erro {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
@ -244,284 +245,6 @@
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
/* Altura padrão para controles do cabeçalho (busca e botões)
|
|
||||||
* - Mantém alinhamento visual entre input de busca e ações
|
|
||||||
* - Pode ser sobrescrita via CSS no consumidor, se necessário
|
|
||||||
*/
|
|
||||||
--eli-tabela-cabecalho-controle-altura: 34px;
|
--eli-tabela-cabecalho-controle-altura: 34px;
|
||||||
|
|
||||||
/* Borda dos controles do cabeçalho: menos "pílula", mais quadrado.
|
|
||||||
* Ajuste fino via CSS no consumidor, se necessário.
|
|
||||||
*/
|
|
||||||
--eli-tabela-cabecalho-controle-radius: 8px;
|
--eli-tabela-cabecalho-controle-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.eli-tabela__acoes-cabecalho {
|
|
||||||
display: inline-flex;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-cabecalho-botao {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
height: var(--eli-tabela-cabecalho-controle-altura);
|
|
||||||
padding: 0 14px;
|
|
||||||
border-radius: var(--eli-tabela-cabecalho-controle-radius);
|
|
||||||
border: none;
|
|
||||||
background: var(--cor-eli-primaria-bg);
|
|
||||||
color: var(--cor-eli-primaria-escura);
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 1;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s ease, color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-cabecalho-botao:hover,
|
|
||||||
.eli-tabela__acoes-cabecalho-botao:focus-visible {
|
|
||||||
background: var(--cor-eli-primaria-clara);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-cabecalho-botao:focus-visible {
|
|
||||||
outline: 2px solid var(--cor-eli-primaria-clara);
|
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-cabecalho-icone {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-cabecalho-rotulo {
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-toggle {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 9999px;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
color: rgba(15, 23, 42, 0.72);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s ease, color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-toggle-icone {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-toggle:hover,
|
|
||||||
.eli-tabela__acoes-toggle:focus-visible {
|
|
||||||
background-color: rgba(15, 23, 42, 0.08);
|
|
||||||
color: rgba(15, 23, 42, 0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-toggle:focus-visible {
|
|
||||||
outline: 2px solid var(--cor-eli-primaria-clara);
|
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-toggle:disabled {
|
|
||||||
cursor: default;
|
|
||||||
color: rgba(148, 163, 184, 0.8);
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-menu {
|
|
||||||
min-width: 180px;
|
|
||||||
padding: 6px 0;
|
|
||||||
margin: 0;
|
|
||||||
list-style: none;
|
|
||||||
background: var(--cor-eli-superficie);
|
|
||||||
border: 1px solid rgba(15, 23, 42, 0.08);
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0 12px 30px rgba(15, 23, 42, 0.18);
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-item {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-item-botao {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-item-botao:hover,
|
|
||||||
.eli-tabela__acoes-item-botao:focus-visible {
|
|
||||||
background-color: rgba(15, 23, 42, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-item-botao:focus-visible {
|
|
||||||
outline: 2px solid currentColor;
|
|
||||||
outline-offset: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-item-icone {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__acoes-item-texto {
|
|
||||||
flex: 1;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================
|
|
||||||
* Expander (colunas invisíveis)
|
|
||||||
* ========================= */
|
|
||||||
|
|
||||||
.eli-tabela__th--expander,
|
|
||||||
.eli-tabela__td--expander {
|
|
||||||
width: 42px;
|
|
||||||
padding: 6px 8px;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__expander-botao {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
border-radius: 9999px;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
color: rgba(15, 23, 42, 0.72);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s ease, color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__expander-botao:hover,
|
|
||||||
.eli-tabela__expander-botao:focus-visible {
|
|
||||||
background-color: rgba(15, 23, 42, 0.08);
|
|
||||||
color: rgba(15, 23, 42, 0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__expander-botao:focus-visible {
|
|
||||||
outline: 2px solid var(--cor-eli-primaria-clara);
|
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__expander-botao--ativo {
|
|
||||||
background-color: rgba(15, 23, 42, 0.06);
|
|
||||||
color: rgba(15, 23, 42, 0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__td--detalhes {
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__tr--detalhes .eli-tabela__td {
|
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__detalhes {
|
|
||||||
display: grid;
|
|
||||||
gap: 10px;
|
|
||||||
padding-left: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__detalhe {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 180px 1fr;
|
|
||||||
gap: 10px;
|
|
||||||
align-items: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__detalhe-rotulo {
|
|
||||||
font-weight: 600;
|
|
||||||
color: rgba(15, 23, 42, 0.85);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__detalhe-valor {
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
.eli-tabela__detalhe {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
* Seleção (Checkboxes)
|
|
||||||
* ========================================= */
|
|
||||||
.eli-tabela__th--selecao,
|
|
||||||
.eli-tabela__td--selecao {
|
|
||||||
width: 48px;
|
|
||||||
min-width: 48px;
|
|
||||||
max-width: 48px;
|
|
||||||
text-align: center;
|
|
||||||
padding: 0 8px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__checkbox {
|
|
||||||
appearance: none;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
cursor: pointer;
|
|
||||||
border: 2px solid rgba(0, 0, 0, 0.54);
|
|
||||||
border-radius: 2px;
|
|
||||||
margin: 0;
|
|
||||||
vertical-align: middle;
|
|
||||||
position: relative;
|
|
||||||
transition: all 0.2s ease-in-out;
|
|
||||||
background-color: transparent;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__checkbox:hover {
|
|
||||||
border-color: rgba(0, 0, 0, 0.87);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__checkbox:checked,
|
|
||||||
.eli-tabela__checkbox:indeterminate {
|
|
||||||
background-color: var(--cor-eli-primaria);
|
|
||||||
border-color: var(--cor-eli-primaria);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__checkbox:checked::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: 4px;
|
|
||||||
width: 4px;
|
|
||||||
height: 9px;
|
|
||||||
border: solid white;
|
|
||||||
border-width: 0 2px 2px 0;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__checkbox:indeterminate::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 5px;
|
|
||||||
left: 2px;
|
|
||||||
width: 8px;
|
|
||||||
height: 2px;
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela__checkbox:focus-visible {
|
|
||||||
box-shadow: 0 0 0 2px var(--cor-eli-primaria-clara);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
v-if="exibirBusca || temAcoesSuperiores"
|
v-if="exibirBusca || temAcoesSuperiores"
|
||||||
:exibirBusca="exibirBusca"
|
:exibirBusca="exibirBusca"
|
||||||
:exibirBotaoFiltroAvancado="exibirFiltroAvancado"
|
:exibirBotaoFiltroAvancado="exibirFiltroAvancado"
|
||||||
|
:filtrosAtivosResumo="filtrosAtivosResumo"
|
||||||
:valorBusca="valorBusca"
|
:valorBusca="valorBusca"
|
||||||
:acoesCabecalho="acoesSuperiores"
|
:acoesCabecalho="acoesSuperiores"
|
||||||
:parametrosConsulta="parametrosConsultaAtuais"
|
:parametrosConsulta="parametrosConsultaAtuais"
|
||||||
|
|
|
||||||
207
src/componentes/EliTabela/EliTabelaAcoes.css
Normal file
207
src/componentes/EliTabela/EliTabelaAcoes.css
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
/* =========================
|
||||||
|
* EliTabela — Ações de linha, Menu e Seleção (Checkboxes)
|
||||||
|
* Extraído de EliTabela.css para manter cada arquivo CSS abaixo de 250 linhas.
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
.eli-tabela__acoes-cabecalho {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-cabecalho-botao {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
height: var(--eli-tabela-cabecalho-controle-altura);
|
||||||
|
padding: 0 14px;
|
||||||
|
border-radius: var(--eli-tabela-cabecalho-controle-radius);
|
||||||
|
border: none;
|
||||||
|
background: var(--cor-eli-primaria-bg);
|
||||||
|
color: var(--cor-eli-primaria-escura);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease, color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-cabecalho-botao:hover,
|
||||||
|
.eli-tabela__acoes-cabecalho-botao:focus-visible {
|
||||||
|
background: var(--cor-eli-primaria-clara);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-cabecalho-botao:focus-visible {
|
||||||
|
outline: 2px solid var(--cor-eli-primaria-clara);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-cabecalho-icone {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-cabecalho-rotulo {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-toggle {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: rgba(15, 23, 42, 0.72);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease, color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-toggle-icone {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-toggle:hover,
|
||||||
|
.eli-tabela__acoes-toggle:focus-visible {
|
||||||
|
background-color: rgba(15, 23, 42, 0.08);
|
||||||
|
color: rgba(15, 23, 42, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-toggle:focus-visible {
|
||||||
|
outline: 2px solid var(--cor-eli-primaria-clara);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-toggle:disabled {
|
||||||
|
cursor: default;
|
||||||
|
color: rgba(148, 163, 184, 0.8);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-menu {
|
||||||
|
min-width: 180px;
|
||||||
|
padding: 6px 0;
|
||||||
|
margin: 0;
|
||||||
|
list-style: none;
|
||||||
|
background: var(--cor-eli-superficie);
|
||||||
|
border: 1px solid rgba(15, 23, 42, 0.08);
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 12px 30px rgba(15, 23, 42, 0.18);
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-item {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-item-botao {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-item-botao:hover,
|
||||||
|
.eli-tabela__acoes-item-botao:focus-visible {
|
||||||
|
background-color: rgba(15, 23, 42, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-item-botao:focus-visible {
|
||||||
|
outline: 2px solid currentColor;
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-item-icone {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__acoes-item-texto {
|
||||||
|
flex: 1;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
* Expander (colunas invisíveis)
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
.eli-tabela__th--expander,
|
||||||
|
.eli-tabela__td--expander {
|
||||||
|
width: 42px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__expander-botao {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: rgba(15, 23, 42, 0.72);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease, color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__expander-botao:hover,
|
||||||
|
.eli-tabela__expander-botao:focus-visible {
|
||||||
|
background-color: rgba(15, 23, 42, 0.08);
|
||||||
|
color: rgba(15, 23, 42, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__expander-botao:focus-visible {
|
||||||
|
outline: 2px solid var(--cor-eli-primaria-clara);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__expander-botao--ativo {
|
||||||
|
background-color: rgba(15, 23, 42, 0.06);
|
||||||
|
color: rgba(15, 23, 42, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__td--detalhes {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__tr--detalhes .eli-tabela__td {
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__detalhes {
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__detalhe {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 180px 1fr;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__detalhe-rotulo {
|
||||||
|
font-weight: 600;
|
||||||
|
color: rgba(15, 23, 42, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__detalhe-valor {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.eli-tabela__detalhe {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -16,9 +16,16 @@
|
||||||
v-if="exibirBotaoFiltroAvancado"
|
v-if="exibirBotaoFiltroAvancado"
|
||||||
type="button"
|
type="button"
|
||||||
class="eli-tabela__acoes-cabecalho-botao eli-tabela__acoes-cabecalho-botao--filtro"
|
class="eli-tabela__acoes-cabecalho-botao eli-tabela__acoes-cabecalho-botao--filtro"
|
||||||
|
:title="tooltipFiltro"
|
||||||
@click="emitFiltroAvancado"
|
@click="emitFiltroAvancado"
|
||||||
>
|
>
|
||||||
<Filter :size="15" :stroke-width="2" />
|
<span class="eli-tabela__filtro-icone-container">
|
||||||
|
<Filter :size="15" :stroke-width="2" />
|
||||||
|
<span
|
||||||
|
v-if="filtrosAtivosResumo.quantidade > 0"
|
||||||
|
class="eli-tabela__filtro-badge"
|
||||||
|
>{{ filtrosAtivosResumo.quantidade }}</span>
|
||||||
|
</span>
|
||||||
Filtro
|
Filtro
|
||||||
</button>
|
</button>
|
||||||
<EliTabelaCaixaDeBusca :modelo="valorBusca" @buscar="emitBuscar" />
|
<EliTabelaCaixaDeBusca :modelo="valorBusca" @buscar="emitBuscar" />
|
||||||
|
|
@ -70,6 +77,11 @@ export default defineComponent({
|
||||||
required: false,
|
required: false,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
filtrosAtivosResumo: {
|
||||||
|
type: Object as PropType<{ quantidade: number; rotulos: string[] }>,
|
||||||
|
required: false,
|
||||||
|
default: () => ({ quantidade: 0, rotulos: [] }),
|
||||||
|
},
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
|
|
@ -107,6 +119,12 @@ export default defineComponent({
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const temAcoesCabecalho = computed(() => props.acoesCabecalho.length > 0)
|
const temAcoesCabecalho = computed(() => props.acoesCabecalho.length > 0)
|
||||||
|
|
||||||
|
const tooltipFiltro = computed(() => {
|
||||||
|
const { quantidade, rotulos } = props.filtrosAtivosResumo
|
||||||
|
if (quantidade === 0) return "Filtro avançado"
|
||||||
|
return `Filtros ativos (${quantidade}):\n${rotulos.map((r) => `• ${r}`).join("\n")}`
|
||||||
|
})
|
||||||
|
|
||||||
function emitBuscar(texto: string) {
|
function emitBuscar(texto: string) {
|
||||||
emit("buscar", texto)
|
emit("buscar", texto)
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +137,7 @@ export default defineComponent({
|
||||||
emit("filtroAvancado")
|
emit("filtroAvancado")
|
||||||
}
|
}
|
||||||
|
|
||||||
return { temAcoesCabecalho, emitBuscar, emitColunas, emitFiltroAvancado }
|
return { temAcoesCabecalho, tooltipFiltro, emitBuscar, emitColunas, emitFiltroAvancado }
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -131,4 +149,28 @@ export default defineComponent({
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.eli-tabela__filtro-icone-container {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__filtro-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -7px;
|
||||||
|
right: -9px;
|
||||||
|
min-width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
padding: 0 4px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
background: var(--cor-eli-erro, #dc3545);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 16px;
|
||||||
|
text-align: center;
|
||||||
|
pointer-events: none;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "./EliTabelaModalColunasItens.css";
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__overlay {
|
.eli-tabela-modal-colunas__overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
|
@ -162,181 +164,3 @@
|
||||||
.eli-tabela-modal-colunas__lista--invisiveis {
|
.eli-tabela-modal-colunas__lista--invisiveis {
|
||||||
background: var(--cor-eli-fundo);
|
background: var(--cor-eli-fundo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Item ── */
|
|
||||||
.eli-tabela-modal-colunas__item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 9px 10px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid var(--cor-eli-borda);
|
|
||||||
background: var(--cor-eli-superficie);
|
|
||||||
cursor: grab;
|
|
||||||
user-select: none;
|
|
||||||
transition: box-shadow 0.15s ease, opacity 0.15s ease, border-color 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item + .eli-tabela-modal-colunas__item {
|
|
||||||
margin-top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item:hover {
|
|
||||||
border-color: var(--cor-eli-borda-forte);
|
|
||||||
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item:active {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item--invisivel {
|
|
||||||
opacity: 0.72;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item--arrastando {
|
|
||||||
opacity: 0.15;
|
|
||||||
border-style: dashed;
|
|
||||||
border-color: var(--cor-eli-primaria-media);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Partes do item ── */
|
|
||||||
.eli-tabela-modal-colunas__item-handle {
|
|
||||||
color: var(--cor-eli-borda-forte);
|
|
||||||
flex-shrink: 0;
|
|
||||||
transition: color 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item:hover .eli-tabela-modal-colunas__item-handle {
|
|
||||||
color: var(--cor-eli-neutro);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item-texto {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
color: var(--cor-eli-neutro-escuro);
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item-badge-icone {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item-badge-icone--visivel {
|
|
||||||
color: var(--cor-eli-primaria-acao);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__item-badge-icone--invisivel {
|
|
||||||
color: var(--cor-eli-borda-forte);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Estado vazio ── */
|
|
||||||
.eli-tabela-modal-colunas__vazio {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 24px 12px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: var(--cor-eli-neutro);
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__vazio-icone {
|
|
||||||
color: var(--cor-eli-borda-forte);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__vazio-icone--ok {
|
|
||||||
color: var(--cor-eli-primaria-acao);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Animações TransitionGroup ── */
|
|
||||||
.list-move,
|
|
||||||
.list-enter-active,
|
|
||||||
.list-leave-active {
|
|
||||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-enter-from,
|
|
||||||
.list-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-leave-active {
|
|
||||||
position: absolute;
|
|
||||||
width: calc(100% - 16px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Footer ── */
|
|
||||||
.eli-tabela-modal-colunas__footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 12px 16px;
|
|
||||||
border-top: 1px solid var(--cor-eli-borda);
|
|
||||||
background: var(--cor-eli-fundo);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__botao {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
height: 34px;
|
|
||||||
padding: 0 16px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid var(--cor-eli-borda);
|
|
||||||
background: var(--cor-eli-superficie);
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 500;
|
|
||||||
transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__botao--sec {
|
|
||||||
color: var(--cor-eli-neutro-escuro);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__botao--sec:hover,
|
|
||||||
.eli-tabela-modal-colunas__botao--sec:focus-visible {
|
|
||||||
background: var(--cor-eli-fundo);
|
|
||||||
border-color: var(--cor-eli-borda-forte);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__botao--sec:focus-visible {
|
|
||||||
outline: 2px solid var(--cor-eli-primaria-clara);
|
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__botao--prim {
|
|
||||||
border: none;
|
|
||||||
background: var(--cor-eli-primaria);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__botao--prim:hover,
|
|
||||||
.eli-tabela-modal-colunas__botao--prim:focus-visible {
|
|
||||||
background: var(--cor-eli-primaria-escura);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__botao--prim:focus-visible {
|
|
||||||
outline: 2px solid var(--cor-eli-primaria-clara);
|
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Responsivo ── */
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
.eli-tabela-modal-colunas__conteudo {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-colunas__coluna + .eli-tabela-modal-colunas__coluna {
|
|
||||||
border-left: none;
|
|
||||||
border-top: 1px solid var(--cor-eli-borda);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
182
src/componentes/EliTabela/EliTabelaModalColunasItens.css
Normal file
182
src/componentes/EliTabela/EliTabelaModalColunasItens.css
Normal file
|
|
@ -0,0 +1,182 @@
|
||||||
|
/* =========================
|
||||||
|
* EliTabelaModalColunas — Itens, estados e footer
|
||||||
|
* Extraído de EliTabelaModalColunas.css para manter cada arquivo abaixo de 250 linhas.
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
/* ── Item ── */
|
||||||
|
.eli-tabela-modal-colunas__item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 9px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--cor-eli-borda);
|
||||||
|
background: var(--cor-eli-superficie);
|
||||||
|
cursor: grab;
|
||||||
|
user-select: none;
|
||||||
|
transition: box-shadow 0.15s ease, opacity 0.15s ease, border-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item + .eli-tabela-modal-colunas__item {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item:hover {
|
||||||
|
border-color: var(--cor-eli-borda-forte);
|
||||||
|
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item--invisivel {
|
||||||
|
opacity: 0.72;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item--arrastando {
|
||||||
|
opacity: 0.15;
|
||||||
|
border-style: dashed;
|
||||||
|
border-color: var(--cor-eli-primaria-media);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Partes do item ── */
|
||||||
|
.eli-tabela-modal-colunas__item-handle {
|
||||||
|
color: var(--cor-eli-borda-forte);
|
||||||
|
flex-shrink: 0;
|
||||||
|
transition: color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item:hover .eli-tabela-modal-colunas__item-handle {
|
||||||
|
color: var(--cor-eli-neutro);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item-texto {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--cor-eli-neutro-escuro);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item-badge-icone {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item-badge-icone--visivel {
|
||||||
|
color: var(--cor-eli-primaria-acao);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__item-badge-icone--invisivel {
|
||||||
|
color: var(--cor-eli-borda-forte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Estado vazio ── */
|
||||||
|
.eli-tabela-modal-colunas__vazio {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 24px 12px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--cor-eli-neutro);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__vazio-icone {
|
||||||
|
color: var(--cor-eli-borda-forte);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__vazio-icone--ok {
|
||||||
|
color: var(--cor-eli-primaria-acao);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Animações TransitionGroup ── */
|
||||||
|
.list-move,
|
||||||
|
.list-enter-active,
|
||||||
|
.list-leave-active {
|
||||||
|
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-enter-from,
|
||||||
|
.list-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-leave-active {
|
||||||
|
position: absolute;
|
||||||
|
width: calc(100% - 16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Footer ── */
|
||||||
|
.eli-tabela-modal-colunas__footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-top: 1px solid var(--cor-eli-borda);
|
||||||
|
background: var(--cor-eli-fundo);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__botao {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
height: 34px;
|
||||||
|
padding: 0 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid var(--cor-eli-borda);
|
||||||
|
background: var(--cor-eli-superficie);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__botao--sec {
|
||||||
|
color: var(--cor-eli-neutro-escuro);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__botao--sec:hover,
|
||||||
|
.eli-tabela-modal-colunas__botao--sec:focus-visible {
|
||||||
|
background: var(--cor-eli-fundo);
|
||||||
|
border-color: var(--cor-eli-borda-forte);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__botao--sec:focus-visible {
|
||||||
|
outline: 2px solid var(--cor-eli-primaria-clara);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__botao--prim {
|
||||||
|
border: none;
|
||||||
|
background: var(--cor-eli-primaria);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__botao--prim:hover,
|
||||||
|
.eli-tabela-modal-colunas__botao--prim:focus-visible {
|
||||||
|
background: var(--cor-eli-primaria-escura);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__botao--prim:focus-visible {
|
||||||
|
outline: 2px solid var(--cor-eli-primaria-clara);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Responsivo ── */
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.eli-tabela-modal-colunas__conteudo {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-colunas__coluna + .eli-tabela-modal-colunas__coluna {
|
||||||
|
border-left: none;
|
||||||
|
border-top: 1px solid var(--cor-eli-borda);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "./EliTabelaModalFiltroFormula.css";
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__overlay {
|
.eli-tabela-modal-filtro__overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
|
@ -217,227 +219,3 @@
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: var(--cor-eli-primaria);
|
border-color: var(--cor-eli-primaria);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Fórmula de combinação ───────────────────── */
|
|
||||||
.eli-tabela-modal-filtro__formula-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-label {
|
|
||||||
font-size: 0.82rem;
|
|
||||||
font-weight: 500;
|
|
||||||
color: rgba(15, 23, 42, 0.55);
|
|
||||||
white-space: nowrap;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-ajuda {
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
color: rgba(15, 23, 42, 0.35);
|
|
||||||
cursor: help;
|
|
||||||
transition: color 0.15s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-ajuda:hover,
|
|
||||||
.eli-tabela-modal-filtro__formula-ajuda:focus-visible {
|
|
||||||
color: var(--cor-eli-primaria);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-ajuda:hover .eli-tabela-modal-filtro__formula-tooltip,
|
|
||||||
.eli-tabela-modal-filtro__formula-ajuda:focus-visible .eli-tabela-modal-filtro__formula-tooltip {
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: auto;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-tooltip {
|
|
||||||
position: absolute;
|
|
||||||
bottom: calc(100% + 10px);
|
|
||||||
right: 0;
|
|
||||||
width: 280px;
|
|
||||||
background: #0f172a;
|
|
||||||
color: #e2e8f0;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
line-height: 1.55;
|
|
||||||
z-index: 100;
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
transform: translateY(4px);
|
|
||||||
transition: opacity 0.18s ease, transform 0.18s ease;
|
|
||||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-tooltip::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 100%;
|
|
||||||
right: 6px;
|
|
||||||
border: 6px solid transparent;
|
|
||||||
border-top-color: #0f172a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-tooltip strong {
|
|
||||||
font-size: 0.82rem;
|
|
||||||
color: var(--cor-eli-fundo);
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-tooltip p {
|
|
||||||
margin: 6px 0 4px;
|
|
||||||
color: #94a3b8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-tooltip ul {
|
|
||||||
margin: 4px 0 8px 14px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-tooltip li {
|
|
||||||
margin-bottom: 3px;
|
|
||||||
color: #cbd5e1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-tooltip code {
|
|
||||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
|
||||||
color: #7dd3fc;
|
|
||||||
font-size: 0.78rem;
|
|
||||||
background: rgba(255, 255, 255, 0.07);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 1px 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-input {
|
|
||||||
width: 220px;
|
|
||||||
height: 36px;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
||||||
padding: 0 10px;
|
|
||||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
background: var(--cor-eli-fundo);
|
|
||||||
transition: border-color 0.15s, background 0.15s;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-input:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: var(--cor-eli-primaria);
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__formula-tooltip-nota {
|
|
||||||
margin-top: 8px;
|
|
||||||
opacity: 0.75;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Footer ──────────────────────────────────── */
|
|
||||||
.eli-tabela-modal-filtro__footer {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 14px 20px;
|
|
||||||
border-top: 1px solid rgba(15, 23, 42, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__footer-spacer {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Botões ──────────────────────────────────── */
|
|
||||||
.eli-tabela-modal-filtro__botao {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 5px;
|
|
||||||
height: 36px;
|
|
||||||
padding: 0 16px;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
||||||
background: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 500;
|
|
||||||
transition: background 0.15s, color 0.15s, border-color 0.15s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao:disabled {
|
|
||||||
opacity: 0.45;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao--sec:hover:not(:disabled),
|
|
||||||
.eli-tabela-modal-filtro__botao--sec:focus-visible {
|
|
||||||
background: rgba(15, 23, 42, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao--prim {
|
|
||||||
border: none;
|
|
||||||
background: var(--cor-eli-primaria);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao--prim:hover:not(:disabled),
|
|
||||||
.eli-tabela-modal-filtro__botao--prim:focus-visible {
|
|
||||||
background: var(--cor-eli-primaria-escura);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao--perigo {
|
|
||||||
color: rgba(220, 38, 38, 0.85);
|
|
||||||
border-color: rgba(220, 38, 38, 0.18);
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao--perigo:hover:not(:disabled),
|
|
||||||
.eli-tabela-modal-filtro__botao--perigo:focus-visible {
|
|
||||||
background: rgba(239, 68, 68, 0.06);
|
|
||||||
border-color: rgba(220, 38, 38, 0.3);
|
|
||||||
color: rgba(220, 38, 38, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Responsivo ──────────────────────────────── */
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.eli-tabela-modal-filtro__lista {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
.eli-tabela-modal-filtro__rodape-filtros {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
.eli-tabela-modal-filtro__acoes {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Transição de abertura/fechamento ────────── */
|
|
||||||
.eli-tabela-modal-filtro-enter-active,
|
|
||||||
.eli-tabela-modal-filtro-leave-active {
|
|
||||||
transition: opacity 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro-enter-active .eli-tabela-modal-filtro__modal,
|
|
||||||
.eli-tabela-modal-filtro-leave-active .eli-tabela-modal-filtro__modal {
|
|
||||||
transition: transform 0.2s ease, opacity 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro-enter-from,
|
|
||||||
.eli-tabela-modal-filtro-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro-enter-from .eli-tabela-modal-filtro__modal,
|
|
||||||
.eli-tabela-modal-filtro-leave-to .eli-tabela-modal-filtro__modal {
|
|
||||||
transform: scale(0.96);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
225
src/componentes/EliTabela/EliTabelaModalFiltroFormula.css
Normal file
225
src/componentes/EliTabela/EliTabelaModalFiltroFormula.css
Normal file
|
|
@ -0,0 +1,225 @@
|
||||||
|
/* =========================
|
||||||
|
* EliTabelaModalFiltroAvancado — Fórmula, tooltip, botões e transições
|
||||||
|
* Extraído de EliTabelaModalFiltroAvancado.css para manter cada arquivo abaixo de 250 linhas.
|
||||||
|
* ========================= */
|
||||||
|
|
||||||
|
/* ── Fórmula de combinação ───────────────────── */
|
||||||
|
.eli-tabela-modal-filtro__formula-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-label {
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: rgba(15, 23, 42, 0.55);
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-ajuda {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
color: rgba(15, 23, 42, 0.35);
|
||||||
|
cursor: help;
|
||||||
|
transition: color 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-ajuda:hover,
|
||||||
|
.eli-tabela-modal-filtro__formula-ajuda:focus-visible {
|
||||||
|
color: var(--cor-eli-primaria);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-ajuda:hover .eli-tabela-modal-filtro__formula-tooltip,
|
||||||
|
.eli-tabela-modal-filtro__formula-ajuda:focus-visible .eli-tabela-modal-filtro__formula-tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-tooltip {
|
||||||
|
position: absolute;
|
||||||
|
bottom: calc(100% + 10px);
|
||||||
|
right: 0;
|
||||||
|
width: 280px;
|
||||||
|
background: #0f172a;
|
||||||
|
color: #e2e8f0;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 14px 16px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
line-height: 1.55;
|
||||||
|
z-index: 100;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transform: translateY(4px);
|
||||||
|
transition: opacity 0.18s ease, transform 0.18s ease;
|
||||||
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-tooltip::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
right: 6px;
|
||||||
|
border: 6px solid transparent;
|
||||||
|
border-top-color: #0f172a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-tooltip strong {
|
||||||
|
font-size: 0.82rem;
|
||||||
|
color: var(--cor-eli-fundo);
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-tooltip p {
|
||||||
|
margin: 6px 0 4px;
|
||||||
|
color: #94a3b8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-tooltip ul {
|
||||||
|
margin: 4px 0 8px 14px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-tooltip li {
|
||||||
|
margin-bottom: 3px;
|
||||||
|
color: #cbd5e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-tooltip code {
|
||||||
|
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
||||||
|
color: #7dd3fc;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
background: rgba(255, 255, 255, 0.07);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 1px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-input {
|
||||||
|
width: 220px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid rgba(15, 23, 42, 0.12);
|
||||||
|
padding: 0 10px;
|
||||||
|
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
background: var(--cor-eli-fundo);
|
||||||
|
transition: border-color 0.15s, background 0.15s;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--cor-eli-primaria);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__formula-tooltip-nota {
|
||||||
|
margin-top: 8px;
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Footer ──────────────────────────────────── */
|
||||||
|
.eli-tabela-modal-filtro__footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 14px 20px;
|
||||||
|
border-top: 1px solid rgba(15, 23, 42, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__footer-spacer {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Botões ──────────────────────────────────── */
|
||||||
|
.eli-tabela-modal-filtro__botao {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
height: 36px;
|
||||||
|
padding: 0 16px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid rgba(15, 23, 42, 0.12);
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: background 0.15s, color 0.15s, border-color 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__botao:disabled {
|
||||||
|
opacity: 0.45;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__botao--sec:hover:not(:disabled),
|
||||||
|
.eli-tabela-modal-filtro__botao--sec:focus-visible {
|
||||||
|
background: rgba(15, 23, 42, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__botao--prim {
|
||||||
|
border: none;
|
||||||
|
background: var(--cor-eli-primaria);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__botao--prim:hover:not(:disabled),
|
||||||
|
.eli-tabela-modal-filtro__botao--prim:focus-visible {
|
||||||
|
background: var(--cor-eli-primaria-escura);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__botao--perigo {
|
||||||
|
color: rgba(220, 38, 38, 0.85);
|
||||||
|
border-color: rgba(220, 38, 38, 0.18);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro__botao--perigo:hover:not(:disabled),
|
||||||
|
.eli-tabela-modal-filtro__botao--perigo:focus-visible {
|
||||||
|
background: rgba(239, 68, 68, 0.06);
|
||||||
|
border-color: rgba(220, 38, 38, 0.3);
|
||||||
|
color: rgba(220, 38, 38, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Responsivo ──────────────────────────────── */
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.eli-tabela-modal-filtro__lista {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.eli-tabela-modal-filtro__rodape-filtros {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
.eli-tabela-modal-filtro__acoes {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Transição de abertura/fechamento ────────── */
|
||||||
|
.eli-tabela-modal-filtro-enter-active,
|
||||||
|
.eli-tabela-modal-filtro-leave-active {
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro-enter-active .eli-tabela-modal-filtro__modal,
|
||||||
|
.eli-tabela-modal-filtro-leave-active .eli-tabela-modal-filtro__modal {
|
||||||
|
transition: transform 0.2s ease, opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro-enter-from,
|
||||||
|
.eli-tabela-modal-filtro-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela-modal-filtro-enter-from .eli-tabela-modal-filtro__modal,
|
||||||
|
.eli-tabela-modal-filtro-leave-to .eli-tabela-modal-filtro__modal {
|
||||||
|
transform: scale(0.96);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
66
src/componentes/EliTabela/EliTabelaSelecao.css
Normal file
66
src/componentes/EliTabela/EliTabelaSelecao.css
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* =========================================
|
||||||
|
* Seleção (Checkboxes)
|
||||||
|
* Extraído de EliTabela.css para manter cada arquivo abaixo de 250 linhas.
|
||||||
|
* ========================================= */
|
||||||
|
.eli-tabela__th--selecao,
|
||||||
|
.eli-tabela__td--selecao {
|
||||||
|
width: 48px;
|
||||||
|
min-width: 48px;
|
||||||
|
max-width: 48px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 8px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__checkbox {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 2px solid rgba(0, 0, 0, 0.54);
|
||||||
|
border-radius: 2px;
|
||||||
|
margin: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
background-color: transparent;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__checkbox:hover {
|
||||||
|
border-color: rgba(0, 0, 0, 0.87);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__checkbox:checked,
|
||||||
|
.eli-tabela__checkbox:indeterminate {
|
||||||
|
background-color: var(--cor-eli-primaria);
|
||||||
|
border-color: var(--cor-eli-primaria);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__checkbox:checked::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 4px;
|
||||||
|
width: 4px;
|
||||||
|
height: 9px;
|
||||||
|
border: solid white;
|
||||||
|
border-width: 0 2px 2px 0;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__checkbox:indeterminate::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
left: 2px;
|
||||||
|
width: 8px;
|
||||||
|
height: 2px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__checkbox:focus-visible {
|
||||||
|
box-shadow: 0 0 0 2px var(--cor-eli-primaria-clara);
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { LucideIcon } from "@lucide/vue"
|
import type { LucideIcon } from "@lucide/vue"
|
||||||
import type { tipoFiltroDeltaColunaTipada } from "p-comuns"
|
import type { tipoCondicaoFiltroDeltaTipado, tipoFiltroDeltaColunaTipada } from "p-comuns"
|
||||||
|
|
||||||
import type { tipoResposta } from "p-respostas"
|
import type { tipoResposta } from "p-respostas"
|
||||||
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas"
|
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas"
|
||||||
|
|
@ -160,9 +160,17 @@ export type tipoEliTabelaConsulta<T> = {
|
||||||
chave: string
|
chave: string
|
||||||
/** Rótulo exibido no select de adicionar filtro */
|
/** Rótulo exibido no select de adicionar filtro */
|
||||||
rotulo: string
|
rotulo: string
|
||||||
/** vai gerar filtro e mescla com os filtros já existentes */
|
/** vai gerar filtro e mescla com os filtros já existentes , id é gerado de forma altomatica para esse local*/
|
||||||
filtro: (valor: unknown) => tipoFiltroDeltaColunaTipada<Extract<keyof T, string>> | undefined
|
filtro: (
|
||||||
|
valor: unknown,
|
||||||
|
) =>
|
||||||
|
| Pick<
|
||||||
|
tipoCondicaoFiltroDeltaTipado<Extract<keyof T, string>>,
|
||||||
|
"coluna" | "operador" | "valor"
|
||||||
|
>
|
||||||
|
| undefined
|
||||||
/** componente de entrada que vai receber o valor para o filtro */
|
/** componente de entrada que vai receber o valor para o filtro */
|
||||||
entrada: ComponenteEntrada
|
entrada: ComponenteEntrada
|
||||||
}[]
|
}[]
|
||||||
}
|
}
|
||||||
|
;("")
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,13 @@ export function useEliTabelaFiltrosAvancados(
|
||||||
.map((f) => {
|
.map((f) => {
|
||||||
const b = base.find((x) => String(x.chave) === String(f.chave))
|
const b = base.find((x) => String(x.chave) === String(f.chave))
|
||||||
if (!b) return null
|
if (!b) return null
|
||||||
return { chave: f.chave, filtro: b.filtro(f.valor) }
|
const condicao = b.filtro(f.valor)
|
||||||
|
if (!condicao) return null
|
||||||
|
return { chave: f.chave, condicao }
|
||||||
})
|
})
|
||||||
.filter(
|
.filter((f): f is { chave: string; condicao: tipoCondicaoFiltroDelta } => f !== null)
|
||||||
(f): f is { chave: string; filtro: tipoFiltroDeltaColunaTipada<string> } =>
|
|
||||||
f !== null && f.filtro !== undefined && f.filtro !== null,
|
if (filtrosIndividuais.length === 0) return []
|
||||||
)
|
|
||||||
|
|
||||||
if (filtrosFormula.value && filtrosIndividuais.length > 1) {
|
if (filtrosFormula.value && filtrosIndividuais.length > 1) {
|
||||||
const condicoesFinais: tipoCondicaoFiltroDelta[] = []
|
const condicoesFinais: tipoCondicaoFiltroDelta[] = []
|
||||||
|
|
@ -62,25 +63,22 @@ export function useEliTabelaFiltrosAvancados(
|
||||||
filtrosIndividuais.forEach(({ chave }, i) => {
|
filtrosIndividuais.forEach(({ chave }, i) => {
|
||||||
formulaFinal = formulaFinal.replace(new RegExp(`\\{${chave}\\}`, "g"), `{c${i + 1}}`)
|
formulaFinal = formulaFinal.replace(new RegExp(`\\{${chave}\\}`, "g"), `{c${i + 1}}`)
|
||||||
})
|
})
|
||||||
let globalIdx = 1
|
filtrosIndividuais.forEach(({ condicao }, i) => {
|
||||||
for (let i = 0; i < filtrosIndividuais.length; i++) {
|
const novoId = `{c${i + 1}}`
|
||||||
const { filtro } = filtrosIndividuais[i]
|
condicoesFinais.push({ ...condicao, id: novoId })
|
||||||
const idMap: Record<string, string> = {}
|
})
|
||||||
for (const cond of filtro.condicoes) {
|
|
||||||
const novoId = `{c${globalIdx++}}`
|
|
||||||
idMap[cond.id] = novoId
|
|
||||||
condicoesFinais.push({ ...cond, id: novoId })
|
|
||||||
}
|
|
||||||
let formulaLocal = filtro.formula
|
|
||||||
for (const [oldId, newId] of Object.entries(idMap)) {
|
|
||||||
formulaLocal = formulaLocal.replace(new RegExp(`\\{${oldId.slice(1, -1)}\\}`, "g"), newId)
|
|
||||||
}
|
|
||||||
const subst = filtro.condicoes.length > 1 ? `(${formulaLocal})` : formulaLocal
|
|
||||||
formulaFinal = formulaFinal.replace(new RegExp(`\\{c${i + 1}\\}`, "g"), subst)
|
|
||||||
}
|
|
||||||
return [{ condicoes: condicoesFinais, formula: formulaFinal }]
|
return [{ condicoes: condicoesFinais, formula: formulaFinal }]
|
||||||
}
|
}
|
||||||
return filtrosIndividuais.map((f) => f.filtro)
|
|
||||||
|
/** Sem fórmula customizada: monta condições com IDs sequenciais e fórmula "E" */
|
||||||
|
const condicoesFinais: tipoCondicaoFiltroDelta[] = filtrosIndividuais.map(
|
||||||
|
({ condicao }, i) => ({
|
||||||
|
...condicao,
|
||||||
|
id: `{c${i + 1}}`,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
const formula = condicoesFinais.map((c) => c.id).join(" E ")
|
||||||
|
return [{ condicoes: condicoesFinais, formula }]
|
||||||
})
|
})
|
||||||
|
|
||||||
function abrirModalFiltro() {
|
function abrirModalFiltro() {
|
||||||
|
|
@ -114,12 +112,82 @@ export function useEliTabelaFiltrosAvancados(
|
||||||
else void carregar()
|
else void carregar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nomesOperadores: Record<string, string> = {
|
||||||
|
"=": "igual a",
|
||||||
|
"!=": "diferente de",
|
||||||
|
">": "maior que",
|
||||||
|
"<": "menor que",
|
||||||
|
">=": "maior ou igual a",
|
||||||
|
"<=": "menor ou igual a",
|
||||||
|
like: "contém",
|
||||||
|
in: "em",
|
||||||
|
"∩": "possui",
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatarFiltroAtivo(entrada: unknown, valor: unknown): string {
|
||||||
|
const [tipo, opcoes] = Array.isArray(entrada)
|
||||||
|
? (entrada as [string, Record<string, unknown>])
|
||||||
|
: [entrada as string, {} as Record<string, unknown>]
|
||||||
|
|
||||||
|
if (tipo === "confirmacao") {
|
||||||
|
const opt = opcoes || {}
|
||||||
|
if (valor === true) return (opt.rotuloAtivo as string) || "Sim"
|
||||||
|
if (valor === false) return (opt.rotuloInativo as string) || "Não"
|
||||||
|
return String(valor)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tipo === "selecao" || tipo === "selecaoMultipla") && typeof opcoes?.itens === "function") {
|
||||||
|
try {
|
||||||
|
const itensResult = opcoes.itens()
|
||||||
|
if (Array.isArray(itensResult)) {
|
||||||
|
const findLabel = (key: string) => {
|
||||||
|
const found = (itensResult as { chave: string; rotulo: string }[]).find(
|
||||||
|
(item) => String(item.chave) === String(key),
|
||||||
|
)
|
||||||
|
return found ? found.rotulo : key
|
||||||
|
}
|
||||||
|
if (Array.isArray(valor)) {
|
||||||
|
return valor.map((v) => findLabel(String(v))).join(", ")
|
||||||
|
}
|
||||||
|
return findLabel(String(valor))
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Fallback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(valor)) {
|
||||||
|
return valor.map(String).join(", ")
|
||||||
|
}
|
||||||
|
return String(valor)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Resumo dos filtros ativos para badge e tooltip do cabecalho */
|
||||||
|
const filtrosAtivosResumo = computed(() => {
|
||||||
|
const base = props.tabela.filtroAvancado ?? []
|
||||||
|
const ativos = (filtrosUi.value ?? []).filter((f) => f && f.chave !== undefined)
|
||||||
|
const rotulos: string[] = []
|
||||||
|
for (const f of ativos) {
|
||||||
|
const b = base.find((x) => String(x.chave) === String(f.chave))
|
||||||
|
if (b) {
|
||||||
|
const condicao = b.filtro(f.valor)
|
||||||
|
if (condicao) {
|
||||||
|
const opStr = nomesOperadores[condicao.operador] || condicao.operador
|
||||||
|
const valStr = formatarFiltroAtivo(b.entrada, condicao.valor)
|
||||||
|
rotulos.push(`${b.rotulo} ${opStr} "${valStr}"`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { quantidade: rotulos.length, rotulos }
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filtrosUi,
|
filtrosUi,
|
||||||
filtrosFormula,
|
filtrosFormula,
|
||||||
modalFiltroAberto,
|
modalFiltroAberto,
|
||||||
exibirFiltroAvancado,
|
exibirFiltroAvancado,
|
||||||
filtrosAvancadosAtivos,
|
filtrosAvancadosAtivos,
|
||||||
|
filtrosAtivosResumo,
|
||||||
abrirModalFiltro,
|
abrirModalFiltro,
|
||||||
fecharModalFiltro,
|
fecharModalFiltro,
|
||||||
limparFiltrosAvancados,
|
limparFiltrosAvancados,
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,16 @@
|
||||||
*
|
*
|
||||||
* Extraído de `EliTabelaModalFiltroAvancado.vue` para manter o componente abaixo de 250 linhas.
|
* Extraído de `EliTabelaModalFiltroAvancado.vue` para manter o componente abaixo de 250 linhas.
|
||||||
*/
|
*/
|
||||||
import { computed, type Ref, ref, watch } from "vue"
|
import { type Component, computed, type Ref, ref, watch } from "vue"
|
||||||
import { EliEntradaDataHora, EliEntradaNumero, EliEntradaTexto } from "../EliEntrada"
|
import {
|
||||||
|
EliEntradaConfirmacao,
|
||||||
|
EliEntradaDataHora,
|
||||||
|
EliEntradaNumero,
|
||||||
|
EliEntradaParagrafo,
|
||||||
|
EliEntradaSelecao,
|
||||||
|
EliEntradaSelecaoMultipla,
|
||||||
|
EliEntradaTexto,
|
||||||
|
} from "../EliEntrada"
|
||||||
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas"
|
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas"
|
||||||
import type { tipoEliTabelaConsulta } from "./types-eli-tabela"
|
import type { tipoEliTabelaConsulta } from "./types-eli-tabela"
|
||||||
|
|
||||||
|
|
@ -97,10 +105,14 @@ export function useFiltroAvancado({
|
||||||
return (filtrosBase.value ?? []).filter((b) => !usadas.has(String(b.chave)))
|
return (filtrosBase.value ?? []).filter((b) => !usadas.has(String(b.chave)))
|
||||||
})
|
})
|
||||||
|
|
||||||
function componenteEntrada(entrada: ComponenteEntrada) {
|
function componenteEntrada(entrada: ComponenteEntrada): Component {
|
||||||
const tipo = entrada?.[0]
|
const tipo = entrada?.[0]
|
||||||
if (tipo === "numero") return EliEntradaNumero
|
if (tipo === "numero") return EliEntradaNumero
|
||||||
if (tipo === "dataHora") return EliEntradaDataHora
|
if (tipo === "dataHora") return EliEntradaDataHora
|
||||||
|
if (tipo === "selecao") return EliEntradaSelecao
|
||||||
|
if (tipo === "selecaoMultipla") return EliEntradaSelecaoMultipla
|
||||||
|
if (tipo === "paragrafo") return EliEntradaParagrafo
|
||||||
|
if (tipo === "confirmacao") return EliEntradaConfirmacao
|
||||||
return EliEntradaTexto
|
return EliEntradaTexto
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,6 +126,9 @@ export function useFiltroAvancado({
|
||||||
|
|
||||||
function valorInicialPorEntrada(entrada: ComponenteEntrada) {
|
function valorInicialPorEntrada(entrada: ComponenteEntrada) {
|
||||||
if (entrada?.[0] === "numero") return null
|
if (entrada?.[0] === "numero") return null
|
||||||
|
if (entrada?.[0] === "selecao") return null
|
||||||
|
if (entrada?.[0] === "selecaoMultipla") return []
|
||||||
|
if (entrada?.[0] === "confirmacao") return false
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,26 @@ import type { tipoCondicaoFiltroDelta, zFiltroDelta } from "p-comuns"
|
||||||
import type z from "zod"
|
import type z from "zod"
|
||||||
import { _dados_empreendedores, type tipoEmpreendedores } from "./dados"
|
import { _dados_empreendedores, type tipoEmpreendedores } from "./dados"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UDF registrada no Alasql para suportar o operador ∩ (interseção).
|
||||||
|
* Verifica se dois arrays possuem ao menos um elemento em comum.
|
||||||
|
*/
|
||||||
|
alasql.fn.arr_intersecta = (coluna: unknown, filtro: unknown): boolean => {
|
||||||
|
if (!Array.isArray(coluna) || !Array.isArray(filtro)) return false
|
||||||
|
return coluna.some((item) => filtro.includes(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UDF universal para o operador "in".
|
||||||
|
* - Coluna escalar: verifica se o valor está na lista de filtro (IN clássico).
|
||||||
|
* - Coluna array: verifica se há interseção entre o array da coluna e a lista de filtro.
|
||||||
|
*/
|
||||||
|
alasql.fn.arr_in = (coluna: unknown, filtro: unknown): boolean => {
|
||||||
|
const lista = Array.isArray(filtro) ? filtro : [filtro]
|
||||||
|
if (Array.isArray(coluna)) return coluna.some((item) => lista.includes(item))
|
||||||
|
return lista.includes(coluna)
|
||||||
|
}
|
||||||
|
|
||||||
const zCondicaoFiltroDeltaParaQuery = ({
|
const zCondicaoFiltroDeltaParaQuery = ({
|
||||||
condicao,
|
condicao,
|
||||||
}: {
|
}: {
|
||||||
|
|
@ -39,14 +59,21 @@ const zCondicaoFiltroDeltaParaQuery = ({
|
||||||
? condicao.valor
|
? condicao.valor
|
||||||
: `%${condicao.valor}%`
|
: `%${condicao.valor}%`
|
||||||
} else if (condicao.operador === "in") {
|
} else if (condicao.operador === "in") {
|
||||||
// Alasql usa @(?) para arrays. Porém, o passo 2 substitui {id} por ?.
|
// UDF universal: funciona tanto para colunas escalares (IN clássico)
|
||||||
// O que resultará em @(?).
|
// quanto para colunas array (interseção).
|
||||||
retorno.sql = `${coluna} IN @(${condicao.id})`
|
retorno.sql = `arr_in(${coluna}, ${condicao.id}) = TRUE`
|
||||||
retorno.parametro[condicao.id] = Array.isArray(condicao.valor)
|
retorno.parametro[condicao.id] = Array.isArray(condicao.valor)
|
||||||
? condicao.valor
|
? condicao.valor
|
||||||
: String(condicao.valor)
|
: String(condicao.valor)
|
||||||
.split(",")
|
.split(",")
|
||||||
.map((s) => s.trim())
|
.map((s) => s.trim())
|
||||||
|
} else if (condicao.operador === "∩") {
|
||||||
|
// Interseção: verifica se o array da coluna contém ao menos um dos valores informados.
|
||||||
|
// Como o Alasql não suporta nativamente comparação de arrays, usamos uma UDF.
|
||||||
|
retorno.sql = `arr_intersecta(${coluna}, ${condicao.id}) = TRUE`
|
||||||
|
retorno.parametro[condicao.id] = Array.isArray(condicao.valor)
|
||||||
|
? condicao.valor
|
||||||
|
: [condicao.valor]
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Operador inválido: ${condicao.operador as string}`)
|
throw new Error(`Operador inválido: ${condicao.operador as string}`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
|
|
||||||
let _id = 0
|
export const zAreaAtuacao = z.enum([
|
||||||
/** Gera um ID incremental único para uso no seed de dados do playground. Não usar em produção. */
|
"mineracao",
|
||||||
export const gerarId = () => `item-${_id++}`
|
"agro",
|
||||||
|
"turismo",
|
||||||
|
"tecnologia",
|
||||||
|
"educacao",
|
||||||
|
"saude",
|
||||||
|
])
|
||||||
|
|
||||||
/** Schema Zod do registro de empreendedor — usado para validação e inferência de tipo no playground. */
|
/** Schema Zod do registro de empreendedor — usado para validação e inferência de tipo no playground. */
|
||||||
export const zEmpreendedores = z.object({
|
export const zEmpreendedores = z.object({
|
||||||
|
|
@ -14,237 +19,21 @@ export const zEmpreendedores = z.object({
|
||||||
telefone: z.string(),
|
telefone: z.string(),
|
||||||
faturamento: z.number(),
|
faturamento: z.number(),
|
||||||
peso_kg: z.number(),
|
peso_kg: z.number(),
|
||||||
areas_atuacao: z.array(
|
ativo: z.boolean(),
|
||||||
z.enum(["mineracao", "agro", "turismo", "tecnologia", "educacao", "saude"]),
|
areas_atuacao: z.array(zAreaAtuacao),
|
||||||
),
|
|
||||||
criado_em: z.string(),
|
criado_em: z.string(),
|
||||||
atualizado_em: z.string(),
|
atualizado_em: z.string(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const AreaAtuacaoDetalhes: Record<z.infer<typeof zAreaAtuacao>, string> = {
|
||||||
|
mineracao: "Mineração",
|
||||||
|
agro: "Agropecuária",
|
||||||
|
turismo: "Turismo",
|
||||||
|
tecnologia: "Tecnologia",
|
||||||
|
educacao: "Educação",
|
||||||
|
saude: "Saúde",
|
||||||
|
}
|
||||||
|
|
||||||
export type tipoEmpreendedores = z.infer<typeof zEmpreendedores>
|
export type tipoEmpreendedores = z.infer<typeof zEmpreendedores>
|
||||||
|
|
||||||
// == SIMULAÇÃO DE API (CRUD) ==
|
export { _dados_empreendedores } from "./dadosSeed"
|
||||||
// Dados isolados (simulando um banco de dados no servidor)
|
|
||||||
export const _dados_empreendedores: tipoEmpreendedores[] = [
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
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",
|
|
||||||
telefone: "(11) 91234-5678",
|
|
||||||
faturamento: 12500.5,
|
|
||||||
peso_kg: 12.4,
|
|
||||||
areas_atuacao: ["agro", "turismo"],
|
|
||||||
criado_em: "2026-01-09T16:15:00Z",
|
|
||||||
atualizado_em: "2026-01-29T15:30:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "João Pereira",
|
|
||||||
empreendimento: "Café Peregrino",
|
|
||||||
documento: "98.765.432/0001-12",
|
|
||||||
email: "contato@cafeperegrino.com",
|
|
||||||
telefone: "(11) 93456-7810",
|
|
||||||
faturamento: 8000,
|
|
||||||
peso_kg: 6.2,
|
|
||||||
areas_atuacao: ["tecnologia", "agro"],
|
|
||||||
criado_em: "2026-01-02T10:00:00-03:00",
|
|
||||||
atualizado_em: "2026-01-20T08:10:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Ana Costa",
|
|
||||||
empreendimento: "Flor de Sal Gastronomia",
|
|
||||||
documento: "45.678.912/0001-55",
|
|
||||||
email: "ana@flordesal.com",
|
|
||||||
telefone: "(21) 99876-5432",
|
|
||||||
faturamento: 3200.75,
|
|
||||||
peso_kg: 4.8,
|
|
||||||
areas_atuacao: ["educacao"],
|
|
||||||
criado_em: "2025-12-10T09:30:00-03:00",
|
|
||||||
atualizado_em: "2026-01-15T19:20:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Rafael Lima",
|
|
||||||
empreendimento: "Tech Agro Solutions",
|
|
||||||
documento: "07.654.321/0001-00",
|
|
||||||
email: "rafael@techagro.com",
|
|
||||||
telefone: "(31) 94567-8899",
|
|
||||||
faturamento: 15999.9,
|
|
||||||
peso_kg: 9.1,
|
|
||||||
areas_atuacao: ["tecnologia"],
|
|
||||||
criado_em: "2026-01-12T12:00:00-03:00",
|
|
||||||
atualizado_em: "2026-01-28T11:00:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Juliana Torres",
|
|
||||||
empreendimento: "Torres Moda Sustentável",
|
|
||||||
documento: "33.210.987/0001-44",
|
|
||||||
email: "juliana@torresmoda.com",
|
|
||||||
telefone: "(71) 97766-5544",
|
|
||||||
faturamento: 4500,
|
|
||||||
peso_kg: 3.3,
|
|
||||||
areas_atuacao: ["turismo", "agro"],
|
|
||||||
criado_em: "2026-01-01T00:00:00Z",
|
|
||||||
atualizado_em: "2026-01-10T13:45:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Marcos Vieira",
|
|
||||||
empreendimento: "Padaria Pão Quentinho",
|
|
||||||
documento: "21.109.876/0001-32",
|
|
||||||
email: "marcos@paoquentinho.com",
|
|
||||||
telefone: "(48) 99654-3210",
|
|
||||||
faturamento: 2200.4,
|
|
||||||
peso_kg: 15.7,
|
|
||||||
areas_atuacao: ["saude"],
|
|
||||||
criado_em: "2026-01-05T07:25:00-03:00",
|
|
||||||
atualizado_em: "2026-01-23T20:15:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Bianca Rocha",
|
|
||||||
empreendimento: "Studio Beleza em Casa",
|
|
||||||
documento: "54.321.098/0001-21",
|
|
||||||
email: "contato@belezaemcasa.com",
|
|
||||||
telefone: "(85) 98877-1122",
|
|
||||||
faturamento: 990,
|
|
||||||
peso_kg: 1.9,
|
|
||||||
areas_atuacao: ["agro", "tecnologia"],
|
|
||||||
criado_em: "2026-01-03T14:00:00-03:00",
|
|
||||||
atualizado_em: "2026-01-29T09:00:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Caio Albuquerque",
|
|
||||||
empreendimento: "Albuquerque Engenharia Verde",
|
|
||||||
documento: "65.432.109/0001-09",
|
|
||||||
email: "caio@engenhariaverde.com",
|
|
||||||
telefone: "(61) 98123-4567",
|
|
||||||
faturamento: 100000,
|
|
||||||
peso_kg: 21.3,
|
|
||||||
areas_atuacao: ["mineracao"],
|
|
||||||
criado_em: "2025-11-18T16:10:00-03:00",
|
|
||||||
atualizado_em: "2026-01-25T10:40:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Fernanda Almeida",
|
|
||||||
empreendimento: "Faz Bem Produtos Naturais",
|
|
||||||
documento: "87.654.210/0001-98",
|
|
||||||
email: "fernanda@fazbem.com",
|
|
||||||
telefone: "(41) 99777-6655",
|
|
||||||
faturamento: 5600.2,
|
|
||||||
peso_kg: 8.6,
|
|
||||||
areas_atuacao: ["mineracao", "turismo"],
|
|
||||||
criado_em: "2026-01-08T12:12:00-03:00",
|
|
||||||
atualizado_em: "2026-01-21T17:55:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Gabriel Martins",
|
|
||||||
empreendimento: "Martins Tech Repair",
|
|
||||||
documento: "19.876.543/0001-76",
|
|
||||||
email: "suporte@martinstech.com",
|
|
||||||
telefone: "(19) 98888-9090",
|
|
||||||
faturamento: 7550,
|
|
||||||
peso_kg: 7.7,
|
|
||||||
areas_atuacao: ["mineracao", "turismo"],
|
|
||||||
criado_em: "2026-01-11T11:00:00-03:00",
|
|
||||||
atualizado_em: "2026-01-18T11:30:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Helena Duarte",
|
|
||||||
empreendimento: "Ateliê Costura Criativa",
|
|
||||||
documento: "23.456.789/0001-65",
|
|
||||||
email: "helena@costuracriativa.com",
|
|
||||||
telefone: "(51) 98765-4433",
|
|
||||||
faturamento: 2700,
|
|
||||||
peso_kg: 2.5,
|
|
||||||
areas_atuacao: ["turismo", "mineracao"],
|
|
||||||
criado_em: "2026-01-07T08:00:00-03:00",
|
|
||||||
atualizado_em: "2026-01-16T14:10:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Igor Santos",
|
|
||||||
empreendimento: "Santos Consultoria Financeira",
|
|
||||||
documento: "43.219.876/0001-54",
|
|
||||||
email: "igor@santosconsultoria.com",
|
|
||||||
telefone: "(31) 99332-1100",
|
|
||||||
faturamento: 12000,
|
|
||||||
peso_kg: 5.4,
|
|
||||||
areas_atuacao: ["saude"],
|
|
||||||
criado_em: "2026-01-06T10:30:00-03:00",
|
|
||||||
atualizado_em: "2026-01-22T18:30:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Jéssica Nunes",
|
|
||||||
empreendimento: "Nunes Eventos & Decoração",
|
|
||||||
documento: "09.876.543/0001-33",
|
|
||||||
email: "jessica@nunesdecora.com",
|
|
||||||
telefone: "(62) 99922-3344",
|
|
||||||
faturamento: 3300.1,
|
|
||||||
peso_kg: 4.1,
|
|
||||||
areas_atuacao: ["turismo"],
|
|
||||||
criado_em: "2026-01-04T13:30:00-03:00",
|
|
||||||
atualizado_em: "2026-01-26T09:20:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Leonardo Prado",
|
|
||||||
empreendimento: "Prado Bike Courier",
|
|
||||||
documento: "72.345.098/0001-27",
|
|
||||||
email: "contato@pradobike.com",
|
|
||||||
telefone: "(47) 98444-6677",
|
|
||||||
faturamento: 4100,
|
|
||||||
peso_kg: 6.8,
|
|
||||||
areas_atuacao: ["mineracao"],
|
|
||||||
criado_em: "2026-01-02T18:40:00-03:00",
|
|
||||||
atualizado_em: "2026-01-27T12:00:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Marina Lopes",
|
|
||||||
empreendimento: "Lopes Design Digital",
|
|
||||||
documento: "56.789.012/0001-11",
|
|
||||||
email: "marina@lopesdesign.com",
|
|
||||||
telefone: "(27) 99911-2233",
|
|
||||||
faturamento: 2100,
|
|
||||||
peso_kg: 3.7,
|
|
||||||
areas_atuacao: ["agro"],
|
|
||||||
criado_em: "2026-01-09T09:00:00-03:00",
|
|
||||||
atualizado_em: "2026-01-19T15:35:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Nicolas Teixeira",
|
|
||||||
empreendimento: "QualiVida Fitness",
|
|
||||||
documento: "34.567.890/0001-02",
|
|
||||||
email: "nicolas@qualivida.com",
|
|
||||||
telefone: "(92) 99456-7788",
|
|
||||||
faturamento: 8600.9,
|
|
||||||
peso_kg: 11.2,
|
|
||||||
areas_atuacao: ["agro", "saude"],
|
|
||||||
criado_em: "2026-01-12T19:15:00-03:00",
|
|
||||||
atualizado_em: "2026-01-29T10:50:00-03:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
codigo: gerarId(),
|
|
||||||
empreendedor: "Olívia Azevedo",
|
|
||||||
empreendimento: "Azevedo Pet Care",
|
|
||||||
documento: "88.901.234/0001-45",
|
|
||||||
email: "olivia@petcare.com",
|
|
||||||
telefone: "(16) 99788-6655",
|
|
||||||
faturamento: 1900.3,
|
|
||||||
peso_kg: 2.2,
|
|
||||||
areas_atuacao: ["agro"],
|
|
||||||
criado_em: "2026-01-10T15:00:00-03:00",
|
|
||||||
atualizado_em: "2026-01-14T16:00:00-03:00",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
|
||||||
249
src/playground/api_simulador/dadosSeed.ts
Normal file
249
src/playground/api_simulador/dadosSeed.ts
Normal file
|
|
@ -0,0 +1,249 @@
|
||||||
|
/** dadosSeed — dados de seed (mock) para o playground da EliTabela. */
|
||||||
|
import type { tipoEmpreendedores } from "./dados"
|
||||||
|
|
||||||
|
let _id = 0
|
||||||
|
/** Gera um ID incremental único para uso no seed de dados do playground. Não usar em produção. */
|
||||||
|
export const gerarId = () => `item-${_id++}`
|
||||||
|
|
||||||
|
// == SIMULAÇÃO DE API (CRUD) ==
|
||||||
|
// Dados isolados (simulando um banco de dados no servidor)
|
||||||
|
export const _dados_empreendedores: tipoEmpreendedores[] = [
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
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",
|
||||||
|
telefone: "(11) 91234-5678",
|
||||||
|
faturamento: 12500.5,
|
||||||
|
peso_kg: 12.4,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["agro", "turismo"],
|
||||||
|
criado_em: "2026-01-09T16:15:00Z",
|
||||||
|
atualizado_em: "2026-01-29T15:30:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "João Pereira",
|
||||||
|
empreendimento: "Café Peregrino",
|
||||||
|
documento: "98.765.432/0001-12",
|
||||||
|
email: "contato@cafeperegrino.com",
|
||||||
|
telefone: "(11) 93456-7810",
|
||||||
|
faturamento: 8000,
|
||||||
|
peso_kg: 6.2,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["tecnologia", "agro"],
|
||||||
|
criado_em: "2026-01-02T10:00:00-03:00",
|
||||||
|
atualizado_em: "2026-01-20T08:10:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Ana Costa",
|
||||||
|
empreendimento: "Flor de Sal Gastronomia",
|
||||||
|
documento: "45.678.912/0001-55",
|
||||||
|
email: "ana@flordesal.com",
|
||||||
|
telefone: "(21) 99876-5432",
|
||||||
|
faturamento: 3200.75,
|
||||||
|
peso_kg: 4.8,
|
||||||
|
ativo: false,
|
||||||
|
areas_atuacao: ["educacao"],
|
||||||
|
criado_em: "2025-12-10T09:30:00-03:00",
|
||||||
|
atualizado_em: "2026-01-15T19:20:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Rafael Lima",
|
||||||
|
empreendimento: "Tech Agro Solutions",
|
||||||
|
documento: "07.654.321/0001-00",
|
||||||
|
email: "rafael@techagro.com",
|
||||||
|
telefone: "(31) 94567-8899",
|
||||||
|
faturamento: 15999.9,
|
||||||
|
peso_kg: 9.1,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["tecnologia"],
|
||||||
|
criado_em: "2026-01-12T12:00:00-03:00",
|
||||||
|
atualizado_em: "2026-01-28T11:00:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Juliana Torres",
|
||||||
|
empreendimento: "Torres Moda Sustentável",
|
||||||
|
documento: "33.210.987/0001-44",
|
||||||
|
email: "juliana@torresmoda.com",
|
||||||
|
telefone: "(71) 97766-5544",
|
||||||
|
faturamento: 4500,
|
||||||
|
peso_kg: 3.3,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["turismo", "agro"],
|
||||||
|
criado_em: "2026-01-01T00:00:00Z",
|
||||||
|
atualizado_em: "2026-01-10T13:45:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Marcos Vieira",
|
||||||
|
empreendimento: "Padaria Pão Quentinho",
|
||||||
|
documento: "21.109.876/0001-32",
|
||||||
|
email: "marcos@paoquentinho.com",
|
||||||
|
telefone: "(48) 99654-3210",
|
||||||
|
faturamento: 2200.4,
|
||||||
|
peso_kg: 15.7,
|
||||||
|
ativo: false,
|
||||||
|
areas_atuacao: ["saude"],
|
||||||
|
criado_em: "2026-01-05T07:25:00-03:00",
|
||||||
|
atualizado_em: "2026-01-23T20:15:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Bianca Rocha",
|
||||||
|
empreendimento: "Studio Beleza em Casa",
|
||||||
|
documento: "54.321.098/0001-21",
|
||||||
|
email: "contato@belezaemcasa.com",
|
||||||
|
telefone: "(85) 98877-1122",
|
||||||
|
faturamento: 990,
|
||||||
|
peso_kg: 1.9,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["agro", "tecnologia"],
|
||||||
|
criado_em: "2026-01-03T14:00:00-03:00",
|
||||||
|
atualizado_em: "2026-01-29T09:00:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Caio Albuquerque",
|
||||||
|
empreendimento: "Albuquerque Engenharia Verde",
|
||||||
|
documento: "65.432.109/0001-09",
|
||||||
|
email: "caio@engenhariaverde.com",
|
||||||
|
telefone: "(61) 98123-4567",
|
||||||
|
faturamento: 100000,
|
||||||
|
peso_kg: 21.3,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["mineracao"],
|
||||||
|
criado_em: "2025-11-18T16:10:00-03:00",
|
||||||
|
atualizado_em: "2026-01-25T10:40:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Fernanda Almeida",
|
||||||
|
empreendimento: "Faz Bem Produtos Naturais",
|
||||||
|
documento: "87.654.210/0001-98",
|
||||||
|
email: "fernanda@fazbem.com",
|
||||||
|
telefone: "(41) 99777-6655",
|
||||||
|
faturamento: 5600.2,
|
||||||
|
peso_kg: 8.6,
|
||||||
|
ativo: false,
|
||||||
|
areas_atuacao: ["mineracao", "turismo"],
|
||||||
|
criado_em: "2026-01-08T12:12:00-03:00",
|
||||||
|
atualizado_em: "2026-01-21T17:55:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Gabriel Martins",
|
||||||
|
empreendimento: "Martins Tech Repair",
|
||||||
|
documento: "19.876.543/0001-76",
|
||||||
|
email: "suporte@martinstech.com",
|
||||||
|
telefone: "(19) 98888-9090",
|
||||||
|
faturamento: 7550,
|
||||||
|
peso_kg: 7.7,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["mineracao", "turismo"],
|
||||||
|
criado_em: "2026-01-11T11:00:00-03:00",
|
||||||
|
atualizado_em: "2026-01-18T11:30:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Helena Duarte",
|
||||||
|
empreendimento: "Ateliê Costura Criativa",
|
||||||
|
documento: "23.456.789/0001-65",
|
||||||
|
email: "helena@costuracriativa.com",
|
||||||
|
telefone: "(51) 98765-4433",
|
||||||
|
faturamento: 2700,
|
||||||
|
peso_kg: 2.5,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["turismo", "mineracao"],
|
||||||
|
criado_em: "2026-01-07T08:00:00-03:00",
|
||||||
|
atualizado_em: "2026-01-16T14:10:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Igor Santos",
|
||||||
|
empreendimento: "Santos Consultoria Financeira",
|
||||||
|
documento: "43.219.876/0001-54",
|
||||||
|
email: "igor@santosconsultoria.com",
|
||||||
|
telefone: "(31) 99332-1100",
|
||||||
|
faturamento: 12000,
|
||||||
|
peso_kg: 5.4,
|
||||||
|
ativo: false,
|
||||||
|
areas_atuacao: ["saude"],
|
||||||
|
criado_em: "2026-01-06T10:30:00-03:00",
|
||||||
|
atualizado_em: "2026-01-22T18:30:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Jéssica Nunes",
|
||||||
|
empreendimento: "Nunes Eventos & Decoração",
|
||||||
|
documento: "09.876.543/0001-33",
|
||||||
|
email: "jessica@nunesdecora.com",
|
||||||
|
telefone: "(62) 99922-3344",
|
||||||
|
faturamento: 3300.1,
|
||||||
|
peso_kg: 4.1,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["turismo"],
|
||||||
|
criado_em: "2026-01-04T13:30:00-03:00",
|
||||||
|
atualizado_em: "2026-01-26T09:20:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Leonardo Prado",
|
||||||
|
empreendimento: "Prado Bike Courier",
|
||||||
|
documento: "72.345.098/0001-27",
|
||||||
|
email: "contato@pradobike.com",
|
||||||
|
telefone: "(47) 98444-6677",
|
||||||
|
faturamento: 4100,
|
||||||
|
peso_kg: 6.8,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["mineracao"],
|
||||||
|
criado_em: "2026-01-02T18:40:00-03:00",
|
||||||
|
atualizado_em: "2026-01-27T12:00:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Marina Lopes",
|
||||||
|
empreendimento: "Lopes Design Digital",
|
||||||
|
documento: "56.789.012/0001-11",
|
||||||
|
email: "marina@lopesdesign.com",
|
||||||
|
telefone: "(27) 99911-2233",
|
||||||
|
faturamento: 2100,
|
||||||
|
peso_kg: 3.7,
|
||||||
|
ativo: false,
|
||||||
|
areas_atuacao: ["agro"],
|
||||||
|
criado_em: "2026-01-09T09:00:00-03:00",
|
||||||
|
atualizado_em: "2026-01-19T15:35:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Nicolas Teixeira",
|
||||||
|
empreendimento: "QualiVida Fitness",
|
||||||
|
documento: "34.567.890/0001-02",
|
||||||
|
email: "nicolas@qualivida.com",
|
||||||
|
telefone: "(92) 99456-7788",
|
||||||
|
faturamento: 8600.9,
|
||||||
|
peso_kg: 11.2,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["agro", "saude"],
|
||||||
|
criado_em: "2026-01-12T19:15:00-03:00",
|
||||||
|
atualizado_em: "2026-01-29T10:50:00-03:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
codigo: gerarId(),
|
||||||
|
empreendedor: "Olívia Azevedo",
|
||||||
|
empreendimento: "Azevedo Pet Care",
|
||||||
|
documento: "88.901.234/0001-45",
|
||||||
|
email: "olivia@petcare.com",
|
||||||
|
telefone: "(16) 99788-6655",
|
||||||
|
faturamento: 1900.3,
|
||||||
|
peso_kg: 2.2,
|
||||||
|
ativo: true,
|
||||||
|
areas_atuacao: ["agro"],
|
||||||
|
criado_em: "2026-01-10T15:00:00-03:00",
|
||||||
|
atualizado_em: "2026-01-14T16:00:00-03:00",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
@ -39,6 +39,7 @@ const api_criar: tipoFuncaoApiSimulacao<"criar"> = async (dados) => {
|
||||||
telefone: dados.telefone || "(00) 0000-0000",
|
telefone: dados.telefone || "(00) 0000-0000",
|
||||||
faturamento: dados.faturamento || 0,
|
faturamento: dados.faturamento || 0,
|
||||||
peso_kg: dados.peso_kg || 0,
|
peso_kg: dados.peso_kg || 0,
|
||||||
|
ativo: dados.ativo ?? true,
|
||||||
areas_atuacao: dados.areas_atuacao || [],
|
areas_atuacao: dados.areas_atuacao || [],
|
||||||
criado_em: new Date().toISOString(),
|
criado_em: new Date().toISOString(),
|
||||||
atualizado_em: new Date().toISOString(),
|
atualizado_em: new Date().toISOString(),
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ export function useTabelaPlayground() {
|
||||||
telefone: "",
|
telefone: "",
|
||||||
faturamento: 0,
|
faturamento: 0,
|
||||||
peso_kg: 0,
|
peso_kg: 0,
|
||||||
|
ativo: true,
|
||||||
areas_atuacao: [],
|
areas_atuacao: [],
|
||||||
})
|
})
|
||||||
const erroCadastro = ref<string | undefined>(undefined)
|
const erroCadastro = ref<string | undefined>(undefined)
|
||||||
|
|
@ -54,6 +55,7 @@ export function useTabelaPlayground() {
|
||||||
telefone: "",
|
telefone: "",
|
||||||
faturamento: 0,
|
faturamento: 0,
|
||||||
peso_kg: 0,
|
peso_kg: 0,
|
||||||
|
ativo: true,
|
||||||
areas_atuacao: [],
|
areas_atuacao: [],
|
||||||
}
|
}
|
||||||
erroCadastro.value = undefined
|
erroCadastro.value = undefined
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,22 @@
|
||||||
* @see useTabelaPlayground.ts — composable que consome estas configurações
|
* @see useTabelaPlayground.ts — composable que consome estas configurações
|
||||||
*/
|
*/
|
||||||
import { BadgeCheck, Eye, Pencil, Trash2 } from "@lucide/vue"
|
import { BadgeCheck, Eye, Pencil, Trash2 } from "@lucide/vue"
|
||||||
import { iniciarFiltroDelta } from "p-comuns"
|
|
||||||
|
|
||||||
import type { ComponenteEntrada } from "@/componentes/EliEntrada/tiposEntradas"
|
import type { ComponenteEntrada } from "@/componentes/EliEntrada/tiposEntradas"
|
||||||
import type { tipoEliTabelaConsulta } from "@/componentes/EliTabela"
|
import type { tipoEliTabelaConsulta } from "@/componentes/EliTabela"
|
||||||
import { celulaTabela } from "@/componentes/EliTabela"
|
import { celulaTabela } from "@/componentes/EliTabela"
|
||||||
|
|
||||||
import type { tipoEmpreendedores } from "./api_simulador/dados"
|
import { AreaAtuacaoDetalhes, type tipoEmpreendedores } from "./api_simulador/dados"
|
||||||
|
|
||||||
const { criarFiltroDelta } = iniciarFiltroDelta<Extract<keyof tipoEmpreendedores, string>>()
|
/** Mapeamento de cor por área de atuação para uso nos chips da tabela */
|
||||||
|
const corAreaAtuacao: Record<tipoEmpreendedores["areas_atuacao"][number], string> = {
|
||||||
|
mineracao: "#78909C",
|
||||||
|
agro: "#4CAF50",
|
||||||
|
turismo: "#FF9800",
|
||||||
|
tecnologia: "#2196F3",
|
||||||
|
educacao: "#9C27B0",
|
||||||
|
saude: "#E91E63",
|
||||||
|
}
|
||||||
|
|
||||||
/** Ações por linha usadas nas 3 instâncias de tabela do playground */
|
/** Ações por linha usadas nas 3 instâncias de tabela do playground */
|
||||||
export function criarAcoesLinha(
|
export function criarAcoesLinha(
|
||||||
|
|
@ -79,6 +86,17 @@ export const colunasTabela: tipoEliTabelaConsulta<tipoEmpreendedores>["colunas"]
|
||||||
coluna_ordem: "telefone",
|
coluna_ordem: "telefone",
|
||||||
visivel: true,
|
visivel: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
rotulo: "Áreas de Atuação",
|
||||||
|
celula: (l) =>
|
||||||
|
celulaTabela("tags", {
|
||||||
|
opcoes: l.areas_atuacao.map((area) => ({
|
||||||
|
rotulo: AreaAtuacaoDetalhes[area],
|
||||||
|
cor: corAreaAtuacao[area],
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
visivel: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
rotulo: "Faturamento",
|
rotulo: "Faturamento",
|
||||||
celula: (l) =>
|
celula: (l) =>
|
||||||
|
|
@ -134,12 +152,7 @@ export const filtrosAvancados: tipoEliTabelaConsulta<tipoEmpreendedores>["filtro
|
||||||
rotulo: "Empreendedor",
|
rotulo: "Empreendedor",
|
||||||
filtro: (valor: unknown) => {
|
filtro: (valor: unknown) => {
|
||||||
if (!valor) return undefined
|
if (!valor) return undefined
|
||||||
return criarFiltroDelta({
|
return { coluna: "empreendedor", operador: "like" as const, valor: valor as string }
|
||||||
condicoes: [
|
|
||||||
{ id: "{c1}", coluna: "empreendedor", operador: "like", valor: valor as string },
|
|
||||||
],
|
|
||||||
formula: "{c1}",
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
entrada: ["texto", { rotulo: "Empreendedor" }] as ComponenteEntrada,
|
entrada: ["texto", { rotulo: "Empreendedor" }] as ComponenteEntrada,
|
||||||
},
|
},
|
||||||
|
|
@ -148,12 +161,7 @@ export const filtrosAvancados: tipoEliTabelaConsulta<tipoEmpreendedores>["filtro
|
||||||
rotulo: "Empreendimento",
|
rotulo: "Empreendimento",
|
||||||
filtro: (valor: unknown) => {
|
filtro: (valor: unknown) => {
|
||||||
if (!valor) return undefined
|
if (!valor) return undefined
|
||||||
return criarFiltroDelta({
|
return { coluna: "empreendimento", operador: "like" as const, valor: valor as string }
|
||||||
condicoes: [
|
|
||||||
{ id: "{c1}", coluna: "empreendimento", operador: "like", valor: valor as string },
|
|
||||||
],
|
|
||||||
formula: "{c1}",
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
entrada: ["texto", { rotulo: "Empreendimento" }] as ComponenteEntrada,
|
entrada: ["texto", { rotulo: "Empreendimento" }] as ComponenteEntrada,
|
||||||
},
|
},
|
||||||
|
|
@ -162,10 +170,7 @@ export const filtrosAvancados: tipoEliTabelaConsulta<tipoEmpreendedores>["filtro
|
||||||
rotulo: "Documento",
|
rotulo: "Documento",
|
||||||
filtro: (valor: unknown) => {
|
filtro: (valor: unknown) => {
|
||||||
if (!valor) return undefined
|
if (!valor) return undefined
|
||||||
return criarFiltroDelta({
|
return { coluna: "documento", operador: "like" as const, valor: valor as string }
|
||||||
condicoes: [{ id: "{c1}", coluna: "documento", operador: "like", valor: valor as string }],
|
|
||||||
formula: "{c1}",
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
entrada: ["texto", { rotulo: "Documento", formato: "cpfCnpj" }] as ComponenteEntrada,
|
entrada: ["texto", { rotulo: "Documento", formato: "cpfCnpj" }] as ComponenteEntrada,
|
||||||
},
|
},
|
||||||
|
|
@ -174,13 +179,65 @@ export const filtrosAvancados: tipoEliTabelaConsulta<tipoEmpreendedores>["filtro
|
||||||
rotulo: "E-mail",
|
rotulo: "E-mail",
|
||||||
filtro: (valor: unknown) => {
|
filtro: (valor: unknown) => {
|
||||||
if (!valor) return undefined
|
if (!valor) return undefined
|
||||||
return criarFiltroDelta({
|
return { coluna: "email", operador: "like" as const, valor: valor as string }
|
||||||
condicoes: [{ id: "{c1}", coluna: "email", operador: "like", valor: valor as string }],
|
|
||||||
formula: "{c1}",
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
entrada: ["texto", { rotulo: "E-mail", formato: "email" }] as ComponenteEntrada,
|
entrada: ["texto", { rotulo: "E-mail", formato: "email" }] as ComponenteEntrada,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
chave: "ativo",
|
||||||
|
rotulo: "Ativo",
|
||||||
|
filtro: (valor: unknown) => {
|
||||||
|
return { coluna: "ativo", operador: "=" as const, valor: valor as boolean }
|
||||||
|
},
|
||||||
|
entrada: [
|
||||||
|
"confirmacao",
|
||||||
|
{ rotulo: "Ativo", rotuloAtivo: "Apenas ativos", rotuloInativo: "Apenas inativos" },
|
||||||
|
] as ComponenteEntrada,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
chave: "faturamento_min",
|
||||||
|
rotulo: "Faturamento mínimo",
|
||||||
|
filtro: (valor: unknown) => {
|
||||||
|
if (valor === null || valor === undefined) return undefined
|
||||||
|
return { coluna: "faturamento", operador: ">=" as const, valor: valor as number }
|
||||||
|
},
|
||||||
|
entrada: ["numero", { rotulo: "Faturamento mínimo (R$)" }] as ComponenteEntrada,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
chave: "areas_atuacao",
|
||||||
|
rotulo: "Área de Atuação",
|
||||||
|
filtro: (valor: unknown) => {
|
||||||
|
const arr = valor as string[]
|
||||||
|
if (!arr.length) return undefined
|
||||||
|
return { coluna: "areas_atuacao", operador: "∩" as const, valor: arr }
|
||||||
|
},
|
||||||
|
entrada: [
|
||||||
|
"selecaoMultipla",
|
||||||
|
{
|
||||||
|
rotulo: "Área de Atuação",
|
||||||
|
limpavel: true,
|
||||||
|
itens: () =>
|
||||||
|
Object.entries(AreaAtuacaoDetalhes).map(([chave, rotulo]) => ({ chave, rotulo })),
|
||||||
|
},
|
||||||
|
] as ComponenteEntrada,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
chave: "areas_atuacao2",
|
||||||
|
rotulo: "Área de Atuação (2)",
|
||||||
|
filtro: (valor: unknown) => {
|
||||||
|
if (!valor) return undefined
|
||||||
|
return { coluna: "areas_atuacao", operador: "in" as const, valor }
|
||||||
|
},
|
||||||
|
entrada: [
|
||||||
|
"selecao",
|
||||||
|
{
|
||||||
|
rotulo: "Área de Atuação",
|
||||||
|
limpavel: true,
|
||||||
|
itens: () =>
|
||||||
|
Object.entries(AreaAtuacaoDetalhes).map(([chave, rotulo]) => ({ chave, rotulo })),
|
||||||
|
},
|
||||||
|
] as ComponenteEntrada,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue