Project

General

Profile

Actions

Padrão #6

open

Rim - Interação entre opções após a ação do usuário

Added by Henrique Novaes 6 months ago. Updated 6 months ago.

Status:
teste reprovado
Priority:
normal
Assignee:
Category:
planejada
Start date:
07/03/2025
Due date:
% Done:

0%

Estimated time:

Description

Aqui vou citar as outras ações a mais caso o usuário selecione uma das 7 opções listadas na tarefa anterior:

Ausência Renal Direita / Nefrectomia Direita (aqui também vale o contrário para o lado esquerdo)

  • Bloquear e desmarcar:
    Medidas Rim Direito / Nefropatia parenquimatosa Rim Direito / Cisto Rim Direito / Cistos Bilaterais / Dilatação do sistema coletor Rim Direito / cálculo obstrutivo rim direito / múltiplos cálculos obstrutivos bilaterais
  • Bloquear a possibilidade de escolher "direito", "rim direito" ou "RD" de:
    "direita" em rim pélvico (dentro de anomalias congênitas) / "RD" em nefrectomia parcial (dentro de cirurgias prévias) / "RD" em nódulo sólido / "RD" em Angiomiolipoma / "RD" em Cisto complexo / "RD" em todos os Cálculos não obstrutivos / "rim direito" em microcálculos calicinais

Rins em Ferradura

  • Bloquear e desmarcar: Medidas Rim Direito e Esquerdo / Nefropatia parenquimatosa (Direito ou Esquerdo) / Cirurgias prévias (todo o campo)

Ectopia renal cruzada direita ou esquerda

  • Bloquear e desmarcar todos os campos, exceto dilatação do sistema coletor RD e RE (pode bloquear também cálculo obstrutivo)

Files

Actions #1

Updated by jean sodré 6 months ago

  • Status changed from a fazer to em execução
Actions #2

Updated by camila oliveira 6 months ago

  • Assignee set to jean sodré
Actions #3

Updated by jean sodré 6 months ago

  • Status changed from em execução to teste
Actions #4

Updated by jean sodré 6 months ago

  • Status changed from teste to em execução
Actions #5

Updated by jean sodré 6 months ago

  • Status changed from em execução to teste

Exemplo de lógica aplicada:


   $scope.criarExclusaoMutuaComMemoria({
        campos: [
            'dados.rins.ausenciaRD',
            'dados.rins.ausenciaRE',
            'dados.rins.cistoRimDireitoQtd',
            'dados.rins.nefropatiaRD',
            'dados.rins.cistosBilateraisAtivo',
            'dados.rins.dilatacaoDireitoGrau',
            'dados.rins.ureteralDireito',
            'dados.rins.calculoObstrutivoDireito',
            'dados.rins.multiplosCalculos',
            'dados.rins.cistoRimEsquerdoQtd',
            'dados.rins.nefropatiaRE',
            'dados.rins.dilatacaoEsquerdoGrau',
            'dados.rins.ureteralEsquerdo',
            'dados.rins.calculoObstrutivoEsquerdo'
        ],
        gruposCompativeis: [
            // Grupo 1: Ausência Lado Direito - compatível com elementos do lado esquerdo
            ['dados.rins.ausenciaRE', 'dados.rins.cistoRimDireitoQtd', 'dados.rins.nefropatiaRD', 'dados.rins.cistosBilateraisAtivo',
            'dados.rins.dilatacaoDireitoGrau', 'dados.rins.ureteralDireito', 'dados.rins.calculoObstrutivoDireito'
            ],
            // Grupo 2: Ausência Lado Esquerdo - compatível com elementos do lado direito
            ['dados.rins.ausenciaRD', 'dados.rins.cistoRimEsquerdoQtd', 'dados.rins.nefropatiaRE', 'dados.rins.cistosBilateraisAtivo',
            'dados.rins.dilatacaoEsquerdoGrau', 'dados.rins.ureteralEsquerdo', 'dados.rins.calculoObstrutivoEsquerdo' ],
            // Grupo 3: Elementos do lado esquerdo compatíveis entre si
            ['dados.rins.cistoRimEsquerdoQtd', 'dados.rins.nefropatiaRE', 'dados.rins.cistosBilateraisAtivo',
            'dados.rins.dilatacaoEsquerdoGrau', 'dados.rins.ureteralEsquerdo', 'dados.rins.calculoObstrutivoEsquerdo', 
            'dados.rins.calculoObstrutivoDireito', 'dados.rins.multiplosCalculos' ],
            // Grupo 4: Elementos do lado direito compatíveis entre si
            ['dados.rins.cistoRimDireitoQtd', 'dados.rins.nefropatiaRD', 'dados.rins.cistosBilateraisAtivo',
            'dados.rins.dilatacaoDireitoGrau', 'dados.rins.ureteralDireito', 'dados.rins.calculoObstrutivoDireito',
            'dados.rins.multiplosCalculos' 
            ]
        ],
        camposPrioritarios: [
            'dados.rins.ausenciaRD',
            'dados.rins.ausenciaRE'
        ]
    });

Actions #6

Updated by jean sodré 6 months ago · Edited

Função criada para salvar em memória e facilitar a configuração desabilitar/habilitar campos

     $scope.criarExclusaoMutuaComMemoria = function(config) {
        let processandoExclusao = false;
        let memoriaEstados = {}; // Guarda o estado anterior dos campos
        
        // Função para obter valor aninhado
        function getNestedValue(obj, path) {
            return path.split('.').reduce((current, key) => {
                return current && current[key] !== undefined ? current[key] : null;
            }, obj);
        }
        
        // Função para definir valor aninhado
        function setNestedValue(obj, path, value) {
            const keys = path.split('.');
            const lastKey = keys.pop();
            const target = keys.reduce((current, key) => {
                if (!current[key]) current[key] = {};
                return current[key];
            }, obj);
            target[lastKey] = value;
        }
        
        // Função para detectar o tipo de valor e definir o valor "vazio"
        function getValorVazio(valor) {
            if (typeof valor === 'boolean') return false;
            if (typeof valor === 'number') return 0;
            if (typeof valor === 'string') return '';
            return null;
        }
        
        // 🎯 NOVA FUNÇÃO: Verifica se um campo está ativo considerando valores específicos
        function campoEstaAtivo(path, valorEspecifico = null) {
            const valor = getNestedValue($scope, path);
            
            // Se foi especificado um valor específico, verifica se o campo tem esse valor
            if (valorEspecifico !== null) {
                return valor === valorEspecifico;
            }
            
            // Lógica original para outros tipos
            if (typeof valor === 'boolean') return valor === true;
            if (typeof valor === 'number') return valor !== 0;
            if (typeof valor === 'string') return valor !== '';
            return false;
        }
        
        // 🎯 NOVA FUNÇÃO: Verifica se um campo tem configuração de valor específico
        function temValorEspecifico(campoConfig) {
            return typeof campoConfig === 'object' && campoConfig.campo && campoConfig.valor;
        }
        
        // 🎯 NOVA FUNÇÃO: Extrai o nome do campo de uma configuração
        function getNomeCampo(campoConfig) {
            return temValorEspecifico(campoConfig) ? campoConfig.campo : campoConfig;
        }
        
        // 🎯 NOVA FUNÇÃO: Extrai o valor específico de uma configuração
        function getValorEspecifico(campoConfig) {
            return temValorEspecifico(campoConfig) ? campoConfig.valor : null;
        }
        
        // 🎯 FUNÇÃO: Salva estado atual dos campos na memória
        function salvarEstadoNaMemoria(campoReferencia, camposParaSalvar) {
            if (!memoriaEstados[campoReferencia]) {
                memoriaEstados[campoReferencia] = {};
            }
            
            camposParaSalvar.forEach(campoConfig => {
                const nomeCampo = getNomeCampo(campoConfig);
                const valor = getNestedValue($scope, nomeCampo);
                
                if (campoEstaAtivo(nomeCampo)) {
                    memoriaEstados[campoReferencia][nomeCampo] = valor;
                    console.log(`💾 Salvando estado de '${nomeCampo}':`, valor);
                }
            });
        }
        
        // 🎯 FUNÇÃO: Restaura estado dos campos da memória
        function restaurarEstadoDaMemoria(campoReferencia) {
            if (memoriaEstados[campoReferencia]) {
                console.log(`🔄 Restaurando estados para '${campoReferencia}':`, memoriaEstados[campoReferencia]);
                
                Object.keys(memoriaEstados[campoReferencia]).forEach(campo => {
                    const valorSalvo = memoriaEstados[campoReferencia][campo];
                    setNestedValue($scope, campo, valorSalvo);
                    console.log(`✅ Restaurado '${campo}' para:`, valorSalvo);
                });
                
                // Limpa a memória após restaurar
                delete memoriaEstados[campoReferencia];
            }
        }
        
        // 🎯 FUNÇÃO: Limpa memória de um campo
        function limparMemoriaDoCampo(campoReferencia) {
            if (memoriaEstados[campoReferencia]) {
                console.log(`🗑️ Limpando memória de '${campoReferencia}'`);
                delete memoriaEstados[campoReferencia];
            }
        }
        
        // 🎯 NOVA FUNÇÃO: Limpa um campo considerando configurações especiais
        function limparCampo(campoConfig) {
            const nomeCampo = getNomeCampo(campoConfig);
            
            // Se tem configuração de limpeza específica
            if (temValorEspecifico(campoConfig) && campoConfig.limparPara !== undefined) {
                setNestedValue($scope, nomeCampo, campoConfig.limparPara);
                console.log(`🧹 Limpando '${nomeCampo}' para valor específico:`, campoConfig.limparPara);
            } else {
                // Lógica original
                const valor = getNestedValue($scope, nomeCampo);
                const valorVazio = getValorVazio(valor);
                setNestedValue($scope, nomeCampo, valorVazio);
                console.log(`🧹 Limpando '${nomeCampo}' para valor vazio:`, valorVazio);
            }
        }
        
        // 🎯 NOVA FUNÇÃO: Verifica se dois campos são compatíveis
        function saoCompativeis(campoConfig1, campoConfig2) {
            const nomeCampo1 = getNomeCampo(campoConfig1);
            const nomeCampo2 = getNomeCampo(campoConfig2);
            
            if (config.gruposCompativeis) {
                return config.gruposCompativeis.some(grupo => {
                    const temCampo1 = grupo.some(item => getNomeCampo(item) === nomeCampo1);
                    const temCampo2 = grupo.some(item => getNomeCampo(item) === nomeCampo2);
                    return temCampo1 && temCampo2;
                });
            }
            return false;
        }
        
        // 🎯 NOVA FUNÇÃO: Verifica se é um campo prioritário
        function ehCampoPrioritario(campoConfig) {
            const nomeCampo = getNomeCampo(campoConfig);
            return config.camposPrioritarios && config.camposPrioritarios.some(item => 
                getNomeCampo(item) === nomeCampo
            );
        }
        
        // 🎯 NOVA FUNÇÃO: Obtém campos incompatíveis
        function getCamposIncompativeis(campoReferencia, todosCampos) {
            return todosCampos.filter(campoConfig => {
                const nomeCampo = getNomeCampo(campoConfig);
                const nomeReferencia = getNomeCampo(campoReferencia);
                
                return nomeCampo !== nomeReferencia && !saoCompativeis(campoReferencia, campoConfig);
            });
        }
        
        // 🎯 NOVA FUNÇÃO: Normaliza a lista de campos para incluir apenas nomes únicos para o watchGroup
        function getNomesCamposParaWatch() {
            const nomes = new Set();
            config.campos.forEach(campoConfig => {
                nomes.add(getNomeCampo(campoConfig));
            });
            return Array.from(nomes);
        }
        
        // Cria o $watchGroup automaticamente
        const nomesParaWatch = getNomesCamposParaWatch();
        
        $scope.$watchGroup(nomesParaWatch, function(newValues, oldValues) {
            
            // Evita loop infinito
            if (processandoExclusao) return;
            
            // Evita execução na primeira vez
            if (newValues === oldValues) return;
            
            // Encontra qual campo foi alterado
            let campoAlterado = null;
            let valorAnterior = null;
            let valorAtual = null;
            
            for (let i = 0; i < nomesParaWatch.length; i++) {
                if (newValues[i] !== oldValues[i]) {
                    const nomeCampo = nomesParaWatch[i];
                    valorAnterior = oldValues[i];
                    valorAtual = newValues[i];
                    
                    // Encontra a configuração completa do campo alterado
                    campoAlterado = config.campos.find(campoConfig => 
                        getNomeCampo(campoConfig) === nomeCampo
                    );
                    break;
                }
            }
            
            if (campoAlterado) {
                processandoExclusao = true;
                
                const nomeCampoAlterado = getNomeCampo(campoAlterado);
                const valorEspecifico = getValorEspecifico(campoAlterado);
                
                console.log('Campo alterado:', nomeCampoAlterado, 'de', valorAnterior, 'para', valorAtual);
                if (valorEspecifico) {
                    console.log('Valor específico monitorado:', valorEspecifico);
                }
                
                // Obtém os campos incompatíveis com o campo alterado
                const camposIncompativeis = getCamposIncompativeis(campoAlterado, config.campos);
                
                // 🎯 LÓGICA PRINCIPAL: Se campo foi ATIVADO (considerando valor específico)
                if (campoEstaAtivo(nomeCampoAlterado, valorEspecifico)) {
                    
                    console.log(`✅ Campo '${nomeCampoAlterado}' foi ativado`);
                    
                    // 🎯 Se é um campo prioritário
                    if (ehCampoPrioritario(campoAlterado)) {
                        console.log(`🎯 Campo '${nomeCampoAlterado}' é prioritário - salvando estados`);
                        // Salva o estado dos campos que serão limpos
                        salvarEstadoNaMemoria(nomeCampoAlterado, camposIncompativeis);
                    }
                    
                    // Limpa os campos incompatíveis que estão ativos
                    camposIncompativeis.forEach(campoConfig => {
                        const nomeCampo = getNomeCampo(campoConfig);
                        const valorEspecificoIncompativel = getValorEspecifico(campoConfig);
                        
                        if (campoEstaAtivo(nomeCampo, valorEspecificoIncompativel)) {
                            console.log(`🧹 Limpando campo incompatível: '${nomeCampo}'`);
                            limparCampo(campoConfig);
                        }
                    });
                    
                    // Limpa memória de outros campos prioritários que podem ter conflito
                    if (config.camposPrioritarios) {
                        config.camposPrioritarios.forEach(campoPrioritario => {
                            const nomePrioritario = getNomeCampo(campoPrioritario);
                            if (nomePrioritario !== nomeCampoAlterado) {
                                limparMemoriaDoCampo(nomePrioritario);
                            }
                        });
                    }
                    
                } 
                // 🎯 LÓGICA PRINCIPAL: Se campo foi DESATIVADO
                else {
                    console.log(`❌ Campo '${nomeCampoAlterado}' foi desativado`);
                    
                    // 🎯 Se é um campo prioritário que foi desativado
                    if (ehCampoPrioritario(campoAlterado)) {
                        console.log(`🔄 Campo '${nomeCampoAlterado}' é prioritário - restaurando estados`);
                        // Restaura o estado anterior dos campos
                        restaurarEstadoDaMemoria(nomeCampoAlterado);
                    }
                }
                
                setTimeout(() => {
                    processandoExclusao = false;
                }, 100);
            }
        });
        
        console.log('Exclusão mútua com memória criada para:', config.campos.map(c => getNomeCampo(c)));
        console.log('Grupos compatíveis:', config.gruposCompativeis);
        console.log('Campos prioritários:', config.camposPrioritarios);
    };
Actions #7

Updated by Henrique Novaes 6 months ago

Após revisão:

  1. Ausência RD selecionada pelo usuário:
  • falta bloquear o campo "Nefropatia parenquimatosa RD"
  • Quando seleciono "Nefropatia parenquimatosa RE" está desmarcando automaticamente o "Ausência RD" (o certo é o usuário poder utilizar essa opção)
  • Nefrectomia total ainda está habilitado = o certo é bloquear as duas opções (lado direito e lado esquerdo)
  • As opções de lado direito de "nefrectomia parcial", "rim pélvico", "nódulo sólido", "angiomiolipoma", "cisto complexo", "cálculos não obstrutivos" e "microcálculos calicinais" permanecem passíveis de serem selecionadas (o certo é estarem bloqueadas já que não temos rim direito)
    OBS: no caso dos microcálculos calicinais, tem uma opção "bilaterais" na caixa de seleção que também é bloqueada nesses casos de ausência RD/RE e nefrectomia total RD/RE
  1. Ausência RE selecionada pelo usuário:
    Mesma situação do ausência RD, porém do lado esquerdo agora

  2. Nefrectomia RD/RE selecionada pelo usuário
    Popover com problema, não consegui testar

  3. Rins em Ferradura
    Bloqueou os campos certos, porém está bloqueando os "Cistos Rim Direito" e "Cistos Rim Esquerdo" quando são descritos isoladamente (o certo é não bloquear esses campos). O restante está correto

  4. Ectopia Renal Cruzada
    Correto

Actions #8

Updated by jean sodré 6 months ago

  • Status changed from teste to teste reprovado
Actions #9

Updated by jean sodré 6 months ago

  • Status changed from teste reprovado to teste
Actions #10

Updated by Henrique Novaes 6 months ago

  1. "Ausência RD" selecionada pelo usuário
  • Está bloqueando todo o campo de cirurgias prévias (como comentado anteriormente na outra tarefa, o objetivo é bloquear apenas "nefrectomia total")
  • Ao mudar o numero de "cistos", desmarca sozinho de maneira errada o "ausência RD". Da mesma forma outras alternativas como "nefropatia parenquimatosa RE" e "microcálculos calicinais" também se desmarcam sozinhas ao tentar mudar algo na caixa de seleção deles, mas não interferem diretamente no "ausência RD".
  • precisamos também bloquear as opções do lado direito das seguintes: "nefrectomia parcial", "rim pélvico", "nódulo sólido", "angiomiolipoma", "cisto complexo", "cálculos não obstrutivos" e "microcálculos calicinais" (o certo é estarem bloqueadas já que não temos rim direito). Segue um exemplo:
  1. "Ausência RE" selecionada pelo usuário
  • Aqui consegui marcar outras opções sem problemas, o que falta mesmo é bloquear a possibilidade de marcar o lado esquerdo das mesmas opções acima ("nefrectomia parcial", "rim pélvico", "nódulo sólido", "angiomiolipoma", "cisto complexo", "cálculos não obstrutivos" e "microcálculos calicinais")
  1. "Nefrectomia total direita" selecionada pelo usuário
  • Precisamos bloquear os campos de "ausência RD", "ausência RE", "cistos Rim direito", "Cistos bilaterais", "Dilatação sistema coletor direito", "Cistos bilaterais" e "múltiplos cálculos não obstrutivos bilaterais"
  • precisamos também bloquear as opções do lado direito das seguintes: "nefrectomia parcial", "rim pélvico", "nódulo sólido", "angiomiolipoma", "cisto complexo", "cálculos não obstrutivos" e "microcálculos calicinais" (o certo é estarem bloqueadas já que não temos rim direito).
  1. "Nefrectomia total esquerda" selecionada pelo usuário
  • Precisamos bloquear os campos de "ausência RD", "ausência RE", "cistos Rim esquerdo", "Cistos bilaterais", "Dilatação sistema coletor esquerdo", "Cistos bilaterais" e "múltiplos cálculos não obstrutivos bilaterais"
  • precisamos também bloquear as opções do lado esquerdo das seguintes: "nefrectomia parcial", "rim pélvico", "nódulo sólido", "angiomiolipoma", "cisto complexo", "cálculos não obstrutivos" e "microcálculos calicinais" (o certo é estarem bloqueadas já que não temos rim esquerdo).

Notei também que estamos tendo problemas ao selecionar alguma opção das caixas de seleção de algumas opções:

  • Nefropatia parenquimatosa RD/RE: desmarca sozinho ao clicar na caixa de seleção
    • ureteral: desmarca sozinho ao clicar na caixa de seleção
  • Microcálculos calicinais: desmarca sozinho ao clicar na caixa de seleção
Actions #11

Updated by jean sodré 6 months ago

Sobre o pedido 3 e o pedido 4 "bloquear nefrectomia parcial", eu não não apliquei porque é um radio, então o usuário só vai poder escolher ou um ou outro mesmo... Mas depois me confirma como prefere

Actions #12

Updated by Henrique Novaes 6 months ago

  • Status changed from teste to teste reprovado

Comentei com mais precisão na tarefa #2

Actions

Also available in: Atom PDF