Skip to content

Mad Framework 5.151.1

Choose a tag to compare

@matheusagnes matheusagnes released this 10 Oct 08:32
· 39 commits to main since this release

Novidades

  • Segurança: quando a verificação em duas etapas de uma conta é bloqueada por códigos errados, o dono recebe um e-mail na hora (um por bloqueio), com a data, o endereço de origem e a orientação de trocar a senha. O modelo do e-mail fica em Preferências › E-mail › Bloqueio do 2FA; sem modelo próprio, sai no idioma da conta.
  • Usuários: nova ação Liberar verificação em duas etapas na lista de usuários, para o administrador desbloquear a conta antes do prazo de 15 minutos.
  • Formulários: a cortina lateral e o modal podem pedir confirmação antes de fechar com Esc, no X ou no clique fora quando há alteração não salva. Ligue com protected static bool $confirmDiscard = true; na tela, ou com confirm-close em <mad-drawer> e <mad-modal>. Salvar, Voltar e Cancelar continuam fechando direto.
  • Campos de exibição: <mad-display-field> ganha model, display e key: quando o valor é a chave de outra tabela, o campo mostra o nome do registro, como o combo mostra (um valor ou vários, inclusive de seleção múltipla).
  • App gerado: os trechos de Header & Footer Tags das Propriedades do projeto passam a sair em todas as páginas do app: o do cabeçalho no fim do <head> e o do rodapé antes do </body>, nas telas do painel, no login e no site público.
  • Listagens: a grade pinta a linha, o cartão ou só uma célula conforme o valor do registro, com <mad-row-highlights> e uma <mad-row-highlight> por regra (when-field/when-op/when-value ou display-condition, tone perigo/aviso/sucesso/info ou color, cell para só a célula). Vale a primeira regra que casar; a exportação não leva cor.
  • Listagens: a condição das ações da linha (when-op) aceita também maior e menor (gt, gte, lt, lte), comparando números como números.
  • Temas: cada unidade (empresa) pode ter o seu tema. No cadastro de Unidade, a seção Aparência escolhe o tema e se o usuário pode trocá-lo; quem entra na unidade já vê o tema dela, sem piscar o padrão.
  • Temas: com a troca liberada, a escolha de tema de cada usuário vale só para a unidade em que ele a fez; com a troca travada, o seletor de temas some e vale sempre o tema da unidade.
  • Temas: logo do cabeçalho e logos do login separados para o modo claro e o escuro. Ao alternar o sol/lua, o logo troca junto; tema com um logo só continua como antes.
  • Login: a tela de login abre com o último tema usado naquele navegador e respeita o modo claro ou escuro do tema.

Melhorias

  • Formulário: a Coluna inicial da Coluna (start do <mad-form-grid-item>) passa a valer: a Coluna começa naquela coluna da Linha e ocupa o número de colunas do span. Sem ela, nada muda; no celular as Colunas continuam empilhadas.

Correções

  • Formulários: campo marcado como Obrigatório deixava salvar em branco. Agora o Salvar segura o envio e avisa no próprio campo; se ele pode ficar vazio, desligue Obrigatório. Republique o projeto para aplicar.
  • Formulários: Obrigatório quando (required-when) não mostrava o asterisco nem impedia salvar com o campo vazio. Agora faz as duas coisas enquanto a condição valer. Republique o projeto para aplicar.
  • Formulários: campo desabilitado por Desabilitar quando (disabled-when) ainda enviava e gravava o valor ao salvar. Agora não envia. Republique o projeto para aplicar.
  • Formulários: Somente leitura quando (readonly-when) passa a travar também seleção, combo, caixa de marcar, rádio e interruptor, não só campos de texto. Republique o projeto para aplicar.
  • Formulários: num combo que depende de outro campo e tem Preenchimento de campos, escolher o valor do campo de cima (o Cliente) apagava o texto que o usuário já tinha digitado no campo preenchido (o Título). Agora o texto digitado é mantido; ao esvaziar o combo, só é desfeito o que o próprio preenchimento escreveu e ninguém alterou. Republique o projeto para aplicar.
  • Formulários: no combo com Sem resultados → Cadastrar novo, o nome digitado na busca não vinha preenchido no cadastro aberto na cortina lateral. Agora vem. Republique o projeto para aplicar.
  • Formulários: num combo cuja lista é trocada pelo código da tela (setItems no On Change de outro campo), a lista filtrada voltava a mostrar todas as opções logo depois de carregar, quando a tela era redesenhada. Agora a lista filtrada é mantida, e o On Change do combo não é mais chamado quando só a lista muda e o valor escolhido continua o mesmo. Republique o projeto para aplicar.
  • Formulários: no seletor de data e hora, o On Change do campo era chamado várias vezes enquanto a pessoa escolhia dia, hora e minuto, a primeira com a hora ainda zerada. Agora é chamado uma vez, quando a escolha é confirmada (Aplicar, Agora, Limpar ou clique fora), e só se o valor mudou. Republique o projeto para aplicar.
  • Formulários: passar o foco muito rápido de um <mad-numeric-field> para outro (ou entre células numéricas da Lista de itens) podia travar a aba do navegador. O texto continua selecionado ao entrar no campo.
  • Formulários: num campo de arquivo ou de imagem guardado no banco (storage="db") com o mesmo registro aberto em duas abas, a aba que tinha enviado um arquivo o gravava de novo a cada Salvar, por cima do que a outra aba tinha trocado, e a aba que tinha removido o arquivo apagava o que a outra enviou depois. Agora cada Salvar só mexe no arquivo quando você o troca ou o remove naquela tela, e avisa quando o arquivo já foi trocado em outra tela. Republique o projeto para aplicar.
  • Formulários: corrigida a acentuação de avisos que o usuário lê no app: CEP incompleto ("Informe 8 dígitos."), falha no envio de arquivo, arquivo sem pré-visualização, câmera da leitura de código, busca da documentação e a opção "Não" do <mad-radio-field boolean>. Republique o projeto para aplicar.
  • Formulários: um <script> escrito dentro de uma tela aberta em cortina lateral (por exemplo, o JS de um componente próprio incluído no formulário) não executava, e um <script src> perdia o endereço ao navegar entre telas. Agora os dois executam. Republique o projeto para aplicar.
  • Formulários: abrir pelo endereço a edição de um registro que não existe, ou que a pessoa não pode ver (o endereço do botão Editar da listagem), mostrava uma tela de erro técnica. Agora mostra o aviso "Registro não encontrado", com Voltar, ou Fechar na cortina lateral.
  • Formulários: com Após salvar em Ir para outra página (ou Tela inteira), o aviso de que o registro foi salvo nunca aparecia. Agora aparece na página de destino. Republique o projeto para aplicar.
  • Formulários: depois de corrigir um campo recusado e salvar com sucesso, a mensagem de erro continuava embaixo do campo até recarregar a tela. Agora ela sai no Salvar que passa.
  • Formulários: quando o Salvar não gravava as linhas de uma Lista de itens (o formulário recebido não batia com a tela), a resposta dizia só "Registro salvo com sucesso!". Agora aparece o aviso "Linhas não gravadas", com o nome da lista e o que fazer.
  • Formulários: numa Lista de itens com coluna de arquivo cuja pasta leva data e hora, as linhas deixavam de ser gravadas quando a pessoa fazia muitas ações na tela antes de salvar. Agora são gravadas.
  • Formulários: no Avatar e na Assinatura, o Tamanho máximo e os Tipos aceitos valiam só no navegador; uma requisição alterada gravava qualquer arquivo. Agora valem também no Salvar, com a mensagem no campo. Republique o projeto para aplicar.
  • Formulários: no Avatar, escrever os Tipos aceitos como extensão (.png) recusava qualquer foto. Agora vale a mesma regra dos outros campos de upload.
  • Formulários: a Assinatura desenhada ou digitada saía sempre em PNG, mesmo com os Tipos aceitos só em JPEG. Agora sai num tipo aceito e dentro do Tamanho máximo; quando não cabe, avisa e não é aplicada.
  • Formulários: nos Anexos (<mad-attachments>) e nos blocos com arquivo (<mad-db-blocks>), um arquivo acima do limite de envio do servidor era descartado e o item era gravado sem ele, com mensagem de sucesso. Agora nada é gravado e o aviso diz o arquivo e o limite. Republique o projeto para aplicar.
  • Formulários: numa ação da tela que lê o arquivo com $request->file(), o arquivo recusado pelo servidor sumia e a ação seguia sem ele. Agora a ação para, com o aviso do arquivo e do limite.
  • Formulários: no campo Imagem que guarda a foto na própria coluna (sem storage), os Tipos aceitos eram conferidos só pelo tipo que o envio declarava: uma requisição alterada gravava um JPEG dizendo ser PNG, ou uma imagem sem tipo. Agora o tipo é conferido pelo conteúdo da imagem. Republique o projeto para aplicar.
  • Formulários: na Lista de itens, o Tamanho máximo de uma coluna de arquivo valia só no navegador; uma requisição alterada gravava arquivo de qualquer tamanho nas linhas. Agora vale também no Salvar, com o aviso do arquivo e do limite. Republique o projeto para aplicar.
  • Formulários: quando uma ação trocava as opções de um Grupo de caixas, Checklist, Multi Entry ou Sort List com setItems(), o campo voltava sem nenhuma marca e o Salvar seguinte gravava a seleção vazia; no Checklist a ação nem respondia. Agora as marcas que continuam na lista ficam marcadas. Republique o projeto para aplicar.
  • Formulários: num redesenho completo da tela, o DB Checkbox Group gravado em outra tabela voltava ao que estava salvo e desfazia o que o usuário tinha marcado e ainda não salvou. Agora ele mantém o que está na tela, como os outros campos de seleção múltipla.
  • Formulários: num campo de seleção múltipla gravado por vírgula na própria coluna, o Salvar que chegava sem o formulário da tela, ou sem o campo (marcado numa ação anterior, campo desabilitado), tirava da coluna os itens que a lista não mostra e podia gravar a seleção num formato que o campo não lê. Agora sai da coluna só o que a tela mostrou marcado e o usuário desmarcou. Republique o projeto para aplicar.
  • Formulários: campos de seleção múltipla com separator diferente de vírgula liam a coluna com o separador do campo, mas o Salvar gravava com vírgula, e na tela seguinte nada aparecia marcado. Agora a coluna é gravada com o separador do campo. Republique o projeto para aplicar.
  • Formulários: ao consultar um CNPJ num formulário que também tem Consulta CEP, o CEP preenchido fazia uma segunda consulta que reescrevia o endereço com outra grafia e mostrava dois avisos. Agora o endereço do CNPJ é mantido e a segunda consulta só acontece quando o CNPJ não preenche todos os campos do CEP. Republique o projeto para aplicar.
  • Formulários: no Preenchimento de campos do combo, os formatos CPF, CNPJ, CEP, telefone, moedas, inteiro, percentual e datas escolhidos na Transformação não eram aplicados e o valor entrava sem formatação; agora são aplicados. Número (1.234,56) passa a preencher com 2 casas, como o rótulo indica. Republique o projeto para aplicar.
  • Formulários: a assinatura ou a imagem desenhada no formulário de um item (<mad-detail-form>, inclusive na cortina lateral) não era gravada ao salvar, e a coluna ficava vazia sem aviso. Agora é gravada, como no formulário próprio da tabela. Republique o projeto para aplicar.
  • Formulários: o checkbox abria desmarcado no cadastro novo mesmo com Valor padrão (ou checked na tag); agora abre marcado quando o padrão é o valor ligado. Republique o projeto para aplicar.
  • Formulários: a Entrada múltipla (<mad-multi-entry-field>) e a Lista ordenável (<mad-sort-list-field>) passam a abrir com o Valor padrão (lista separada por vírgula) no cadastro novo. Republique o projeto para aplicar.
  • Formulários: no checklist que a tela grava pelo próprio código (loadChecklist() / saveChecklist()), uma marca de item que a lista de quem salva não mostra era gravada quando a tabela de ligação não tinha regras. Agora o Salvar é recusado com a mensagem no campo.
  • Formulários: nesse checklist, a ligação com um item que a lista da tela não oferece (lista filtrada, item inativo) saía no Salvar sem ninguém desmarcar. Agora ela continua gravada.
  • Formulários: nas telas Grupos, Perfis e Programas, quem salvava depois desfazia a ação que outra pessoa tinha tirado de um programa enquanto a tela estava aberta. Agora a mudança da outra pessoa fica e quem salva é avisado.
  • Formulários: o aviso de marca mudada em outra aba passa a dizer em qual lista foi (o rótulo do checklist ou o nome da aba).
  • Formulários: o Grupo de caixas (<mad-checkbox-group-field>, <mad-dbcheckbox-group-field>) e a Multi busca (<mad-multi-search-field>, <mad-dbmulti-search-field>) passam a abrir com o Valor padrão no cadastro novo, e o Salvar grava essas marcas na coluna ou na tabela de ligação. Ao editar um registro, vale o que está gravado. Republique o projeto para aplicar.
  • Formulários: a Entrada múltipla (<mad-multi-entry-field>) abria vazia ao editar um registro; agora mostra os valores gravados. A Lista ordenável (<mad-sort-list-field>) passa a abrir na ordem gravada na coluna. Republique o projeto para aplicar.
  • Formulários: o contador do Checklist passava do total da lista ("4 de 3 selecionados") quando o registro tinha marcas em itens que a lista não mostra. Agora conta só as marcas da lista e informa à parte quantas ficaram fora dela ("mais 2 fora da lista"), no idioma do app.
  • Formulários: um campo ligado a uma coluna que o Model não aceita da tela (fora do $fillable, em $guarded, ou uma coluna de controle como created_at) salvava sem gravar o valor trocado e respondia só "Registro salvo com sucesso!". Agora a resposta avisa "Valor não gravado" com o nome do campo, a menos que o código da tela grave a coluna.
  • Formulários: a lista que o código põe com setItems() num Radio, Checkbox em grupo, Multi entry, Lista ordenável, Checklist ou na versão de banco deles voltava inteira quando a tela era redesenhada. Agora o campo continua com a lista do código, também no primeiro desenho quando o setItems() está no carregamento da tela.
  • Formulários: o aviso "Itens já removidos" de uma aba desatualizada citava "a linha 3 da lista" e o nome interno do anexo, não dizia que a edição feita na linha se perdeu e voltava a cada Salvar. Agora cita a linha pelo texto que a tela mostra e o anexo pelo nome exibido, avisa que a alteração não foi gravada e tira a linha da Lista de itens e do Detail Form.
  • Listagens: o Excluir do <mad-del> numa listagem <mad-grid self> (a listagem gerada) respondia "Método não permitido" e não excluía nada, na linha ou dentro de um grupo de ações. Agora exclui, como no <mad-grid model="…">: só linhas que a listagem mostra, com aviso quando o registro já não está lá ou o cadastro recusa. Republique o projeto para aplicar.
  • Listagens: a Variante success, warning, info e ghost da Ação Grid (<mad-act variant="…">, <mad-nav variant="…">) saía no botão neutro. Agora o botão da linha, o item do menu do grupo de ações e o botão do cartão saem na cor da variante (ghost, sem borda). Republique o projeto para aplicar.
  • Listagens: na edição de data ou de data e hora na célula, o calendário reaberto antes de o salvamento anterior terminar mostrava a data antiga, e depois de um Esc mostrava o que tinha sido descartado. Agora ele abre com o valor que está sendo editado. Republique o projeto para aplicar.
  • Listagens: no PDF exportado, a seta do período e os sinais de maior ou igual e menor ou igual na linha de filtros do cabeçalho ({FILTERS}) saíam como ponto de interrogação ("01/01/2026 ? 31/12/2026"). Agora o período sai em palavras, como no {PERIOD}: "de 01/01/2026 a 31/12/2026", "a partir de …", "até …". Republique o projeto para aplicar.
  • Listagens: a navegação de uma ação da listagem com params="{modo: ver}" (o formato do painel) entregava à tela destino um parâmetro só, com o texto inteiro. Agora chega como modo=ver, com {campo} trocado pelo valor da linha, e um formato não reconhecido mostra aviso na tela.
  • Listagens: a grade de painel sem o botão Excluir aceitava excluir um registro por uma requisição montada à mão, e as condições do Excluir (exibir quando, desabilitar quando) só escondiam o botão. Agora o servidor recusa a exclusão onde a tela não mostra o Excluir.
  • Importação de dados: no PostgreSQL toda linha falhava, e no MySQL e no SQLite reimportar um registro trocava o código dele e apagava as colunas que não vinham no arquivo. Agora o registro que já existe (mesma chave ou campo único) é atualizado no lugar. Republique o projeto para aplicar.
  • Importação de dados: arquivos "CSV UTF-8" e "CSV" do Excel são lidos corretamente, Sim/Não vira verdadeiro/falso, e uma coluna do mapeamento que falta no arquivo agora interrompe a importação com aviso, em vez de gravar vazio.
  • Importação de dados: as linhas importadas recebem data, usuário e unidade de criação e de alteração, como as gravadas pelo formulário; com Multi-unidade elas podiam sumir da listagem.
  • Importação de dados: no modo atômico, cada linha com erro mostra o próprio erro.
  • Importação de dados: os templates passam a respeitar os Grupos com acesso e Usuários com acesso: quem não está neles não vê o template na lista nem o botão <mad-import-btn>, e não importa com ele; template inativo só aparece para administrador. Republique o projeto para aplicar.
  • Importação de dados: o Banco de Dados não oferece mais as conexões internas do sistema, e a Tabela destino não lista as tabelas internas (mad_*); a importação para elas é recusada.
  • Importação de dados: a ação Modelo CSV da lista de templates baixava "Arquivo modelo não encontrado."; agora baixa o modelo, e excluir o template apaga o arquivo dele.
  • Importação de dados: ao editar um template ativo, o interruptor Ativo aparecia desligado, e salvar desativava o template.
  • Importação de dados: escolher o Banco de Dados não apaga mais a tabela e o campo já escolhidos nas linhas do mapeamento.
  • Importação de dados: o Modelo CSV gerado traz exemplos no formato de cada campo (número, data, valor, Sim/Não), prontos para importar.
  • Importação de dados: o erro de cada linha aparece em frase ("O campo Nome é obrigatório.") em vez do texto técnico do banco, no resultado e no histórico; a lista Campo CSV da importação livre mostra os cabeçalhos de arquivos do Excel sem caracteres estranhos.
  • API: /api/import-templates passa a exigir o acesso às telas de importação e às permissões de cada template; antes bastava estar logado.
  • Componentes: o menu de botão direito (<mad-context-menu> e o <mad-tree-context-menu> da árvore) saía cortado dentro de uma coluna com rolagem, como a barra lateral de pastas. Agora ele aparece inteiro, por cima da tela, e fecha ao rolar a coluna ou a página.
  • Empresas (multi-banco): provisionar de novo uma empresa com banco próprio não reexecuta mais todo o histórico do modelo de dados, que podia esvaziar uma coluna cujo nome foi reaproveitado. Agora só rodam as alterações que ainda faltam naquele banco, e uma alteração que falhar aparece como aviso na tela.
  • Depuração: mdm($valor) e mad_dump_modal($valor) num método de tela davam erro "Call to undefined function mdm()". Agora abrem o modal de depuração com os valores e a linha do código que os chamou. Republique o projeto para aplicar.
  • API REST: os filtros da listagem enviados em texto JSON (filters={"status":{"eq":"open"}}, a forma dos exemplos da documentação) passam a filtrar; antes a API devolvia todas as linhas. Texto inválido é recusado com erro 422, e filtro que não pôde ser aplicado volta listado em meta.ignored_filters.
  • API REST: as mensagens de validação da API saem no idioma do app (português do Brasil, de Portugal e espanhol) em vez de inglês. Republique o projeto para aplicar.
  • API REST: ao criar ou alterar um registro, a resposta passa a listar em ignored as chaves do corpo que não foram gravadas (nome antigo de uma coluna, erro de digitação), no registro e em cada linha de detalhe. Antes o valor sumia sem aviso.
  • Lista de itens: com o Model escrito com namespace (model="App\Models\Fin\Parcela"), a lista abria sempre vazia ao editar um registro com linhas e o Salvar respondia que a classe não existia. Agora as duas formas (nome curto e com namespace) funcionam. Um apóstrofo nos textos da tag (add-label="Adicionar item d'água") também deixa de aparecer com uma barra antes. Republique o projeto para aplicar.
  • Lista de itens: o total no rodapé de uma coluna com soma (sum) arredondava sempre para 2 casas decimais, mesmo em colunas com mais casas (decimals="3" mostrava 3,74 em vez de 3,735), e o evento Ao totalizar (on-totalize) recebia o mesmo valor arredondado. Agora o rodapé e o <campo>_sum respeitam as casas da coluna, e o evento passa a receber também <campo>_sum_value, a soma como número, pronta para cálculo. Republique o projeto para aplicar.
  • Lista de itens: numa coluna de vários arquivos (type="multifile"), anexar um arquivo a uma linha que já tinha arquivos deixava só o novo no registro, e os antigos ficavam sobrando no disco; cada Salvar seguinte gravava o mesmo arquivo de novo, e o X de um arquivo já gravado não tinha efeito. Agora o arquivo novo é acrescentado aos que já estavam, é gravado uma vez só, e o X remove o arquivo do registro e do disco. Republique o projeto para aplicar.
  • Lista de itens: numa coluna de tabela (type="dbcombo"), a linha cujo valor gravado não está na lista de quem edita (cadastro de outra unidade, usuário que a pessoa não enxerga, registro inativo) abria com o combo em "Selecione...", escondendo que havia um valor ali. Agora a linha mostra a opção "Registro atual (fora da sua lista)", selecionada, como já acontecia nos campos do formulário; dá para trocar por um item da lista ou limpar. Republique o projeto para aplicar.
  • Temas: a tela de login na variante 3 sem imagem de fundo carregava uma foto de um site externo a cada abertura (e ficava vazia sem internet). Agora usa um fundo próprio. Republique o projeto para aplicar.
  • Formulário: $this->form->setItems('tipo', $itens, null, 'Escolha o tipo') no mount() abria o combo sem a opção vazia e com a primeira opção da lista já escolhida. Agora a opção vazia com esse texto aparece desde a abertura da tela, no <mad-select-field> e no <mad-dbcombo-field>.
  • Segurança: campos de seleção múltipla com consulta própria (:query) ou com opções fixas aceitavam, numa requisição alterada, um valor que a lista não oferece, inclusive o que a consulta da tela filtrou de propósito. Agora o Salvar é recusado, com a mensagem no campo; o que já estava gravado continua valendo. Republique o projeto para aplicar.
  • Segurança: a chave de pareamento do Driver REST e as credenciais do armazenamento S3 do projeto passam a ficar cifradas no storage/ do app; o que já estava gravado continua valendo e é cifrado no primeiro uso.
  • Permissões: dois Salvar no mesmo instante nas telas de Usuários, Grupos, Perfis e Programas podiam gravar a mesma ligação duas vezes. O banco passa a recusar a repetida, e as ligações repetidas que já existiam viram uma só na atualização, sem mudar o que cada pessoa pode fazer.
  • Usuários: com o Licenciamento ligado, salvar um usuário apagava o vínculo com uma unidade que outro administrador tinha criado com a tela aberta, junto com os perfis e os módulos dele. Agora o Salvar só remove as unidades tiradas naquela tela.
  • Avisos de alteração em outra aba: depois de salvar numa cortina (Usuários da unidade, Perfis e módulos, módulos da licença), o aviso de que outra pessoa mudou algo pedia "Atualize a tela" com a tela já fechada. Agora pede para abrir o cadastro de novo.
  • Usuários da unidade: com a tela aberta, o Salvar devolvia o valor antigo de Ativo, Administrador da unidade, nome, e-mail e login que outra pessoa tinha mudado (reativava o vínculo desativado, devolvia a administração). Agora grava só o que foi mudado naquela tela e avisa o que a outra pessoa mudou.
  • Campos de exibição: com format="money", o valor 1234.56 aparecia como R$ 123.456,00; com format="date", datas como 05/10/2026 apareciam com dia e mês trocados. visible-when também passa a valer no <mad-display-field>.
  • Período: as setas do calendário de <mad-daterange-field> passam a andar os dois meses juntos, sempre consecutivos. Antes, voltar o mês da esquerda deixava a direita parada e um mês sumia da vista; vale também para o filtro de Período do dashboard.
  • Bloco de itens (<mad-db-blocks>): uma requisição alterada conseguia renomear, alterar ou remover um item de outro registro (no esqueleto, o rótulo da caixa de correio de outro usuário), gravar uma coluna que o bloco não edita e mover o item para outro registro. Agora o servidor só mexe nos itens que o bloco mostra e só grava os campos que ele edita.
  • Bloco de itens (<mad-db-blocks>): o item novo ou editado pelo formulário do bloco aceitava a chave de um cadastro de outra unidade. Agora as regras exists do rules() do Model valem também aqui, como nas linhas de detalhe.
  • Detail Form: nas linhas, um campo de seleção múltipla gravado por vírgula aceitava, numa requisição alterada, uma marca que a lista do campo não oferece, e uma Imagem aceitava arquivo acima do Tamanho máximo ou de um tipo não aceito. Agora as linhas têm as mesmas conferências do formulário principal.
  • Detail Form: editar uma linha que tem arquivo dava erro: em modal ou cortina lateral a edição não abria, e na própria tela os campos depois do arquivo ficavam com os valores da linha anterior, que o Atualizar gravava. Agora a edição abre com todos os campos da linha e o arquivo dela é mantido.
  • Apps gerados: migration nova, mudança no .env.example (como o APP_TIMEZONE), no artisan, em bin/, deploy/ e nos arquivos de public/ que não são assets passam a chegar aos apps gerados junto com a versão do framework.
  • Banco de dados: com o modelo de dados num banco próprio, o php artisan mad:schema:sync de cada publicação não roda mais de novo todo o histórico do modelo quando uma tabela dele foi excluída ou renomeada — o que podia esvaziar uma coluna cujo nome foi reaproveitado. Alteração que falha passa a aparecer como aviso, e o comando termina com erro.
  • Multiempresa (Dedicado): a pessoa de uma empresa que ainda não teve o banco provisionado não entra mais no banco principal sem aviso. O login, a troca de empresa ou unidade e o "Entrar como" mostram "O banco desta empresa ainda não foi criado. Peça ao administrador para provisionar.", e a API responde 403.
  • Login: com o app atrás de proxy ou balanceador, as senhas erradas de uma pessoa não bloqueiam mais o login de todos nem o do dono da conta: o limite de tentativas conta cada visitante pelo endereço dele. Declare o proxy em TRUSTED_PROXIES no .env.
  • Login: entrar com uma conta válida não zera mais o limite de tentativas do endereço, que continua barrando quem testa senhas em muitos usuários.
  • App gerado: quando a rede caía no meio de uma ação (Salvar de formulário, clique de botão, filtro), nada aparecia na tela e o usuário ficava sem saber se a ação valeu. Agora aparece o aviso "Não foi possível falar com o servidor. Confira a conexão e tente de novo.", uma vez só mesmo com várias ações caindo juntas.
  • Planilha: o que era digitado entre o clique em Salvar e a resposta do servidor sumia sem ter sido gravado. Agora as linhas ficam travadas e esmaecidas até o Salvar responder, e, se o servidor não responder, a Planilha avisa que nada foi salvo e mantém o que foi digitado.
  • Documentos (GED): o link compartilhado de um documento não fica mais gravado em texto puro no banco; quem lê o banco não consegue abrir o documento. Os links já enviados continuam abrindo e podem ser copiados de novo na tela.
  • Instalação: o .env criado pelo instalador deixa de ser legível por qualquer usuário do servidor (permissão 0640); um .env que já existia mantém a permissão que tinha.
  • Chat IA (Mad Coding Plan): quando o chat não pode responder, o app publicado passa a dizer o motivo — chat desligado no projeto, franquia semanal esgotada (com a data em que volta), franquia de teste esgotada, assinatura ou plano sem o recurso, app sem vínculo com o MadBuilder — em vez de uma falha genérica de autenticação.
  • Quadro (Kanban): o e-mail pedido com MailService::send no código que roda ao mover um cartão se perdia nos apps com banco SQLite, como o Teste Online, e o movimento demorava alguns segundos. Agora o e-mail entra na fila assim que o movimento é gravado, e não sai quando o movimento é recusado.
  • E-mail: MailService::send chamado no meio de uma gravação em andamento (transação) espera a gravação terminar para pôr o e-mail na fila; se ela for desfeita, o e-mail não sai.
  • Documentos (PDF): a Imagem dinâmica passa a imprimir a foto enviada pelos campos Upload e Imagem gravando em disco, a imagem guardada em base64 no banco e imagens de endereço https://, que antes saíam só com o texto alternativo. Endereços da rede interna continuam bloqueados. Republique o projeto para aplicar.

Atenção

  • Listagens: os Parâmetros da Ação Grid (params="{origem: lista, cliente: {cliente}}" ou :params="['origem' => …]") passam a chegar ao método com as chaves do painel: $extras['cliente'], e não mais como lista na ordem declarada. Método que lia $extras[0] deve passar a ler pela chave. Parâmetros escritos como lista (:params="['a', 'b']") continuam lista.
  • Formulários: nos campos de seleção múltipla com :query própria ou com opções fixas, o Salvar passa a recusar a marca nova que não está entre as opções que a tela ofereceu (as fixas, as que a consulta carregou ou as que o código trocou com setItems()), com o aviso "Um dos itens marcados não pode ser gravado" no campo. Campos com "Cadastrar novo"/"Adicionar" e mode="manual" não mudam. Se a tela precisa gravar um item fora da lista, atribua o valor no código do Salvar ($form->set()).
  • Bloco de itens (<mad-db-blocks>): a edição de um campo só (blockUpdate) aceita os campos de edit-fields ou, sem eles, os do $fillable do Model. Se a tela edita um campo fora dessas listas, declare-o em edit-fields.
  • Listagens: a grade com um botão próprio que chamava a exclusão da grade sem declarar <mad-del> passa a ter a exclusão recusada ("Requisição inválida"). Declare o <mad-del> na grade, com as condições de quando ele vale.