From 6520d303f7c00e524ed6618d5e4fca8e867bb4f9 Mon Sep 17 00:00:00 2001 From: nala Date: Wed, 28 Oct 2026 21:00:30 +0200 Subject: [PATCH] fix(territory): combine search and selection in one dropdown field --- .../consolidated-review-matrix-2026-10-03.md | 11 ++ ...talogue-province-coverage-qa-20261028.json | 23 ++++ .../unification/traceability-and-manual.md | 11 ++ .../v2/auditoria-portal/matriz-requisitos.csv | 4 +- .../js/components/investment-territory.tsx | 103 +++--------------- .../js/components/territory-search-select.tsx | 66 +++++++++++ .../frontend/territory-search-select.test.mjs | 56 ++++++++++ 7 files changed, 183 insertions(+), 91 deletions(-) create mode 100644 resources/js/components/territory-search-select.tsx create mode 100644 tests/frontend/territory-search-select.test.mjs diff --git a/docs/investmoz/consolidated-review-matrix-2026-10-03.md b/docs/investmoz/consolidated-review-matrix-2026-10-03.md index 51b576b1..2cccd07d 100644 --- a/docs/investmoz/consolidated-review-matrix-2026-10-03.md +++ b/docs/investmoz/consolidated-review-matrix-2026-10-03.md @@ -1758,3 +1758,14 @@ Relatório: `catalogue-province-coverage-qa-20261028.json`. Instalação pelo pr 28/10 - National coverage: 6 tests / 617 assertions passed across all 11 provincial units, 6 configured corridors and 2 sectors, including descendant hierarchy, sector separation and both province/location entry points. The runtime correction already used the common national hierarchy; Maputo was the reported reproduction, not a geographic limit. Existing publication decisions and unknown district/post/site information remain preserved. This is not a claim that every unrelated portal menu has been audited. No additional runtime change since 1b2ede41; types/build accepted evidence reused. Installation remains pending. + + +28/10 - Before selector delta checks: accepted national catalogue QA 47dae1b7, 6 tests/617 assertions, remains uninstalled. Existing TerritoryLevel and ProvinceSelect required two separate fields (search then select). Tempo requests one dropdown on the search field. Consolidate the shared controls while retaining saved values, hierarchy, endpoints, paging and permission decisions;browser visual proof remains separate. + + + +## 28/10/2026 — selecção territorial num único campo de pesquisa, QA + +Pedido expresso da Tempo: o dropdown deve abrir em «Pesquisar província», sem um segundo controlo «Seleccione». `ProvinceSelect` e `TerritoryLevel` passam a usar o mesmo combobox, aplicado a província, distrito, posto administrativo e localidade. Pesquisar e escolher fica num único campo; a paginação permanece na lista. Escrever ou sair com Escape não substitui a selecção guardada; escolher e limpar são acções expressas. Mantêm-se a hierarquia, os endpoints existentes e os controlos de acesso, sem novos dados ou publicações. + +Quatro testes do contrato de eventos/estado passaram: abertura/escolha, preservação ao escrever/Escape, teclado e bloqueio de resultado antigo durante carregamento, limpeza e dependência do nível anterior. Tipos e compilação QA passaram. As 6 provas nacionais/617 verificações são reutilizadas porque o PHP territorial não mudou. Este delta continua em QA e não comprova apresentação ou sessão real no navegador. Será agrupado com a correcção provincial; falta autenticação SSH antes da entrega, sem nova aprovação organizacional. diff --git a/docs/investmoz/unification/catalogue-province-coverage-qa-20261028.json b/docs/investmoz/unification/catalogue-province-coverage-qa-20261028.json index d4150736..28f23a08 100644 --- a/docs/investmoz/unification/catalogue-province-coverage-qa-20261028.json +++ b/docs/investmoz/unification/catalogue-province-coverage-qa-20261028.json @@ -63,5 +63,28 @@ "district_containment": true, "unrelated_provinces_excluded": true, "test_data": "synthetic fixtures rolled back;accepted published source reused" + }, + "selector_delta": { + "Tempo_request": "Dropdown belongs to Pesquisar província;remove separate Seleccione control", + "scope": [ + "ProvinceSelect", + "TerritoryLevel:province,district,administrative post,locality" + ], + "behaviour": [ + "One combobox input opens the list and searches the existing endpoint", + "Explicit choice commits the existing option;typing or Escape does not clear saved values", + "Arrow keys and Enter select;clear is explicit;dependent levels remain disabled without parent", + "Paging retained inside dropdown;loading cannot commit a stale option" + ], + "QA": { + "event_state_contract_tests": 4, + "failures": 0, + "types": "passed", + "build": "passed", + "limit": "Controlled React component contract;not browser visual/session evidence" + }, + "publication_data_permissions_and_territory_rules": "unchanged", + "national_province_evidence": "6 tests/617 assertions reused;unchanged PHP runtime", + "status": "QA_not_installed" } } diff --git a/docs/investmoz/unification/traceability-and-manual.md b/docs/investmoz/unification/traceability-and-manual.md index 4186c284..cd59479f 100644 --- a/docs/investmoz/unification/traceability-and-manual.md +++ b/docs/investmoz/unification/traceability-and-manual.md @@ -7316,3 +7316,14 @@ Relatório: `catalogue-province-coverage-qa-20261028.json`. Instalação pelo pr 28/10 - National coverage: 6 tests / 617 assertions passed across all 11 provincial units, 6 configured corridors and 2 sectors, including descendant hierarchy, sector separation and both province/location entry points. The runtime correction already used the common national hierarchy; Maputo was the reported reproduction, not a geographic limit. Existing publication decisions and unknown district/post/site information remain preserved. This is not a claim that every unrelated portal menu has been audited. No additional runtime change since 1b2ede41; types/build accepted evidence reused. Installation remains pending. + + +28/10 - Before selector delta checks: accepted national catalogue QA 47dae1b7, 6 tests/617 assertions, remains uninstalled. Existing TerritoryLevel and ProvinceSelect required two separate fields (search then select). Tempo requests one dropdown on the search field. Consolidate the shared controls while retaining saved values, hierarchy, endpoints, paging and permission decisions;browser visual proof remains separate. + + + +## 28/10/2026 — selecção territorial num único campo de pesquisa, QA + +Pedido expresso da Tempo: o dropdown deve abrir em «Pesquisar província», sem um segundo controlo «Seleccione». `ProvinceSelect` e `TerritoryLevel` passam a usar o mesmo combobox, aplicado a província, distrito, posto administrativo e localidade. Pesquisar e escolher fica num único campo; a paginação permanece na lista. Escrever ou sair com Escape não substitui a selecção guardada; escolher e limpar são acções expressas. Mantêm-se a hierarquia, os endpoints existentes e os controlos de acesso, sem novos dados ou publicações. + +Quatro testes do contrato de eventos/estado passaram: abertura/escolha, preservação ao escrever/Escape, teclado e bloqueio de resultado antigo durante carregamento, limpeza e dependência do nível anterior. Tipos e compilação QA passaram. As 6 provas nacionais/617 verificações são reutilizadas porque o PHP territorial não mudou. Este delta continua em QA e não comprova apresentação ou sessão real no navegador. Será agrupado com a correcção provincial; falta autenticação SSH antes da entrega, sem nova aprovação organizacional. diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv index 96ebf6f6..31d972ca 100644 --- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv +++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv @@ -367,10 +367,10 @@ V2-03,"Mesmo dossier, pedido, conversa e tarefa interna; ciclo completo demonstr V2-04,Regras internas e recomendações explicáveis; evidência scoped com autoria/data/hash; aceitação distinta de tarefa,"backlog-mestre.md; § 3.2.3.1, p. 2472–2532; § 5.2, p. 7009–7190",Balcão/orientação,/balcao-virtual/contextos; /balcao-virtual/dossiers; /balcao-virtual/dossiers/{id}; /balcao-virtual/dossiers/{id}/documentos; /balcao-virtual/dossiers/{id}/documentos/{document}; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /balcao-virtual/dossiers/{id}/etapas; /balcao-virtual/dossiers/{id}/fontes; /balcao-virtual/dossiers/{id}/orientacao; /balcao-virtual/dossiers/{id}/pedidos; /balcao-virtual/dossiers/{id}/pressupostos; /balcao-virtual/dossiers/{id}/recomendacoes,"VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-04: Expandir consistência entre mercado, capacidade, recursos e calendário com fontes verificáveis; IA externa continua opcional",P2,V2-04: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-04,1,"[{""id"":""V2-04"",""pedido"":""Regras internas e recomendações explicáveis; evidência scoped com autoria/data/hash; aceitação distinta de tarefa"",""fontes"":[""backlog-mestre.md; § 3.2.3.1, p. 2472–2532; § 5.2, p. 7009–7190""],""aceitacao"":""Expandir consistência entre mercado, capacidade, recursos e calendário com fontes verificáveis; IA externa continua opcional"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""Balcão/orientação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.desk_cases: 1 registos; public.desk_requests: 0 registos; public.desk_institutional_links: 0 registos; public.desk_messages: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, V2-05,Calculadores existentes preservados; fronteira entre explicação e cálculo determinístico mantida,"backlog-mestre.md; § 3.2.3.2, p. 2533–2576; § 3.2.1.5, p. 1746–2160",simuladores,/api/v1/questionnaires/{code}; /api/v1/simulation-drafts; /api/v1/simulation-drafts/claim; /api/v1/simulation-drafts/claim-preview; /api/v1/simulation-drafts/current; /api/v1/simulation-drafts/linkable-businesses; /api/v1/simulation-drafts/{id}; /api/v1/simulation-drafts/{id}/business-link; /api/v1/simulation-drafts/{id}/conversions; /api/v1/simulation-drafts/{id}/touch; /api/v1/simulations; /api/v1/simulations/history,"SimulationExecution, resultados/cenários/fontes, rascunhos e dossier existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Cenário→cálculo→gravação→resultado/dossier correto→nova sessão→PDF/derivadas autorizadas. Sem aprovação/score inventado. Critério individual original preservado; cobertura atual ainda não individualizada.,"Regras financeiras/fiscais separadas; fonte oficial aceite, parâmetros/âmbito/período podem faltar; não substituir por0/taxa atual. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.",V2-05: Reconciliar diplomas/artigos e parâmetros ausentes; nenhuma publicação documental ativa cálculos; não substituir desconhecidos por zero,P2,V2-05: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-05,1,"[{""id"":""V2-05"",""pedido"":""Calculadores existentes preservados; fronteira entre explicação e cálculo determinístico mantida"",""fontes"":[""backlog-mestre.md; § 3.2.3.2, p. 2533–2576; § 3.2.1.5, p. 1746–2160""],""aceitacao"":""Reconciliar diplomas/artigos e parâmetros ausentes; nenhuma publicação documental ativa cálculos; não substituir desconhecidos por zero"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""simuladores""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.simulation_form_drafts: 22 registos; public.simulation_scenarios: 16 registos; public.simulations: 16 registos; public.simulation_tax_rules: tabela ausente,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Cenário→cálculo→gravação→resultado/dossier correto→nova sessão→PDF/derivadas autorizadas. Sem aprovação/score inventado. Critério individual original preservado; cobertura atual ainda não individualizada.,"SimulationExecution, resultados/cenários/fontes, rascunhos e dossier existentes","Regras financeiras/fiscais separadas; fonte oficial aceite, parâmetros/âmbito/período podem faltar; não substituir por0/taxa atual.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: simuladores. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,simuladores,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/SimulationTaxParameterResolver.php; resources/js/components/simulation-form.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"SimulationExecutionTest, SimulationFormDraftTest, SimulationDraftContinuityTest, SimulationTaxRuleGovernanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, V2-06,Bolsa instalada constatada por leitura ativa; acesso e contexto compartilhados,"backlog-mestre.md; § 3.2.3.3, p. 2577–2609; § 3.5, p. 3374–3453",Bolsa/parcerias,/api/v1/partnerships; /api/v1/partnerships/source/{type}/{id}; /management/partnerships-install; /parcerias; /parcerias/candidaturas/{id}; /parcerias/criar; /parcerias/notificacoes/{id}/ler; /parcerias/painel; /parcerias/rascunhos; /parcerias/salas/{id}; /parcerias/salas/{id}/acordo; /parcerias/salas/{id}/documentos,"PartnershipExchange, salas, candidaturas, marcos, acesso/revogação documental. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Candidatura/sala→documento autorizado→revogar→URL antigo negado na sessão corrente/nova, preservar proprietário/original. Critério individual original preservado; cobertura atual ainda não individualizada.","ACL da sala específica; autoria/membros/marcos e documentos privados, independente da ACL de oportunidade. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-06: Avaliar restantes propostas de indicadores, contratos e estados contra implementação real; acordos CTA/câmaras/associações dependem de decisões humanas",P2,V2-06: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-06,1,"[{""id"":""V2-06"",""pedido"":""Bolsa instalada constatada por leitura ativa; acesso e contexto compartilhados"",""fontes"":[""backlog-mestre.md; § 3.2.3.3, p. 2577–2609; § 3.5, p. 3374–3453""],""aceitacao"":""Avaliar restantes propostas de indicadores, contratos e estados contra implementação real; acordos CTA/câmaras/associações dependem de decisões humanas"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""Bolsa/parcerias""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.portal_partnerships: 0 registos; public.partnership_rooms: 0 registos; public.partnership_interests: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Candidatura/sala→documento autorizado→revogar→URL antigo negado na sessão corrente/nova, preservar proprietário/original. Critério individual original preservado; cobertura atual ainda não individualizada.","PartnershipExchange, salas, candidaturas, marcos, acesso/revogação documental","ACL da sala específica; autoria/membros/marcos e documentos privados, independente da ACL de oportunidade.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: parcerias. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,parcerias,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/PartnershipExchange.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,PartnershipExchangeTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, -V2-07,Menu de gestão preserva rotas e permissões existentes,"backlog-mestre.md; § 3.2.3.4–3.2.3.10, p. 2610–3339",dashboard/perfis,/api/v1/investment/companies/{id?}; /api/v1/investment/notifications; /api/v1/investment/notifications/{id}/read; /api/v1/investment/profile; /api/v1/investment/submissions/{id}/messages; /api/v1/investment/submissions/{id}/revisions/{version}; /dashboard; /investidor/companies/{id?}; /investidor/manifestacoes/{id}/messages; /investidor/manifestacoes/{id}/revisions/{version}; /investidor/notifications; /investidor/notifications/{id}/read,"Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",28/10:6 tests/617 assertions;shared province/location filters;prior types/build reused. History: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,"28/10:national QA;11 provincial units,6 corridors,2 sectors;not installed. History: 28/10:consulta provincial corrigida em QA,sem instalação;Maputo Agronegócio 0→5;histórico preservado. Histórico: 28/10:menus 6e8de43a instalados e delta técnico conferido;conferência visual autenticada pendente;aceitações anteriores preservadas. Histórico: 28/10:reorganização implementada/verificada estruturalmente em QA,sem instalação;validação visual/sessão real pendente;âmbito anterior preservado. Histórico: 28/10:revisão de apresentação emQA após relato Tempo;verificação do delta pendente,aceitação anterior preservada no seu âmbito. Histórico: Sem evidência suficiente","28/10:falta entrega e conferência visual do delta provincial;outros menus não declarados integralmente auditados. Lacuna anterior: 28/10:omissões/ocultação corrigidas no código instalado;resta observar a sessão real e responsividade sem presumir perda de permissões. Lacuna anterior: 28/10:omissão de subdestinos e ocultação da área de trabalho corrigidas no candidato QA;falta conferência visual e capacidades reais da sessão,sem presumir perda de permissões. Lacuna histórica: 28/10:confirmadas omissão de subdestinos na barra lateral e ocultação da área de trabalho no menu da conta;props/acesso da sessão real não demonstrados,sem presumir falta de permissões. Lacuna histórica: Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-07: Dashboard integral, workflow editorial, métricas e APIs adicionais: reconciliação individual pendente; não criar tabelas paralelas a entidades existentes",P2,V2-07: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-07,1,"[{""id"":""V2-07"",""pedido"":""Menu de gestão preserva rotas e permissões existentes"",""fontes"":[""backlog-mestre.md; § 3.2.3.4–3.2.3.10, p. 2610–3339""],""aceitacao"":""Dashboard integral, workflow editorial, métricas e APIs adicionais: reconciliação individual pendente; não criar tabelas paralelas a entidades existentes"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""dashboard/perfis""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.investment_accounts: 0 registos; public.investment_company_declarations: 0 registos; public.investment_submissions: 3 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: perfis. Esforço de código adicional só após lacuna reproduzida.,"28/10:catalogue-province-coverage-qa-20261028.json;4testes/70verificações,tipos/build/PHP;contexto aprovado em23/10 reutilizado;sem novas publicações/permissões. Evidência anterior: 28/10:navigation-git-delivery-20261028.json;Git normal,backup/restauro176tabelas,369ficheiros/configuração preservados,base interna preservada,16testes QA reutilizados;prova técnica não equivale a visual. Evidência anterior: 28/10:navigation-reconciliation-qa-20261028.json;inventário antes dos testes,16testes/0falhas,4cenários/todos destinos preservados,tipos/build/PHP;SSR não é prova visual activa;6d147693/dados/fontes/perfis/históricos conservados. Evidência histórica: 28/10:inventário anterior em outputs/navigation-reconciliation-20261028/preservation-before.json;6d147693/base435Gurué e provas aceites preservados;fonteAppSidebar/PortalGroupedMenu/ContentManagement conferida antes dos testes do delta. Evidências anteriores: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.",perfis,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/DashboardController.php; app/Services/CountryCatalogue.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentWorkspaceTest, InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, +V2-07,Menu de gestão preserva rotas e permissões existentes,"backlog-mestre.md; § 3.2.3.4–3.2.3.10, p. 2610–3339",dashboard/perfis,/api/v1/investment/companies/{id?}; /api/v1/investment/notifications; /api/v1/investment/notifications/{id}/read; /api/v1/investment/profile; /api/v1/investment/submissions/{id}/messages; /api/v1/investment/submissions/{id}/revisions/{version}; /dashboard; /investidor/companies/{id?}; /investidor/manifestacoes/{id}/messages; /investidor/manifestacoes/{id}/revisions/{version}; /investidor/notifications; /investidor/notifications/{id}/read,"Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",28/10:6 tests/617 assertions;shared province/location filters;prior types/build reused. History: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,"28/10:selector territorial único em QA,sem instalação;preservação e cobertura nacional mantidas. Histórico: 28/10:national QA;11 provincial units,6 corridors,2 sectors;not installed. History: 28/10:consulta provincial corrigida em QA,sem instalação;Maputo Agronegócio 0→5;histórico preservado. Histórico: 28/10:menus 6e8de43a instalados e delta técnico conferido;conferência visual autenticada pendente;aceitações anteriores preservadas. Histórico: 28/10:reorganização implementada/verificada estruturalmente em QA,sem instalação;validação visual/sessão real pendente;âmbito anterior preservado. Histórico: 28/10:revisão de apresentação emQA após relato Tempo;verificação do delta pendente,aceitação anterior preservada no seu âmbito. Histórico: Sem evidência suficiente","28/10:falta entrega e conferência visual do delta provincial;outros menus não declarados integralmente auditados. Lacuna anterior: 28/10:omissões/ocultação corrigidas no código instalado;resta observar a sessão real e responsividade sem presumir perda de permissões. Lacuna anterior: 28/10:omissão de subdestinos e ocultação da área de trabalho corrigidas no candidato QA;falta conferência visual e capacidades reais da sessão,sem presumir perda de permissões. Lacuna histórica: 28/10:confirmadas omissão de subdestinos na barra lateral e ocultação da área de trabalho no menu da conta;props/acesso da sessão real não demonstrados,sem presumir falta de permissões. Lacuna histórica: Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-07: Dashboard integral, workflow editorial, métricas e APIs adicionais: reconciliação individual pendente; não criar tabelas paralelas a entidades existentes",P2,V2-07: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-07,1,"[{""id"":""V2-07"",""pedido"":""Menu de gestão preserva rotas e permissões existentes"",""fontes"":[""backlog-mestre.md; § 3.2.3.4–3.2.3.10, p. 2610–3339""],""aceitacao"":""Dashboard integral, workflow editorial, métricas e APIs adicionais: reconciliação individual pendente; não criar tabelas paralelas a entidades existentes"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""dashboard/perfis""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.investment_accounts: 0 registos; public.investment_company_declarations: 0 registos; public.investment_submissions: 3 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: perfis. Esforço de código adicional só após lacuna reproduzida.,"28/10:selector_delta em catalogue-province-coverage-qa-20261028.json;4testes de eventos/estado,tipos/build;provas nacionais6/617 reutilizadas. Histórico: 28/10:catalogue-province-coverage-qa-20261028.json;4testes/70verificações,tipos/build/PHP;contexto aprovado em23/10 reutilizado;sem novas publicações/permissões. Evidência anterior: 28/10:navigation-git-delivery-20261028.json;Git normal,backup/restauro176tabelas,369ficheiros/configuração preservados,base interna preservada,16testes QA reutilizados;prova técnica não equivale a visual. Evidência anterior: 28/10:navigation-reconciliation-qa-20261028.json;inventário antes dos testes,16testes/0falhas,4cenários/todos destinos preservados,tipos/build/PHP;SSR não é prova visual activa;6d147693/dados/fontes/perfis/históricos conservados. Evidência histórica: 28/10:inventário anterior em outputs/navigation-reconciliation-20261028/preservation-before.json;6d147693/base435Gurué e provas aceites preservados;fonteAppSidebar/PortalGroupedMenu/ContentManagement conferida antes dos testes do delta. Evidências anteriores: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.",perfis,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/DashboardController.php; app/Services/CountryCatalogue.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentWorkspaceTest, InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, V2-08,Projetos/clusters/zonas pesquisáveis e fichas navegáveis em QA; esquema territorial ativo constatado,"backlog-mestre.md; § 4.6.1, p. 3740–6267",cartografia/relações,/api/v1/geo/drafts; /api/v1/geo/search; /api/v1/geo/sources; /api/v1/geo/sources/{id}/transitions; /api/v1/geo/territories; /api/v1/geo/territories/{id}; /api/v1/geo/territories/{id}/transitions; /api/v1/geo/territories/{type}/{id}; /api/v1/geo/{collection}; /api/v1/investment/compare; /api/v1/investment/export; /api/v1/investment/favourites/{id},"InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada.","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-08: Revisão documental de cada área, limites/polígonos oficiais, disponibilidade, capacidade e histórico; links territoriais existentes não certificam todas as correções propostas",P2,V2-08: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-08,1,"[{""id"":""V2-08"",""pedido"":""Projetos/clusters/zonas pesquisáveis e fichas navegáveis em QA; esquema territorial ativo constatado"",""fontes"":[""backlog-mestre.md; § 4.6.1, p. 3740–6267""],""aceitacao"":""Revisão documental de cada área, limites/polígonos oficiais, disponibilidade, capacidade e histórico; links territoriais existentes não certificam todas as correções propostas"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""cartografia/relações""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.geo_locations: 1990 registos; public.geo_geometries: 0 registos; public.project_locations: 28 registos; public.cluster_projects: 13 registos; public.opportunity_projects: 0 registos; public.opportunity_clusters: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Demonstrar consumidor: pesquisar→selecionar→gravar→nova sessão→renderizar limite correto; conservar pai, código e fonte. Critério individual original preservado; cobertura atual ainda não individualizada.","InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: território. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,território,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",resources/js/components/investment-territory.tsx; app/Http/Controllers/InvestmentTerritoryController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentTerritoryTest, TerritorialRegistryTest, InvestmentTerritorialTraceabilityTest, InvestmentZoneTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, V2-09,"Nenhum score de sucesso, disponibilidade ou elegibilidade inventado","backlog-mestre.md; § 4.6.1.14–4.6.1.18, p. 4252–6267",governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-09: Validar pesos, lacunas, condicionantes e saídas explicáveis; não executar seeds demonstrativos contra dados ativos",P2,V2-09: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-09,1,"[{""id"":""V2-09"",""pedido"":""Nenhum score de sucesso, disponibilidade ou elegibilidade inventado"",""fontes"":[""backlog-mestre.md; § 4.6.1.14–4.6.1.18, p. 4252–6267""],""aceitacao"":""Validar pesos, lacunas, condicionantes e saídas explicáveis; não executar seeds demonstrativos contra dados ativos"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, -V2-10,Menus e preparação não limitados aos pilotos,"backlog-mestre.md; § 4.1–4.7, p. 3646–6994",dashboard/perfis,/api/v1/investment/companies/{id?}; /api/v1/investment/notifications; /api/v1/investment/notifications/{id}/read; /api/v1/investment/profile; /api/v1/investment/submissions/{id}/messages; /api/v1/investment/submissions/{id}/revisions/{version}; /dashboard; /investidor/companies/{id?}; /investidor/manifestacoes/{id}/messages; /investidor/manifestacoes/{id}/revisions/{version}; /investidor/notifications; /investidor/notifications/{id}/read,"Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",28/10:6 tests/617 assertions;shared province/location filters;prior types/build reused. History: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,"28/10:national QA;11 provincial units,6 corridors,2 sectors;not installed. History: 28/10:consulta provincial corrigida em QA,sem instalação;Maputo Agronegócio 0→5;histórico preservado. Histórico: 28/10:menus 6e8de43a instalados e delta técnico conferido;conferência visual autenticada pendente;aceitações anteriores preservadas. Histórico: 28/10:reorganização implementada/verificada estruturalmente em QA,sem instalação;validação visual/sessão real pendente;âmbito anterior preservado. Histórico: 28/10:revisão de apresentação emQA após relato Tempo;verificação do delta pendente,aceitação anterior preservada no seu âmbito. Histórico: Sem evidência suficiente","28/10:falta entrega e conferência visual do delta provincial;outros menus não declarados integralmente auditados. Lacuna anterior: 28/10:omissões/ocultação corrigidas no código instalado;resta observar a sessão real e responsividade sem presumir perda de permissões. Lacuna anterior: 28/10:omissão de subdestinos e ocultação da área de trabalho corrigidas no candidato QA;falta conferência visual e capacidades reais da sessão,sem presumir perda de permissões. Lacuna histórica: 28/10:confirmadas omissão de subdestinos na barra lateral e ocultação da área de trabalho no menu da conta;props/acesso da sessão real não demonstrados,sem presumir falta de permissões. Lacuna histórica: Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-10: Pilotos reais de agricultura, indústria e turismo; baseline e métricas com consentimento, responsáveis reais e cobertura inclusiva",P2,V2-10: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-10,1,"[{""id"":""V2-10"",""pedido"":""Menus e preparação não limitados aos pilotos"",""fontes"":[""backlog-mestre.md; § 4.1–4.7, p. 3646–6994""],""aceitacao"":""Pilotos reais de agricultura, indústria e turismo; baseline e métricas com consentimento, responsáveis reais e cobertura inclusiva"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""dashboard/perfis""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.investment_accounts: 0 registos; public.investment_company_declarations: 0 registos; public.investment_submissions: 3 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: perfis. Esforço de código adicional só após lacuna reproduzida.,"28/10:catalogue-province-coverage-qa-20261028.json;4testes/70verificações,tipos/build/PHP;contexto aprovado em23/10 reutilizado;sem novas publicações/permissões. Evidência anterior: 28/10:navigation-git-delivery-20261028.json;Git normal,backup/restauro176tabelas,369ficheiros/configuração preservados,base interna preservada,16testes QA reutilizados;prova técnica não equivale a visual. Evidência anterior: 28/10:navigation-reconciliation-qa-20261028.json;inventário antes dos testes,16testes/0falhas,4cenários/todos destinos preservados,tipos/build/PHP;SSR não é prova visual activa;6d147693/dados/fontes/perfis/históricos conservados. Evidência histórica: 28/10:inventário anterior em outputs/navigation-reconciliation-20261028/preservation-before.json;6d147693/base435Gurué e provas aceites preservados;fonteAppSidebar/PortalGroupedMenu/ContentManagement conferida antes dos testes do delta. Evidências anteriores: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.",perfis,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/DashboardController.php; app/Services/CountryCatalogue.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentWorkspaceTest, InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, +V2-10,Menus e preparação não limitados aos pilotos,"backlog-mestre.md; § 4.1–4.7, p. 3646–6994",dashboard/perfis,/api/v1/investment/companies/{id?}; /api/v1/investment/notifications; /api/v1/investment/notifications/{id}/read; /api/v1/investment/profile; /api/v1/investment/submissions/{id}/messages; /api/v1/investment/submissions/{id}/revisions/{version}; /dashboard; /investidor/companies/{id?}; /investidor/manifestacoes/{id}/messages; /investidor/manifestacoes/{id}/revisions/{version}; /investidor/notifications; /investidor/notifications/{id}/read,"Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",28/10:6 tests/617 assertions;shared province/location filters;prior types/build reused. History: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,"28/10:selector territorial único em QA,sem instalação;preservação e cobertura nacional mantidas. Histórico: 28/10:national QA;11 provincial units,6 corridors,2 sectors;not installed. History: 28/10:consulta provincial corrigida em QA,sem instalação;Maputo Agronegócio 0→5;histórico preservado. Histórico: 28/10:menus 6e8de43a instalados e delta técnico conferido;conferência visual autenticada pendente;aceitações anteriores preservadas. Histórico: 28/10:reorganização implementada/verificada estruturalmente em QA,sem instalação;validação visual/sessão real pendente;âmbito anterior preservado. Histórico: 28/10:revisão de apresentação emQA após relato Tempo;verificação do delta pendente,aceitação anterior preservada no seu âmbito. Histórico: Sem evidência suficiente","28/10:falta entrega e conferência visual do delta provincial;outros menus não declarados integralmente auditados. Lacuna anterior: 28/10:omissões/ocultação corrigidas no código instalado;resta observar a sessão real e responsividade sem presumir perda de permissões. Lacuna anterior: 28/10:omissão de subdestinos e ocultação da área de trabalho corrigidas no candidato QA;falta conferência visual e capacidades reais da sessão,sem presumir perda de permissões. Lacuna histórica: 28/10:confirmadas omissão de subdestinos na barra lateral e ocultação da área de trabalho no menu da conta;props/acesso da sessão real não demonstrados,sem presumir falta de permissões. Lacuna histórica: Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","V2-10: Pilotos reais de agricultura, indústria e turismo; baseline e métricas com consentimento, responsáveis reais e cobertura inclusiva",P2,V2-10: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-10,1,"[{""id"":""V2-10"",""pedido"":""Menus e preparação não limitados aos pilotos"",""fontes"":[""backlog-mestre.md; § 4.1–4.7, p. 3646–6994""],""aceitacao"":""Pilotos reais de agricultura, indústria e turismo; baseline e métricas com consentimento, responsáveis reais e cobertura inclusiva"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""dashboard/perfis""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.investment_accounts: 0 registos; public.investment_company_declarations: 0 registos; public.investment_submissions: 3 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Reutilizar provas existentes; suplementar autorização/revogação/elevação por ação/consumidor, sem sistema paralelo. Critério individual original preservado; cobertura atual ainda não individualizada.","Fortify, PortalProfileAdministration/Access, grants, policies, portal_security_approvals e menus atuais","030000→040000 instalados, seis categorias ON; contas/grants reais concluídos. Autorizações por tipo/org e independência mantidas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: perfis. Esforço de código adicional só após lacuna reproduzida.,"28/10:selector_delta em catalogue-province-coverage-qa-20261028.json;4testes de eventos/estado,tipos/build;provas nacionais6/617 reutilizadas. Histórico: 28/10:catalogue-province-coverage-qa-20261028.json;4testes/70verificações,tipos/build/PHP;contexto aprovado em23/10 reutilizado;sem novas publicações/permissões. Evidência anterior: 28/10:navigation-git-delivery-20261028.json;Git normal,backup/restauro176tabelas,369ficheiros/configuração preservados,base interna preservada,16testes QA reutilizados;prova técnica não equivale a visual. Evidência anterior: 28/10:navigation-reconciliation-qa-20261028.json;inventário antes dos testes,16testes/0falhas,4cenários/todos destinos preservados,tipos/build/PHP;SSR não é prova visual activa;6d147693/dados/fontes/perfis/históricos conservados. Evidência histórica: 28/10:inventário anterior em outputs/navigation-reconciliation-20261028/preservation-before.json;6d147693/base435Gurué e provas aceites preservados;fonteAppSidebar/PortalGroupedMenu/ContentManagement conferida antes dos testes do delta. Evidências anteriores: outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.",perfis,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/DashboardController.php; app/Services/CountryCatalogue.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InvestmentWorkspaceTest, InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, V2-11,Inventário acessível atualizado: 248 ficheiros e 63 anexos incorporados; exemplares de formulários mantidos,"backlog-mestre.md; § 5.1; § 5.2 didática–5.6, p. 7007–7008 e 7191–7558",biblioteca,//; /Simulador; /api/v1/ai/documents; /api/v1/documents/recommendations; /api/v2/investment/admin/legal-sources; /api/v2/investment/admin/legal-sources/{id}/{action}; /apoio; /balcao-virtual; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /como-investir; /documentos; /documentos/{id},"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,"V2-11: Reconciliar todo o conteúdo do portal público, guias/árvores, autorização e atualização por ficheiro; inventário local não é crawl integral do site público",P2,V2-11: Estado da primeira entrega; confirmações posteriores permanecem separadas,V2-11,1,"[{""id"":""V2-11"",""pedido"":""Inventário acessível atualizado: 248 ficheiros e 63 anexos incorporados; exemplares de formulários mantidos"",""fontes"":[""backlog-mestre.md; § 5.1; § 5.2 didática–5.6, p. 7007–7008 e 7191–7558""],""aceitacao"":""Reconciliar todo o conteúdo do portal público, guias/árvores, autorização e atualização por ficheiro; inventário local não é crawl integral do site público"",""estado"":""parcial"",""variantes"":""Estado da primeira entrega; confirmações posteriores permanecem separadas"",""modulo"":""biblioteca""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.documents: 4 registos; public.portal_resources: 4 registos; public.portal_resource_links: 19 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas",Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: documentos e legado. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,documentos e legado,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/PortalServicesController.php; app/Jobs/ScanDocumentForMalware.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"PortalServicesTest, DocumentLibrarySchemaCompatibilityTest, ImportDocumentBatchTest, ClamDScannerIntegrationTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, V2-12,"Validação interna não equivale a licença, aprovação, benefício fiscal ou ato administrativo","backlog-mestre.md; § 6, p. 7559–7687; § 3.2.1, p. 1453–2171 diff --git a/resources/js/components/investment-territory.tsx b/resources/js/components/investment-territory.tsx index 4d50f07b..2a888c6b 100644 --- a/resources/js/components/investment-territory.tsx +++ b/resources/js/components/investment-territory.tsx @@ -3,6 +3,7 @@ import { useEffect, useId, useState } from 'react'; import { api } from '@/pages/investment/shared'; import { replaceTerritoryPath } from '@/lib/territory-path.js'; import TerritoryGeometryPreview from './territory-geometry-preview'; +import TerritorySearchSelect from './territory-search-select'; export type TerritoryOption = { id: string; @@ -135,37 +136,11 @@ export function ProvinceSelect({ total={options.length} retry={() => setRetry((value) => value + 1)} /> - setSearch(event.target.value)} - /> - + option.name === value) ?? { id: value, name: value } : undefined} + onChange={(option) => onChange(option?.name ?? '')} /> {geometryFeedback &&

{geometryFeedback}

} {labels[index]} - { - setSearch(event.target.value); - setPage(1); - }} - placeholder={`Pesquisar ${labels[index].toLowerCase()}`} - /> - + { setSearch(query); setPage(1); }} + options={options} selected={selected} onChange={onChange} loading={loading} error={fieldError || error}> +
+ {page > 1 && } + {more && } +
+
{loading &&

A carregar…

} - {fieldError && ( - - )} -
- {page > 1 && ( - - )} - {more && ( - - )} -
); } diff --git a/resources/js/components/territory-search-select.tsx b/resources/js/components/territory-search-select.tsx new file mode 100644 index 00000000..0719477b --- /dev/null +++ b/resources/js/components/territory-search-select.tsx @@ -0,0 +1,66 @@ +import { useEffect, useRef, useState, type ReactNode } from 'react'; + +type Choice = { id: string; name: string; source_code?: string | null }; + +/** One search field owns the list and commits only an explicitly chosen option. */ +export default function TerritorySearchSelect({ + id, label, search, onSearch, options, selected, onChange, disabled = false, + loading = false, error, required = false, className, placeholder, children, +}: { + id: string; label: string; search: string; onSearch: (query: string) => void; + options: T[]; selected?: T; onChange: (option?: T) => void; + disabled?: boolean; loading?: boolean; error?: string; required?: boolean; + className?: string; placeholder?: string; children?: ReactNode; +}) { + const [open, setOpen] = useState(false); + const [active, setActive] = useState(-1); + const activeRef = useRef(null); + const expanded = open && !disabled; + const listId = `${id}-options`; + useEffect(() => { if (expanded) activeRef.current?.scrollIntoView({ block: 'nearest' }); }, [active, expanded]); + const close = () => { setOpen(false); setActive(-1); onSearch(''); }; + const choose = (option?: T) => { onChange(option); close(); }; + return
{ + if (!event.currentTarget.contains(event.relatedTarget as Node | null)) close(); + }}> + { setOpen(true); setActive(-1); onSearch(''); }} + onClick={() => setOpen(true)} + onChange={(event) => { setOpen(true); setActive(-1); onSearch(event.target.value); }} + onKeyDown={(event) => { + if (event.key === 'Escape') { event.preventDefault(); close(); } + if (event.key === 'ArrowDown' || event.key === 'ArrowUp') { + event.preventDefault(); setOpen(true); + setActive((current) => !options.length ? -1 : event.key === 'ArrowDown' + ? Math.min(current + 1, options.length - 1) : current < 0 ? options.length - 1 : Math.max(0, current - 1)); + } + if (event.key === 'Enter' && expanded) { + event.preventDefault(); + if (!loading && options[active < 0 ? 0 : active]) choose(options[active < 0 ? 0 : active]); + } + }} /> + {selected && !disabled && } + {error && } + {expanded &&
+
+ {loading &&

A carregar…

} + {!loading && options.length === 0 &&

{error ? 'Não foi possível carregar as opções.' : 'Sem resultados para esta pesquisa.'}

} + {options.map((option, index) => )} +
+ {children} +
} +
; +} diff --git a/tests/frontend/territory-search-select.test.mjs b/tests/frontend/territory-search-select.test.mjs new file mode 100644 index 00000000..2b94b758 --- /dev/null +++ b/tests/frontend/territory-search-select.test.mjs @@ -0,0 +1,56 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import fs from 'node:fs'; +import {createRequire} from 'node:module'; +import React from 'react'; +import ts from 'typescript'; + +// Exercise the real component's event/state contract; this is not browser visual QA. +const require=createRequire(import.meta.url); +const source=fs.readFileSync(new URL('../../resources/js/components/territory-search-select.tsx',import.meta.url),'utf8'); +const compiled=ts.transpileModule(source,{compilerOptions:{module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2022,jsx:ts.JsxEmit.ReactJSX}}).outputText; +function harness(overrides={}){ + const memory=[];let cursor=0;const chosen=[]; + const hooks={...React,useState(initial){const i=cursor++;if(!(i in memory))memory[i]=initial;return[memory[i],value=>{memory[i]=typeof value==='function'?value(memory[i]):value;}];},useRef:()=>({current:null}),useEffect:()=>{}}; + const module={exports:{}}; + new Function('require','module','exports',compiled)(name=>name==='react'?hooks:require(name),module,module.exports); + const options=[{id:'province-a',name:'Nampula'},{id:'province-b',name:'Maputo Província'}]; + const props={id:'territory',label:'Província',search:'',options,onSearch(query){props.search=query;},onChange(option){chosen.push(option);props.selected=option;},...overrides}; + let tree; + const flat=node=>!node||typeof node!=='object'?[]:[node,...React.Children.toArray(node.props?.children).flatMap(flat)]; + const render=()=>{cursor=0;tree=module.exports.default(props);return tree;}; + const find=predicate=>flat(tree).find(predicate); + const input=()=>find(node=>node.type==='input'); + const key=value=>input().props.onKeyDown({key:value,preventDefault(){}}); + render();return{props,chosen,render,find,input,key,options}; +} +test('one search input owns the dropdown; the separate select is absent',()=>{ + const h=harness();assert.equal(h.find(node=>node.type==='select'),undefined); + assert.equal(h.input().props.role,'combobox');assert.equal(h.input().props['aria-expanded'],false); + h.input().props.onFocus();h.render(); + assert.equal(h.input().props['aria-expanded'],true); + assert.ok(h.find(node=>node.props?.role==='listbox')); + h.find(node=>node.props?.role==='option'&&node.props.id==='territory-options-1').props.onClick();h.render(); + assert.deepEqual(h.chosen,[h.options[1]]);assert.equal(h.input().props.value,'Maputo Província'); + assert.equal(h.input().props['aria-expanded'],false); +}); +test('typing and Escape preserve the existing selection until an option is explicitly chosen',()=>{ + const selected={id:'saved',name:'Selecção guardada fora desta página'};const h=harness({selected}); + h.input().props.onFocus();h.render();h.input().props.onChange({target:{value:'Map'}});h.render(); + assert.equal(h.props.search,'Map');assert.deepEqual(h.chosen,[]); + h.key('Escape');h.render();assert.equal(h.input().props.value,selected.name);assert.deepEqual(h.chosen,[]); +}); +test('arrow keys and Enter choose from the list; loading cannot commit an old result',()=>{ + const h=harness();h.input().props.onFocus();h.render();h.key('ArrowDown');h.render();h.key('ArrowDown');h.render(); + assert.equal(h.input().props['aria-activedescendant'],'territory-options-1'); + h.key('Enter');h.render();assert.deepEqual(h.chosen,[h.options[1]]); + const busy=harness({loading:true});busy.input().props.onFocus();busy.render();busy.key('Enter'); + assert.deepEqual(busy.chosen,[]); +}); +test('clear is explicit; disabled dependent levels cannot expose the dropdown',()=>{ + const h=harness({selected:{id:'saved',name:'Nampula'}}); + h.find(node=>node.props?.['aria-label']==='Limpar Província').props.onClick();h.render(); + assert.deepEqual(h.chosen,[undefined]);assert.equal(h.input().props.value,''); + const disabled=harness({disabled:true});assert.equal(disabled.input().props.disabled,true); + assert.equal(disabled.find(node=>node.props?.role==='listbox'),undefined); +});