This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
## 10/11/2026 — correcção dirigida das âncoras antes da promoção
|
||||
|
||||
O executor recusou c7901592 por um caso frontendS08 (1falha/1788), mantendo7476dc34 activo. Diagnóstico delimitado: a página tinha dois efeitos de âncora e o teste existente conservava uma única sequência de dependências. A abertura SWOT foi integrada no listener de hash já existente, também para mudanças posteriores de #tarefas, sem alterar a guarda/foco/expansão de S08. O teste S08 aceite conserva as suas asserções; acrescentado caso que alterna #tarefas/#S08, verifica isolamento no dossier e limpeza do listener.15casos dirigidos APIEX/SWOT/âncoras aprovados. Nenhuma alteração de dados, permissões, fontes normativas ou configuração; entrega autorizada retomada no mesmo mecanismo, sem mascarar a falha nem desactivar verificações. Recibos finais continuam a determinar a revisão instalada.
|
||||
|
||||
## 10/11/2026 — Concursos visíveis no menu principal; instalação agrupada autorizada
|
||||
|
||||
Conferência delimitada do destino7476dc34 por SSH autenticado: `procurement.enabled=true`, módulo disponível, tabelas presentes; `/concursos` e raiz HTTP200 com `procurementEnabled=true`. Preservados um concurso em rascunho e zero versões publicadas. O módulo não desapareceu nem estava desligado: a ligação estava dentro de Descoberta. Pedido Tempo «onde foram parar concurso? depois de resolver isso autorizo a instalação»: entrada promovida a grupo próprio **Concursos e anúncios** no menu horizontal comum, com **Consultar concursos e anúncios** e, após autenticação, **Os concursos que acompanho**. Retirada só a ligação duplicada de Descoberta; cinco atalhos principais e autorizações editoriais preservados. Não cria/publica concursos nem muda flags, dados ou schema.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 10/11/2026 — correcção dirigida das âncoras antes da promoção
|
||||
|
||||
O executor recusou c7901592 por um caso frontendS08 (1falha/1788), mantendo7476dc34 activo. Diagnóstico delimitado: a página tinha dois efeitos de âncora e o teste existente conservava uma única sequência de dependências. A abertura SWOT foi integrada no listener de hash já existente, também para mudanças posteriores de #tarefas, sem alterar a guarda/foco/expansão de S08. O teste S08 aceite conserva as suas asserções; acrescentado caso que alterna #tarefas/#S08, verifica isolamento no dossier e limpeza do listener.15casos dirigidos APIEX/SWOT/âncoras aprovados. Nenhuma alteração de dados, permissões, fontes normativas ou configuração; entrega autorizada retomada no mesmo mecanismo, sem mascarar a falha nem desactivar verificações. Recibos finais continuam a determinar a revisão instalada.
|
||||
|
||||
## 10/11/2026 — Concursos visíveis no menu principal; instalação agrupada autorizada
|
||||
|
||||
Conferência delimitada do destino7476dc34 por SSH autenticado: `procurement.enabled=true`, módulo disponível, tabelas presentes; `/concursos` e raiz HTTP200 com `procurementEnabled=true`. Preservados um concurso em rascunho e zero versões publicadas. O módulo não desapareceu nem estava desligado: a ligação estava dentro de Descoberta. Pedido Tempo «onde foram parar concurso? depois de resolver isso autorizo a instalação»: entrada promovida a grupo próprio **Concursos e anúncios** no menu horizontal comum, com **Consultar concursos e anúncios** e, após autenticação, **Os concursos que acompanho**. Retirada só a ligação duplicada de Descoberta; cinco atalhos principais e autorizações editoriais preservados. Não cria/publica concursos nem muda flags, dados ou schema.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 10/11/2026 — correcção dirigida das âncoras antes da promoção
|
||||
|
||||
O executor recusou c7901592 por um caso frontendS08 (1falha/1788), mantendo7476dc34 activo. Diagnóstico delimitado: a página tinha dois efeitos de âncora e o teste existente conservava uma única sequência de dependências. A abertura SWOT foi integrada no listener de hash já existente, também para mudanças posteriores de #tarefas, sem alterar a guarda/foco/expansão de S08. O teste S08 aceite conserva as suas asserções; acrescentado caso que alterna #tarefas/#S08, verifica isolamento no dossier e limpeza do listener.15casos dirigidos APIEX/SWOT/âncoras aprovados. Nenhuma alteração de dados, permissões, fontes normativas ou configuração; entrega autorizada retomada no mesmo mecanismo, sem mascarar a falha nem desactivar verificações. Recibos finais continuam a determinar a revisão instalada.
|
||||
|
||||
## 10/11/2026 — Concursos visíveis no menu principal; instalação agrupada autorizada
|
||||
|
||||
Conferência delimitada do destino7476dc34 por SSH autenticado: `procurement.enabled=true`, módulo disponível, tabelas presentes; `/concursos` e raiz HTTP200 com `procurementEnabled=true`. Preservados um concurso em rascunho e zero versões publicadas. O módulo não desapareceu nem estava desligado: a ligação estava dentro de Descoberta. Pedido Tempo «onde foram parar concurso? depois de resolver isso autorizo a instalação»: entrada promovida a grupo próprio **Concursos e anúncios** no menu horizontal comum, com **Consultar concursos e anúncios** e, após autenticação, **Os concursos que acompanho**. Retirada só a ligação duplicada de Descoberta; cinco atalhos principais e autorizações editoriais preservados. Não cria/publica concursos nem muda flags, dados ou schema.
|
||||
|
||||
@@ -486,25 +486,36 @@ export default function InvestmentPath(path: Path) {
|
||||
window.location.hash,
|
||||
stageCodes.split(','),
|
||||
);
|
||||
if (
|
||||
path.preparation_action &&
|
||||
window.location.hash === '#tarefas'
|
||||
) {
|
||||
const target =
|
||||
root.current.ownerDocument.getElementById('tarefas');
|
||||
if (
|
||||
target?.tagName === 'DETAILS' &&
|
||||
root.current.contains(target)
|
||||
) {
|
||||
(target as HTMLDetailsElement).open = true;
|
||||
target.scrollIntoView({ block: 'start' });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
reveal();
|
||||
window.addEventListener('hashchange', reveal);
|
||||
return () => window.removeEventListener('hashchange', reveal);
|
||||
}, [path.case.id, path.context_opportunity, stageCodes, path.next?.code]);
|
||||
}, [
|
||||
path.case.id,
|
||||
path.context_opportunity,
|
||||
stageCodes,
|
||||
path.next?.code,
|
||||
path.preparation_action?.id,
|
||||
]);
|
||||
const { auth, flash } = usePage<{
|
||||
auth: { user: { id: number } };
|
||||
flash: { success?: string };
|
||||
}>().props;
|
||||
useEffect(() => {
|
||||
if (path.preparation_action && window.location.hash === '#tarefas') {
|
||||
const target = document.getElementById('tarefas');
|
||||
if (target instanceof HTMLDetailsElement) {
|
||||
target.open = true;
|
||||
target.scrollIntoView({ block: 'start' });
|
||||
}
|
||||
}
|
||||
}, [path.preparation_action]);
|
||||
const facts = useForm({
|
||||
version: path.case.version,
|
||||
context_opportunity: path.context_opportunity,
|
||||
|
||||
@@ -270,3 +270,74 @@ test("page reveals the initial hash and server next-stage updates, listens for h
|
||||
globalThis.window = previousWindow;
|
||||
}
|
||||
});
|
||||
|
||||
test('SWOT task anchor uses the shared hash listener inside the dossier and preserves S08', () => {
|
||||
const f = targetFixture(),
|
||||
effects = [],
|
||||
listeners = new Map();
|
||||
const previousWindow = globalThis.window;
|
||||
const task = {
|
||||
tagName: 'DETAILS',
|
||||
open: false,
|
||||
scrollIntoView: (options) => f.calls.push(['task-scroll', options]),
|
||||
};
|
||||
f.root.ownerDocument.getElementById = (id) =>
|
||||
id === 'tarefas' ? task : id === 'S08' ? f.target : null;
|
||||
f.root.contains = (node) => node === task || node === f.target;
|
||||
globalThis.window = {
|
||||
location: { hash: '#tarefas' },
|
||||
addEventListener: (type, fn) => listeners.set(type, fn),
|
||||
removeEventListener: (type) => listeners.delete(type),
|
||||
};
|
||||
try {
|
||||
const h = harness(
|
||||
{
|
||||
investment_context: null,
|
||||
facts: {},
|
||||
fact_reasons: {},
|
||||
phases: {},
|
||||
fintech: null,
|
||||
sector_contexts: [],
|
||||
requests: [],
|
||||
tasks: [],
|
||||
results: [],
|
||||
tools: {},
|
||||
content_sources: [],
|
||||
services: [],
|
||||
steps: [{ code: 'S08', preparation_allowed: true }],
|
||||
preparation_action: {
|
||||
id: 'swot-qa',
|
||||
title: 'Risco QA',
|
||||
kind: 'risk',
|
||||
opportunity: 'opportunity:42',
|
||||
},
|
||||
},
|
||||
{
|
||||
...React,
|
||||
useRef: () => ({ current: f.root }),
|
||||
useEffect: (effect) => effects.push(effect),
|
||||
useState: (initial) => [
|
||||
typeof initial === 'function' ? initial() : initial,
|
||||
() => {},
|
||||
],
|
||||
},
|
||||
);
|
||||
h.renderPage();
|
||||
assert.equal(effects.length, 1);
|
||||
const cleanup = effects[0]();
|
||||
assert.equal(task.open, true);
|
||||
assert.equal(f.phase.open, false);
|
||||
window.location.hash = '#S08';
|
||||
listeners.get('hashchange')();
|
||||
assert.equal(f.phase.open, true);
|
||||
task.open = false;
|
||||
window.location.hash = '#tarefas';
|
||||
listeners.get('hashchange')();
|
||||
assert.equal(task.open, true);
|
||||
assert.equal(f.calls.filter((c) => c[0] === 'task-scroll').length, 2);
|
||||
cleanup();
|
||||
assert.equal(listeners.size, 0);
|
||||
} finally {
|
||||
globalThis.window = previousWindow;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user