fix(offers): align private navigation with portal dropdown menus
tests / ci (push) Waiting to run

This commit is contained in:
2026-11-14 19:07:14 +02:00
parent d954c83b78
commit 3558647e8d
13 changed files with 693 additions and 45 deletions
@@ -10208,3 +10208,6 @@ Após `ed2fd86f`, foi autorizada exclusivamente a correcção da continuidade. `
# Preparação final de homologação privada das Ofertas — 14/11/2026
A Tempo aceitou tecnicamente `9a014268` e autorizou apenas preparação. Parecer em `../v2/auditoria-portal/ofertas-prontidao-homologacao-20261114.md`: integração privada em QA demonstrada, 48 hashes dos recibos F5/correcção conferidos e bundle Git local da candidata verificado. Sem diferenças de migrações/locks face ao recibo histórico `96f51096`; destino actual ainda por conferir. Homologação privada recomendável com publicação fechada, condicionada a revisão/schema/runtime reais, backup/restauro actual, delta e reversão compatível, e nova autorização expressa. GD/WebP ausente no PHP QA bloqueia derivadas, preservando originais; visual/móvel, email real e decisões jurídicas mantêm pendências próprias. Ensaio de correio preparado com dados sintéticos e caixa de teste a designar, sem fila/destinatários operacionais. Nenhuma instalação, migração, alteração operacional, envio de email ou activação pública nesta preparação. RF-MN-003 e matriz final distinguem aprovação técnica, instalação e publicação.
# Menus das Ofertas uniformizados na prévia QA — 14/11/2026
Por pedido expresso da Tempo durante a conferência, a navegação privada das Ofertas reutiliza o padrão horizontal com dropdown do portal. Área de trabalho → Ofertas agrupa consulta/preparação conforme os acessos existentes; o módulo agrupa Ofertas, estados e acompanhamento em dropdowns responsivos. Mudar de estado conserva os filtros de acompanhamento/denúncias. Todas as páginas Ofertas usam o mesmo enquadramento PortalNavigation. Não foram alteradas permissões, rotas, publicação ou dados. Passaram 29 testes de navegação, tipos, lint focado e build QA; um aviso de lint preexistente fora do delta foi preservado. A lista e os dois exemplos já existentes responderam HTTP 200 com os novos assets, mantendo a sessão e os dados da prévia. Conferência visual pelo utilizador pendente; sem instalação em homologação. Recibo: `outputs/offers-menu-qa-20261114/qa-result.json`. O bundle anterior `9a014268` permanece preservado e não inclui este novo delta visual.
File diff suppressed because one or more lines are too long
+340
View File
@@ -0,0 +1,340 @@
> build
> vp build
npm.cmd : [plugin laravel:fonts] Optimized font fallbacks require the optional "fontaine" package. Install it, or set
"optimizedFallbacks: false" on your fonts to disable the feature.
At line:2 char:30
+ ... _BUILD='1'; npm.cmd run build *> outputs/offers-menu-qa-20261114/buil ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: ([plugin laravel...le the feature.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
transforming...
✓ 2849 modules transformed.
rendering chunks...
computing gzip size...
public/build-qa-opportunities/assets/layers-BWBAp2CZ.png 0.69 kB
public/build-qa-opportunities/assets/layers-2x-Bpkbi35X.png 1.25 kB
public/build-qa-opportunities/assets/marker-icon-hN30_KVU.png 1.46 kB
public/build-qa-opportunities/assets/noto-sans-400-normal-BTkUljjl.woff2 13.12 kB
public/build-qa-opportunities/assets/noto-sans-700-normal-CrvTEWhy.woff2 13.46 kB
public/build-qa-opportunities/assets/noto-sans-500-normal-DCA2Z9Cj.woff2 13.49 kB
public/build-qa-opportunities/assets/noto-sans-600-normal-Dkgu5AE5.woff2 13.49 kB
public/build-qa-opportunities/assets/noto-serif-400-normal-BV_iYGc9.woff2 14.40 kB
public/build-qa-opportunities/assets/noto-serif-700-normal-CIw17UNa.woff2 15.23 kB
public/build-qa-opportunities/assets/noto-serif-600-normal-BiuDA9L7.woff2 15.31 kB
public/build-qa-opportunities/assets/noto-sans-400-normal-DPpKfCgK.woff 16.68 kB
public/build-qa-opportunities/assets/instrument-sans-400-normal-DRC__1Mx.woff2 16.86 kB
public/build-qa-opportunities/assets/noto-sans-700-normal-ZyrKABVF.woff 16.95 kB
public/build-qa-opportunities/assets/noto-sans-500-normal-CDPngY5C.woff 17.09 kB
public/build-qa-opportunities/assets/noto-sans-600-normal-DVJMj_t0.woff 17.10 kB
public/build-qa-opportunities/assets/instrument-sans-500-normal-Dk9ku72i.woff2 17.23 kB
public/build-qa-opportunities/assets/instrument-sans-600-normal-B7fBEWYG.woff2 17.40 kB
public/build-qa-opportunities/assets/noto-serif-400-normal-DT0cwSa_.woff 17.81 kB
public/build-qa-opportunities/fonts-manifest.json 18.53 kB │ gzip: 1.23 kB
public/build-qa-opportunities/assets/noto-serif-700-normal-mX-AlFMT.woff 18.54 kB
public/build-qa-opportunities/assets/noto-serif-600-normal-RZopCp-J.woff 18.68 kB
public/build-qa-opportunities/assets/instrument-sans-400-normal-D1W7dsQl.woff 21.24 kB
public/build-qa-opportunities/assets/instrument-sans-500-normal-Z6ESRlEs.woff 21.65 kB
public/build-qa-opportunities/assets/instrument-sans-600-normal-B9e8oLYv.woff 21.67 kB
public/build-qa-opportunities/manifest.json 116.89 kB │ gzip: 12.31 kB
public/build-qa-opportunities/assets/fonts-CcFLQaQ-.css 7.91 kB │ gzip: 0.65 kB
public/build-qa-opportunities/assets/investment-catalogue-WaRR19FV.css 8.15 kB │ gzip: 2.00 kB
public/build-qa-opportunities/assets/interactive-investment-map-Bm3WjoQm.css 10.62 kB │ gzip: 2.65 kB
public/build-qa-opportunities/assets/app-UznX-FqS.css 157.42 kB │ gzip: 25.28 kB
public/build-qa-opportunities/assets/input-text-BlEFHnL-.js 0.09 kB │ gzip: 0.10 kB
public/build-qa-opportunities/assets/check-PcBNn_NG.js 0.12 kB │ gzip: 0.14 kB
public/build-qa-opportunities/assets/company-comparison-qLTgpXjz.js 0.12 kB │ gzip: 0.13 kB
public/build-qa-opportunities/assets/chevron-down-Bjkqe1aH.js 0.12 kB │ gzip: 0.14 kB
public/build-qa-opportunities/assets/chevron-right-K0fOEtTQ.js 0.12 kB │ gzip: 0.14 kB
public/build-qa-opportunities/assets/display-value-DRR1EAAK.js 0.13 kB │ gzip: 0.12 kB
public/build-qa-opportunities/assets/value-text-BztaYdGl.js 0.14 kB │ gzip: 0.12 kB
public/build-qa-opportunities/assets/loader-circle-DS8Tf4er.js 0.14 kB │ gzip: 0.15 kB
public/build-qa-opportunities/assets/shared-B-QpuOU2.js 0.15 kB │ gzip: 0.13 kB
public/build-qa-opportunities/assets/arrow-left-DMVHIw8Z.js 0.16 kB │ gzip: 0.16 kB
public/build-qa-opportunities/assets/arrow-up-right-BIVouzdL.js 0.16 kB │ gzip: 0.15 kB
public/build-qa-opportunities/assets/search-BRvPeo47.js 0.17 kB │ gzip: 0.16 kB
public/build-qa-opportunities/assets/circle-check-DckzuBoW.js 0.17 kB │ gzip: 0.16 kB
public/build-qa-opportunities/assets/product-usage-CHhCL93_.js 0.18 kB │ gzip: 0.17 kB
public/build-qa-opportunities/assets/editorial-states-Bc7NQzsj.js 0.19 kB │ gzip: 0.16 kB
public/build-qa-opportunities/assets/types-BoD_IJFv.js 0.19 kB │ gzip: 0.16 kB
public/build-qa-opportunities/assets/participation-identity-BWabb4yN.js 0.24 kB │ gzip: 0.18 kB
public/build-qa-opportunities/assets/circle-alert-uV7omYjr.js 0.24 kB │ gzip: 0.18 kB
public/build-qa-opportunities/assets/eye-CmcEBfxN.js 0.25 kB │ gzip: 0.20 kB
public/build-qa-opportunities/assets/log-in-Wgc8VLfq.js 0.25 kB │ gzip: 0.22 kB
public/build-qa-opportunities/assets/partnership-history-CfclSLAo.js 0.27 kB │ gzip: 0.19 kB
public/build-qa-opportunities/assets/compiler-runtime-sKsOXjDo.js 0.27 kB │ gzip: 0.23 kB
public/build-qa-opportunities/assets/file-text-CEJtuNfp.js 0.33 kB │ gzip: 0.21 kB
public/build-qa-opportunities/assets/confirm-Culw9Q-x.js 0.36 kB │ gzip: 0.22 kB
public/build-qa-opportunities/assets/text-link-BBvcP60s.js 0.40 kB │ gzip: 0.27 kB
public/build-qa-opportunities/assets/content-management-entry-C_oY4VyW.js 0.42 kB │ gzip: 0.31 kB
public/build-qa-opportunities/assets/handshake-YqyTTm3a.js 0.44 kB │ gzip: 0.28 kB
public/build-qa-opportunities/assets/investment-guides-DO58L8zr.js 0.45 kB │ gzip: 0.26 kB
public/build-qa-opportunities/assets/catalogue-context-Dj8DfFuR.js 0.47 kB │ gzip: 0.30 kB
public/build-qa-opportunities/assets/operation-key-Dr4VtGxa.js 0.51 kB │ gzip: 0.35 kB
public/build-qa-opportunities/assets/spinner-Dmx1j41V.js 0.52 kB │ gzip: 0.36 kB
public/build-qa-opportunities/assets/types-Cxp_Nskt.js 0.55 kB │ gzip: 0.32 kB
public/build-qa-opportunities/assets/sliders-horizontal-D-4FqAHA.js 0.58 kB │ gzip: 0.26 kB
public/build-qa-opportunities/assets/page-preparation-guard-B-OckhBt.js 0.59 kB │ gzip: 0.35 kB
public/build-qa-opportunities/assets/portal-presentation-fH7FShU8.js 0.62 kB │ gzip: 0.38 kB
public/build-qa-opportunities/assets/confidentiality-C2eqbRBb.js 0.64 kB │ gzip: 0.41 kB
public/build-qa-opportunities/assets/dist-RzQD0wUd.js 0.68 kB │ gzip: 0.43 kB
public/build-qa-opportunities/assets/dist-qw3FPjRO.js 0.74 kB │ gzip: 0.49 kB
public/build-qa-opportunities/assets/labels-DxqjesIG.js 0.74 kB │ gzip: 0.46 kB
public/build-qa-opportunities/assets/wayfinder-Dp7PqxvV.js 0.89 kB │ gzip: 0.53 kB
public/build-qa-opportunities/assets/createLucideIcon-oMeAlXbs.js 0.95 kB │ gzip: 0.56 kB
public/build-qa-opportunities/assets/use-interest-draft-waHUBAew.js 0.99 kB │ gzip: 0.51 kB
public/build-qa-opportunities/assets/context-documents-Bh7vrWBo.js 1.01 kB │ gzip: 0.57 kB
public/build-qa-opportunities/assets/label-Dpfg_IeY.js 1.02 kB │ gzip: 0.62 kB
public/build-qa-opportunities/assets/technical-incident-labels-DlL6bSeE.js 1.02 kB │ gzip: 0.51 kB
public/build-qa-opportunities/assets/investment-consumer-identity-Cxp_hGfX.js 1.07 kB │ gzip: 0.59 kB
public/build-qa-opportunities/assets/article-CPPysFRZ.js 1.08 kB │ gzip: 0.65 kB
public/build-qa-opportunities/assets/search-state-RHLy6yI7.js 1.10 kB │ gzip: 0.68 kB
public/build-qa-opportunities/assets/rolldown-runtime-Dd_uD5pT.js 1.10 kB │ gzip: 0.62 kB
public/build-qa-opportunities/assets/catalogue-investment-map-CTNFBreG.js 1.12 kB │ gzip: 0.62 kB
public/build-qa-opportunities/assets/investment-contexts-BQGiwu9n.js 1.17 kB │ gzip: 0.60 kB
public/build-qa-opportunities/assets/profile-json-Bza-VQzw.js 1.20 kB │ gzip: 0.72 kB
public/build-qa-opportunities/assets/document-LUvEPfWd.js 1.23 kB │ gzip: 0.72 kB
public/build-qa-opportunities/assets/shared-JTxA6RNb.js 1.24 kB │ gzip: 0.74 kB
public/build-qa-opportunities/assets/public-detail-DLYw1Lrh.js 1.25 kB │ gzip: 0.72 kB
public/build-qa-opportunities/assets/demographic-context-BMdtlxjJ.js 1.27 kB │ gzip: 0.73 kB
public/build-qa-opportunities/assets/public-offer-card-CudJyoq4.js 1.30 kB │ gzip: 0.70 kB
public/build-qa-opportunities/assets/input-BJ-Jg-jz.js 1.37 kB │ gzip: 0.75 kB
public/build-qa-opportunities/assets/cluster-competitiveness-hNV0FaaW.js 1.37 kB │ gzip: 0.73 kB
public/build-qa-opportunities/assets/verify-email-n6a1zbAv.js 1.40 kB │ gzip: 0.74 kB
public/build-qa-opportunities/assets/business-types-SGCXhH6X.js 1.47 kB │ gzip: 0.75 kB
public/build-qa-opportunities/assets/verification-BOcn3HIw.js 1.48 kB │ gzip: 0.52 kB
public/build-qa-opportunities/assets/country-select-4uP5BvMf.js 1.49 kB │ gzip: 0.78 kB
public/build-qa-opportunities/assets/territorial-source-evidence-eKB4ZB36.js 1.53 kB │ gzip: 0.83 kB
public/build-qa-opportunities/assets/manage-BH66WeT3.js 1.56 kB │ gzip: 0.74 kB
public/build-qa-opportunities/assets/educational-article-card-0rCqZ1kX.js 1.59 kB │ gzip: 0.72 kB
public/build-qa-opportunities/assets/partnership-source-links-VfrXk2FZ.js 1.65 kB │ gzip: 0.91 kB
public/build-qa-opportunities/assets/catalogue-C8vGjaHy.js 1.78 kB │ gzip: 0.96 kB
public/build-qa-opportunities/assets/technical-incident-notice-CjziWA6m.js 1.79 kB │ gzip: 0.89 kB
public/build-qa-opportunities/assets/report-DRxtlCFu.js 1.80 kB │ gzip: 0.93 kB
public/build-qa-opportunities/assets/preparation-index-CdgPdpQ-.js 1.87 kB │ gzip: 0.89 kB
public/build-qa-opportunities/assets/opportunity-technical-incidents-C4aVbut7.js 1.88 kB │ gzip: 0.98 kB
public/build-qa-opportunities/assets/password-input-DdsNob7W.js 1.89 kB │ gzip: 1.06 kB
public/build-qa-opportunities/assets/passkey-verify-ByR3iZeA.js 2.04 kB │ gzip: 1.15 kB
public/build-qa-opportunities/assets/public-record-offline-BmjvnSLE.js 2.07 kB │ gzip: 1.22 kB
public/build-qa-opportunities/assets/investors-Di6y94fY.js 2.09 kB │ gzip: 1.15 kB
public/build-qa-opportunities/assets/forgot-password-DxizqdUw.js 2.10 kB │ gzip: 0.98 kB
public/build-qa-opportunities/assets/sources-BiAS09SV.js 2.13 kB │ gzip: 1.12 kB
public/build-qa-opportunities/assets/saved-BppN3tdr.js 2.21 kB │ gzip: 1.10 kB
public/build-qa-opportunities/assets/zone-map-XsVlgEXC.js 2.26 kB │ gzip: 1.16 kB
public/build-qa-opportunities/assets/appearance-D9-OrC7t.js 2.36 kB │ gzip: 1.14 kB
public/build-qa-opportunities/assets/shared-CBJ3c_x-.js 2.37 kB │ gzip: 1.24 kB
public/build-qa-opportunities/assets/editorial-subjects-C6_MfRSK.js 2.38 kB │ gzip: 1.14 kB
public/build-qa-opportunities/assets/context-installation-BTustRN8.js 2.39 kB │ gzip: 1.23 kB
public/build-qa-opportunities/assets/workspace-4_R1CLYI.js 2.40 kB │ gzip: 1.20 kB
public/build-qa-opportunities/assets/reset-password-Cn0DRbDq.js 2.43 kB │ gzip: 0.98 kB
public/build-qa-opportunities/assets/public-document-content-BHvs9J7S.js 2.47 kB │ gzip: 0.80 kB
public/build-qa-opportunities/assets/manage-C2CmrtWp.js 2.47 kB │ gzip: 1.10 kB
public/build-qa-opportunities/assets/confirm-password-DkwmRtM5.js 2.47 kB │ gzip: 1.06 kB
public/build-qa-opportunities/assets/structures-Dr2nXdub.js 2.49 kB │ gzip: 1.35 kB
public/build-qa-opportunities/assets/bootstrap-confirmation-9RmA5-Yz.js 2.55 kB │ gzip: 1.19 kB
public/build-qa-opportunities/assets/territory-associations-GTcLYnfG.js 2.55 kB │ gzip: 1.11 kB
public/build-qa-opportunities/assets/installation-Dly8Xg6e.js 2.59 kB │ gzip: 1.28 kB
public/build-qa-opportunities/assets/technical-support-DlW3Jv7q.js 2.60 kB │ gzip: 1.18 kB
public/build-qa-opportunities/assets/management-CvdeRZYq.js 2.68 kB │ gzip: 1.18 kB
public/build-qa-opportunities/assets/experiments-BUMjL12A.js 2.73 kB │ gzip: 1.31 kB
public/build-qa-opportunities/assets/password-CB_NxgQN.js 2.73 kB │ gzip: 0.73 kB
public/build-qa-opportunities/assets/opportunity-install-B232n6lM.js 2.75 kB │ gzip: 1.34 kB
public/build-qa-opportunities/assets/dist-BobFCjoG.js 2.92 kB │ gzip: 1.29 kB
public/build-qa-opportunities/assets/offer-navigation-DLl-_mMp.js 2.98 kB │ gzip: 1.11 kB
public/build-qa-opportunities/assets/portal-api-CpQBRfcu.js 2.98 kB │ gzip: 1.50 kB
public/build-qa-opportunities/assets/two-factor-challenge-xfKPtZXs.js 3.24 kB │ gzip: 1.52 kB
public/build-qa-opportunities/assets/territory-geometry-preview-4JCbJT47.js 3.25 kB │ gzip: 1.47 kB
public/build-qa-opportunities/assets/workspace-C_G1PW62.js 3.29 kB │ gzip: 1.44 kB
public/build-qa-opportunities/assets/partnership-agreement-instrument-CCnuZNBy.js 3.43 kB │ gzip: 1.49 kB
public/build-qa-opportunities/assets/funding-classification-DheUcd9F.js 3.44 kB │ gzip: 1.64 kB
public/build-qa-opportunities/assets/guide-mndEuKFT.js 3.45 kB │ gzip: 1.43 kB
public/build-qa-opportunities/assets/history-DSPDM8gM.js 3.46 kB │ gzip: 1.70 kB
public/build-qa-opportunities/assets/audit-Xdo8qR4z.js 3.51 kB │ gzip: 1.69 kB
public/build-qa-opportunities/assets/show-BJFvXI_v.js 3.60 kB │ gzip: 1.82 kB
public/build-qa-opportunities/assets/demography-C6B5IZD_.js 3.70 kB │ gzip: 1.79 kB
public/build-qa-opportunities/assets/corridor-agribusiness-BcIVf-hW.js 3.72 kB │ gzip: 1.53 kB
public/build-qa-opportunities/assets/business-opportunity-DgZSIWou.js 3.73 kB │ gzip: 1.63 kB
public/build-qa-opportunities/assets/management-access-D4VE9LUB.js 3.75 kB │ gzip: 1.43 kB
public/build-qa-opportunities/assets/businesses-BSqviy8L.js 3.76 kB │ gzip: 1.57 kB
public/build-qa-opportunities/assets/editorial-reading-DUFQmJtD.js 3.89 kB │ gzip: 1.68 kB
public/build-qa-opportunities/assets/catalog-B6dpdVsW.js 3.95 kB │ gzip: 1.51 kB
public/build-qa-opportunities/assets/desk-assignments-CfWpiIpK.js 3.99 kB │ gzip: 1.95 kB
public/build-qa-opportunities/assets/dashboard-CxoTLkSg.js 3.99 kB │ gzip: 1.61 kB
public/build-qa-opportunities/assets/investment-context-cards-gJe_oyxw.js 4.05 kB │ gzip: 1.84 kB
public/build-qa-opportunities/assets/shared-OMougC44.js 4.09 kB │ gzip: 2.05 kB
public/build-qa-opportunities/assets/opportunity-contact-form-Cb6iDQ1U.js 4.10 kB │ gzip: 1.67 kB
public/build-qa-opportunities/assets/demographic-evidence-DGwOnf5g.js 4.38 kB │ gzip: 1.84 kB
public/build-qa-opportunities/assets/conversation-DmGmFHQ_.js 4.42 kB │ gzip: 1.95 kB
public/build-qa-opportunities/assets/portfolio-BCzBidHt.js 4.45 kB │ gzip: 1.74 kB
public/build-qa-opportunities/assets/reference-CC7DXgRa.js 4.46 kB │ gzip: 2.00 kB
public/build-qa-opportunities/assets/territory-geometry-import-BnSl5jzG.js 4.49 kB │ gzip: 1.90 kB
public/build-qa-opportunities/assets/opportunity-origin-D3o6OTRg.js 4.64 kB │ gzip: 2.07 kB
public/build-qa-opportunities/assets/context-inheritance-dd0VgP8h.js 4.64 kB │ gzip: 2.00 kB
public/build-qa-opportunities/assets/installation-CnslW5oi.js 4.67 kB │ gzip: 1.95 kB
public/build-qa-opportunities/assets/opportunities-YsMGMCR_.js 4.73 kB │ gzip: 1.77 kB
public/build-qa-opportunities/assets/references-BMPGGgyS.js 4.79 kB │ gzip: 2.22 kB
public/build-qa-opportunities/assets/offer-confidential-access-Bu9EgZ3d.js 4.83 kB │ gzip: 1.91 kB
public/build-qa-opportunities/assets/opportunity-curation-7Gt2cWer.js 4.88 kB │ gzip: 2.04 kB
public/build-qa-opportunities/assets/business-verifications-CI0i9uoo.js 4.90 kB │ gzip: 1.71 kB
public/build-qa-opportunities/assets/crm-edit-comparison-Db53T7I7.js 4.91 kB │ gzip: 1.99 kB
public/build-qa-opportunities/assets/investment-complements-BxgtKBx2.js 5.00 kB │ gzip: 2.05 kB
public/build-qa-opportunities/assets/service-CbUB6_Ll.js 5.05 kB │ gzip: 2.33 kB
public/build-qa-opportunities/assets/agreement-history-BfSa8E7Q.js 5.13 kB │ gzip: 2.10 kB
public/build-qa-opportunities/assets/catalogue-Cd-RNIG1.js 5.13 kB │ gzip: 2.54 kB
public/build-qa-opportunities/assets/workspace-BeyUwWtD.js 5.20 kB │ gzip: 2.18 kB
public/build-qa-opportunities/assets/article-editor-ByLxbPbJ.js 5.25 kB │ gzip: 2.20 kB
public/build-qa-opportunities/assets/context-start-BcJpYa9I.js 5.46 kB │ gzip: 2.09 kB
public/build-qa-opportunities/assets/economic-references-C7dNVUC6.js 5.61 kB │ gzip: 2.52 kB
public/build-qa-opportunities/assets/convert-B3LtI2n6.js 5.81 kB │ gzip: 2.40 kB
public/build-qa-opportunities/assets/editorial-subject-form-B2W8E2NJ.js 5.87 kB │ gzip: 2.66 kB
public/build-qa-opportunities/assets/public-sector-cards-Esb1aTm6.js 5.94 kB │ gzip: 2.55 kB
public/build-qa-opportunities/assets/demography-install-B57rikBv.js 6.05 kB │ gzip: 2.50 kB
public/build-qa-opportunities/assets/context-DX8H9xrC.js 6.06 kB │ gzip: 2.65 kB
public/build-qa-opportunities/assets/request-CEHLhPPo.js 6.10 kB │ gzip: 2.41 kB
public/build-qa-opportunities/assets/structure-geography-Bo85NWTp.js 6.12 kB │ gzip: 2.22 kB
public/build-qa-opportunities/assets/editorial-workflow-DYYZzXOw.js 6.22 kB │ gzip: 2.29 kB
public/build-qa-opportunities/assets/investment-map-panel-B1xwyvFR.js 6.27 kB │ gzip: 2.88 kB
public/build-qa-opportunities/assets/procurement-PtO-r9qV.js 6.35 kB │ gzip: 2.73 kB
public/build-qa-opportunities/assets/register-DyaxliT7.js 6.43 kB │ gzip: 2.71 kB
public/build-qa-opportunities/assets/funding-BslGAfF5.js 6.49 kB │ gzip: 2.00 kB
public/build-qa-opportunities/assets/leads-Bu2UK8ON.js 6.56 kB │ gzip: 2.82 kB
public/build-qa-opportunities/assets/business-marketplace-DGH7B-E2.js 6.59 kB │ gzip: 2.51 kB
public/build-qa-opportunities/assets/interest-xqtiIFPC.js 6.63 kB │ gzip: 2.23 kB
public/build-qa-opportunities/assets/demography-BxaBdOBx.js 6.66 kB │ gzip: 2.51 kB
public/build-qa-opportunities/assets/fiscal-qa-review-CEzw2OQP.js 6.75 kB │ gzip: 2.70 kB
public/build-qa-opportunities/assets/business-interest-CZgFv7wk.js 6.82 kB │ gzip: 2.60 kB
public/build-qa-opportunities/assets/interests-BcpPowrJ.js 6.83 kB │ gzip: 2.78 kB
public/build-qa-opportunities/assets/catalogue-GV7YGM69.js 6.84 kB │ gzip: 2.81 kB
public/build-qa-opportunities/assets/company-comparison-CLzhILGo.js 6.92 kB │ gzip: 2.60 kB
public/build-qa-opportunities/assets/business-classification-CbEGwmnS.js 7.01 kB │ gzip: 2.57 kB
public/build-qa-opportunities/assets/dist-Ddn_hEUd.js 7.02 kB │ gzip: 2.71 kB
public/build-qa-opportunities/assets/blank-2jFZEe2q.js 7.07 kB │ gzip: 2.77 kB
public/build-qa-opportunities/assets/analysis-CWzzPBct.js 7.11 kB │ gzip: 2.96 kB
public/build-qa-opportunities/assets/profile-7Z3ih2bC.js 7.19 kB │ gzip: 2.47 kB
public/build-qa-opportunities/assets/install-ChSwGq-d.js 7.23 kB │ gzip: 3.03 kB
public/build-qa-opportunities/assets/investor-COYuuRY_.js 7.30 kB │ gzip: 2.89 kB
public/build-qa-opportunities/assets/investor-path-CSExMjAt.js 7.36 kB │ gzip: 3.02 kB
public/build-qa-opportunities/assets/proactive-supply-review-Bspf5LP7.js 7.55 kB │ gzip: 2.73 kB
public/build-qa-opportunities/assets/legacy-Cgz97_0u.js 7.67 kB │ gzip: 2.56 kB
public/build-qa-opportunities/assets/jsx-runtime-BpzPEenQ.js 7.89 kB │ gzip: 2.99 kB
public/build-qa-opportunities/assets/shared-BFCbvJo7.js 7.90 kB │ gzip: 3.08 kB
public/build-qa-opportunities/assets/business-objects-BSbz_1pe.js 7.95 kB │ gzip: 2.57 kB
public/build-qa-opportunities/assets/assisted-K2_qpkSv.js 8.06 kB │ gzip: 3.16 kB
public/build-qa-opportunities/assets/value-network-Cp8UYtMs.js 8.06 kB │ gzip: 3.08 kB
public/build-qa-opportunities/assets/editor-xaCzg6Ao.js 8.21 kB │ gzip: 2.97 kB
public/build-qa-opportunities/assets/territorial-editorial-B0ni24WA.js 8.22 kB │ gzip: 3.03 kB
public/build-qa-opportunities/assets/opportunity-promotion-CyWpImc1.js 8.40 kB │ gzip: 2.96 kB
public/build-qa-opportunities/assets/publication-history-DfLO6jOc.js 8.42 kB │ gzip: 3.02 kB
public/build-qa-opportunities/assets/print-Tn3aXHlY.js 8.66 kB │ gzip: 3.55 kB
public/build-qa-opportunities/assets/dialog-D0NJ4SGy.js 8.81 kB │ gzip: 2.76 kB
public/build-qa-opportunities/assets/shared-DXIXdF9G.js 8.92 kB │ gzip: 3.83 kB
public/build-qa-opportunities/assets/iva-modelo-a-CNylSdBc.js 8.94 kB │ gzip: 3.27 kB
public/build-qa-opportunities/assets/zone-relations-CdbqX19L.js 8.95 kB │ gzip: 2.99 kB
public/build-qa-opportunities/assets/investment-territory-CTzFQmCV.js 8.96 kB │ gzip: 3.43 kB
public/build-qa-opportunities/assets/similar-businesses-HTwQGVGQ.js 9.11 kB │ gzip: 3.58 kB
public/build-qa-opportunities/assets/interactive-investment-map-CGOhHCge.js 9.13 kB │ gzip: 3.60 kB
public/build-qa-opportunities/assets/investment-land-preparation-BHeC9B2U.js 9.15 kB │ gzip: 3.33 kB
public/build-qa-opportunities/assets/why-invest-BIS-cmeJ.js 9.16 kB │ gzip: 3.49 kB
public/build-qa-opportunities/assets/interest-history-oHNykKmC.js 9.48 kB │ gzip: 3.45 kB
public/build-qa-opportunities/assets/content-hub-Df5xDkkT.js 9.95 kB │ gzip: 2.93 kB
public/build-qa-opportunities/assets/privacy-policy-LI1lpUCK.js 10.36 kB │ gzip: 3.07 kB
public/build-qa-opportunities/assets/editorial-edition-Zq39X7mf.js 10.36 kB │ gzip: 3.47 kB
public/build-qa-opportunities/assets/panel-Bi6FJvJx.js 10.46 kB │ gzip: 4.29 kB
public/build-qa-opportunities/assets/result-yez5wOFo.js 10.57 kB │ gzip: 4.73 kB
public/build-qa-opportunities/assets/dashboard-mFja_TO4.js 10.92 kB │ gzip: 3.47 kB
public/build-qa-opportunities/assets/zone-attachments-DBvjiTcG.js 10.94 kB │ gzip: 2.75 kB
public/build-qa-opportunities/assets/business-DUxcRYkb.js 11.10 kB │ gzip: 3.08 kB
public/build-qa-opportunities/assets/detail-BRdMNEQp.js 11.73 kB │ gzip: 4.31 kB
public/build-qa-opportunities/assets/login-CDV8vvsd.js 11.89 kB │ gzip: 4.92 kB
public/build-qa-opportunities/assets/support-installation-tsBpnQkP.js 12.36 kB │ gzip: 4.86 kB
public/build-qa-opportunities/assets/show-DF9KhUzw.js 12.37 kB │ gzip: 3.98 kB
public/build-qa-opportunities/assets/tempo-brand-BXcnRsyn.js 12.38 kB │ gzip: 5.01 kB
public/build-qa-opportunities/assets/show-CAVO7psn.js 12.40 kB │ gzip: 4.39 kB
public/build-qa-opportunities/assets/guide-DcEhT0Sh.js 12.58 kB │ gzip: 4.03 kB
public/build-qa-opportunities/assets/contact-BwgG52Cs.js 12.65 kB │ gzip: 4.33 kB
public/build-qa-opportunities/assets/project-dossier-document-DLCZGheg.js 12.68 kB │ gzip: 5.20 kB
public/build-qa-opportunities/assets/dossier-prefill-B18BbJoD.js 12.72 kB │ gzip: 4.64 kB
public/build-qa-opportunities/assets/technical-incident-GDB_x0wp.js 12.73 kB │ gzip: 4.96 kB
public/build-qa-opportunities/assets/competitiveness-60nqrOfg.js 12.74 kB │ gzip: 4.23 kB
public/build-qa-opportunities/assets/editor-DMwEWxsJ.js 12.91 kB │ gzip: 3.75 kB
public/build-qa-opportunities/assets/fiscal-forms-CIgeIrrS.js 13.04 kB │ gzip: 4.75 kB
public/build-qa-opportunities/assets/opportunity-classification-Dm_W66ep.js 13.44 kB │ gzip: 4.55 kB
public/build-qa-opportunities/assets/react-CjVep8xp.js 13.90 kB │ gzip: 4.61 kB
public/build-qa-opportunities/assets/opportunity-search-filters-CqGDv55D.js 14.74 kB │ gzip: 4.72 kB
public/build-qa-opportunities/assets/case-wwTeoOmv.js 14.77 kB │ gzip: 5.38 kB
public/build-qa-opportunities/assets/product-usage-A6hb-0oX.js 14.81 kB │ gzip: 5.29 kB
public/build-qa-opportunities/assets/company-preparation-D8eVac1u.js 15.17 kB │ gzip: 4.92 kB
public/build-qa-opportunities/assets/terms-of-use-CUQdwKes.js 15.27 kB │ gzip: 4.20 kB
public/build-qa-opportunities/assets/edit-DsH5Q1h1.js 15.38 kB │ gzip: 5.15 kB
public/build-qa-opportunities/assets/relationship-repair-brZoqSge.js 16.29 kB │ gzip: 5.62 kB
public/build-qa-opportunities/assets/edit-BPe9IHkr.js 16.60 kB │ gzip: 4.88 kB
public/build-qa-opportunities/assets/edit-CheIw-hI.js 16.93 kB │ gzip: 4.91 kB
public/build-qa-opportunities/assets/search-B8kmEkH5.js 17.16 kB │ gzip: 5.69 kB
public/build-qa-opportunities/assets/funding-institution-DgwDRv_z.js 17.24 kB │ gzip: 5.82 kB
public/build-qa-opportunities/assets/use-two-factor-auth-D9w0KtSq.js 17.31 kB │ gzip: 6.30 kB
public/build-qa-opportunities/assets/administration-CgUGyaX7.js 17.41 kB │ gzip: 4.30 kB
public/build-qa-opportunities/assets/notifications-Tmebv7ru.js 17.61 kB │ gzip: 5.83 kB
public/build-qa-opportunities/assets/ai-ykPV8ntL.js 18.08 kB │ gzip: 6.92 kB
public/build-qa-opportunities/assets/project-dossier-report-DpD9_xNw.js 18.98 kB │ gzip: 6.95 kB
public/build-qa-opportunities/assets/submission-C6KF6kEv.js 19.99 kB │ gzip: 6.32 kB
public/build-qa-opportunities/assets/opportunity-resources-DHgylXUE.js 20.20 kB │ gzip: 7.22 kB
public/build-qa-opportunities/assets/about-BtlawfeW.js 20.95 kB │ gzip: 7.03 kB
public/build-qa-opportunities/assets/zones-Cqg6mKe2.js 21.16 kB │ gzip: 5.22 kB
public/build-qa-opportunities/assets/service-editor-CG1DhyKz.js 21.30 kB │ gzip: 6.58 kB
public/build-qa-opportunities/assets/context-DBE0uEqB.js 21.56 kB │ gzip: 6.99 kB
public/build-qa-opportunities/assets/declaration-Bzl3lixx.js 22.15 kB │ gzip: 7.14 kB
public/build-qa-opportunities/assets/Combination-BBDI-RbM.js 23.03 kB │ gzip: 8.24 kB
public/build-qa-opportunities/assets/desk-internal-operations-BakRT6ga.js 23.14 kB │ gzip: 6.53 kB
public/build-qa-opportunities/assets/education-BElOGGwI.js 23.40 kB │ gzip: 8.20 kB
public/build-qa-opportunities/assets/investment-opportunity-choices-BIDCuOIq.js 24.28 kB │ gzip: 8.06 kB
public/build-qa-opportunities/assets/preparation-D_D73Qym.js 24.56 kB │ gzip: 6.73 kB
public/build-qa-opportunities/assets/utils-CCDJ05Ll.js 27.31 kB │ gzip: 8.71 kB
public/build-qa-opportunities/assets/business-wizard-7qn-T-8z.js 28.60 kB │ gzip: 9.42 kB
public/build-qa-opportunities/assets/proactive-investment-DfIQuXvs.js 28.65 kB │ gzip: 9.16 kB
public/build-qa-opportunities/assets/lead-vUXgd2g8.js 29.03 kB │ gzip: 9.96 kB
public/build-qa-opportunities/assets/preparation-BJOKOlYB.js 29.25 kB │ gzip: 8.51 kB
public/build-qa-opportunities/assets/form-CuZokTHN.js 29.80 kB │ gzip: 8.04 kB
public/build-qa-opportunities/assets/profile-DSwkSvJs.js 30.71 kB │ gzip: 9.33 kB
public/build-qa-opportunities/assets/welcome-_9nm1hgc.js 30.73 kB │ gzip: 6.49 kB
public/build-qa-opportunities/assets/manage-GV_WvYCX.js 31.17 kB │ gzip: 7.63 kB
public/build-qa-opportunities/assets/security-CB7TJeqg.js 32.11 kB │ gzip: 10.06 kB
public/build-qa-opportunities/assets/editor-CWbYf7YK.js 35.03 kB │ gzip: 11.76 kB
public/build-qa-opportunities/assets/case-CPWSbxvW.js 37.38 kB │ gzip: 10.32 kB
public/build-qa-opportunities/assets/room-Bg8k9V54.js 38.25 kB │ gzip: 12.14 kB
public/build-qa-opportunities/assets/simulation-form-CVV000gF.js 39.43 kB │ gzip: 10.27 kB
public/build-qa-opportunities/assets/request-Duh2vDwb.js 41.86 kB │ gzip: 11.30 kB
public/build-qa-opportunities/assets/detail-CXufoj8g.js 46.42 kB │ gzip: 15.18 kB
public/build-qa-opportunities/assets/PortalInvestidor-DCM4Umjc.js 48.72 kB │ gzip: 14.86 kB
public/build-qa-opportunities/assets/business-financial-plan-s1uoiktr.js 49.19 kB │ gzip: 11.98 kB
public/build-qa-opportunities/assets/catalogue-SjEs3uS8.js 50.02 kB │ gzip: 16.10 kB
public/build-qa-opportunities/assets/dropdown-menu-DeBy_kF_.js 57.05 kB │ gzip: 19.02 kB
public/build-qa-opportunities/assets/zone-B2czy9Xo.js 62.42 kB │ gzip: 15.63 kB
public/build-qa-opportunities/assets/show-9fSIEkpb.js 68.49 kB │ gzip: 21.16 kB
public/build-qa-opportunities/assets/opportunity-draft-Cei20Tpo.js 70.65 kB │ gzip: 20.89 kB
public/build-qa-opportunities/assets/document-zip-bqFSTgG4.js 95.97 kB │ gzip: 28.50 kB
public/build-qa-opportunities/assets/app-7Rc_PO3G.js 147.54 kB │ gzip: 45.60 kB
public/build-qa-opportunities/assets/leaflet-src-CUWrUTR2.js 148.82 kB │ gzip: 43.39 kB
public/build-qa-opportunities/assets/dist-BRfsww6z.js 307.99 kB │ gzip: 96.67 kB
public/build-qa-opportunities/assets/document-word-CqTGSyXu.js 403.66 kB │ gzip: 115.44 kB
public/build-qa-opportunities/assets/services-vnbZkLSz.js 965.96 kB │ gzip: 226.50 kB
public/build-qa-opportunities/assets/project-dossier-a3IvmE5B.js 1,009.94 kB │ gzip: 274.44 kB
[plugin builtin:vite-reporter]
(!) Some chunks are larger than 500 kB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rolldownOptions.output.codeSplitting to improve chunking:
https://rolldown.rs/reference/OutputOptions.codeSplitting
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
[PLUGIN_TIMINGS] Your build spent 98% of 24.5s inside plugin hooks (24.0s).
Measured inside the callback, so queue time is excluded and time the callback itself awaited is not:
- @rolldown/plugin-babel transform (78%, 19.1s, 412 calls)
- @tailwindcss/vite:generate:build transform (16%, 3.9s, 3 calls)
Those rows are 94% of the build; the rest of the 98% is below.
Not measurable — 1 hook whose calls overlap, so elapsed time covers work other calls were doing. Profile with `node
--cpu-prof`:
- vite:css transform (3 calls)
See https://rolldown.rs/reference/InputOptions.checks#plugintimings for more details.
✓ built in 24.52s
@@ -0,0 +1,37 @@
✔ each manager dashboard menu anchor resolves to a real section (11.504167ms)
✔ investor section remains distinct from administrative summary (0.786958ms)
✔ sidebar renders every nested authorised destination instead of a first-child shortcut (32.997667ms)
✔ nested current destination is selected without changing its URL or replacing it with a group root (8.242541ms)
✔ rendered visitor sidebar explains access without private operation links (8.582708ms)
✔ sidebar carries the existing search territory when moving between catalogues (11.782958ms)
✔ changing offer state preserves the operational and pending-report filters (29.420375ms)
✔ private offers use the existing work group and do not appear for an ungranted account (6.359416ms)
✔ public and authenticated navigation share groups without revealing management (6.903875ms)
✔ management and optional modules follow permissions and feature flags (1.518125ms)
✔ detail URLs and filtered catalogue pages retain the current group (2.9345ms)
✔ reconciled navigation selects discovery, realization and private support correctly (0.506791ms)
✔ discovery retains distinct catalogues without repeating main entry points (0.444541ms)
✔ catalogue detail and return preserve the search inside the local catalogue (0.951917ms)
✔ both menu consumers respect the existing scoped server decision rather than generic manager status (0.457583ms)
✔ work entry is discoverable without exposing private capabilities to an anonymous visitor (0.628042ms)
✔ work area exposes existing content capability even when the old dashboard flag has no menu object (2.436209ms)
✔ every previously authorised management/profile destination survives the regrouping exactly once (0.993917ms)
✔ ordinary authenticated account has an explanation entry and does not acquire creation or management links (0.281292ms)
✔ direct analysis and ordinary creation preserve distinct selection state in the same work group (0.657375ms)
✔ investment entry belongs to realization exactly once (0.336625ms)
✔ portfolio and zone fiche return keeps the applied catalogue page and filters (0.665541ms)
✔ catalogue pagination inheritance rejects invalid page values (0.243834ms)
✔ funding links require installation and saved list requires authentication (0.728958ms)
✔ installed concours has its own primary group and preserves public and private destinations (0.63125ms)
✔ administration owns dashboard activities once and remains hidden without authorised destinations (0.932792ms)
✔ administrative operations are grouped outside Dashboard and removed from More/work (0.444ms)
✔ actual header has exactly the requested six primary entries on desktop and mobile for public and signed-in users (41.499292ms)
✔ authorised administration is primary and dashboard is a nested expandable group on desktop and mobile (10.578291ms)
ℹ tests 29
ℹ suites 0
ℹ pass 29
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1226.643584
@@ -0,0 +1,51 @@
{
"scope": "Offer navigation only; existing horizontal portal dropdowns reused",
"frontend_tests": {
"tests": 29,
"passed": 29
},
"types": "passed",
"build": "QA build passed; assets served from existing local preview",
"lint": "passed with one pre-existing prefer-string-starts-ends-with warning outside changed lines in portal-navigation.ts",
"backend": "unchanged; no database-refreshing tests run during user preview",
"http": [
{
"path": "/minhas-oportunidades/ofertas",
"status": 200
},
{
"path": "/minhas-oportunidades/ofertas/18",
"status": 200
},
{
"path": "/minhas-oportunidades/ofertas/19",
"status": 200
},
{
"asset": "assets/app-7Rc_PO3G.js",
"status": 200
},
{
"asset": "assets/preparation-BJOKOlYB.js",
"status": 200
},
{
"asset": "assets/preparation-index-CdgPdpQ-.js",
"status": 200
}
],
"data_and_session": "Existing synthetic identities and offers preserved; no seeding, migration, reset or session invalidation during this change",
"publication": "unchanged, closed",
"installed_in_homologation": false,
"visual_acceptance": "pending user review; no browser screenshot acceptance claimed",
"previous_bundle": "9a014268 bundle preserved; this UI delta is not included in that previously frozen package",
"source_sha256": {
"resources/js/app.tsx": "b6afda8c8d60e8049d53352a6b62b7cabf0a470adc31a55c952c6e71456986a1",
"resources/js/lib/portal-navigation.ts": "4fb7cbf0a508cf0964e7ea0dd2023bc00202236bf048f228822d7de6e1f44534",
"resources/js/lib/offer-navigation.ts": "94ec55b7bbbc800f57fd10a9b51a49398c6cdd23fa0df635ca20e949426aef13",
"resources/js/components/offer-navigation.tsx": "4676f4859f7d378ebca988bc5436629f97c0004abe32af6db8a6b40789b48874",
"resources/js/pages/offers/preparation.tsx": "7503946ba28e71ff48e6fd955b1ed587494678df433b6a13492dd026b74ce1de",
"resources/js/pages/offers/preparation-index.tsx": "1cdfe52e4ed8311f52e24caab32d83dc7611213e5b9d3cc477b61c6e6c996276",
"tests/frontend/offer-navigation.test.mjs": "007122b87d4123a6dfd5360b106821a3c27e6ba1575bae4d77ed631da7281ed9"
}
}
@@ -0,0 +1,3 @@
> types:check
> tsc --noEmit
+1 -2
View File
@@ -27,8 +27,7 @@ void createInertiaApp({
case name.startsWith('qa/'):
case name.startsWith('portal/'):
case name.startsWith('investment/'):
case name === 'offers/catalogue':
case name === 'offers/public-detail':
case name.startsWith('offers/'):
case name.startsWith('portfolio/'):
case name.startsWith('land-assistance/'):
case name.startsWith('desk/'):
@@ -0,0 +1,131 @@
import { Link } from '@inertiajs/react';
import { ChevronDown } from 'lucide-react';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { offerStates } from '@/lib/offer-editorial';
import { offerListHref, type OfferListFilters } from '@/lib/offer-navigation';
export default function OfferNavigation({
canCreate = false,
filters,
}: {
canCreate?: boolean;
filters?: OfferListFilters;
}) {
const trigger =
'tempo-nav-trigger inline-flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium';
return (
<nav
aria-label="Navegação das ofertas"
className="bg-background flex min-w-0 flex-wrap items-center gap-2 rounded-xl border p-2"
>
<DropdownMenu>
<DropdownMenuTrigger className={trigger}>
Ofertas{' '}
<ChevronDown aria-hidden="true" className="size-4" />
</DropdownMenuTrigger>
<DropdownMenuContent
align="start"
collisionPadding={12}
className="tempo-dropdown max-h-[70vh] w-64 max-w-[calc(100vw-2rem)] overflow-y-auto p-2"
>
<DropdownMenuItem asChild className="tempo-menu-item">
<Link href="/minhas-oportunidades/ofertas">
As minhas ofertas
</Link>
</DropdownMenuItem>
{canCreate && (
<DropdownMenuItem asChild className="tempo-menu-item">
<Link href="/minhas-oportunidades/ofertas/criar">
Preparar oferta
</Link>
</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
{filters && (
<DropdownMenu>
<DropdownMenuTrigger className={trigger}>
{filters.state
? (offerStates[filters.state] ?? 'Estado')
: 'Todos os estados'}
<ChevronDown aria-hidden="true" className="size-4" />
</DropdownMenuTrigger>
<DropdownMenuContent
align="start"
collisionPadding={12}
className="tempo-dropdown max-h-[70vh] w-72 max-w-[calc(100vw-2rem)] overflow-y-auto p-2"
>
{[
['', 'Todos os estados'],
...Object.entries(offerStates),
].map(([state, label]) => (
<DropdownMenuItem
key={state}
asChild
className="tempo-menu-item"
>
<Link
href={offerListHref({ ...filters, state })}
aria-current={
(filters.state ?? '') === state
? 'page'
: undefined
}
>
{label}
</Link>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
)}
{filters?.operational && (
<DropdownMenu>
<DropdownMenuTrigger className={trigger}>
Acompanhamento{' '}
<ChevronDown aria-hidden="true" className="size-4" />
</DropdownMenuTrigger>
<DropdownMenuContent
align="start"
collisionPadding={12}
className="tempo-dropdown w-72 max-w-[calc(100vw-2rem)] p-2"
>
<DropdownMenuItem asChild className="tempo-menu-item">
<Link
href={offerListHref({
...filters,
pending_reports: false,
})}
aria-current={
!filters.pending_reports
? 'page'
: undefined
}
>
Todas no meu âmbito
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild className="tempo-menu-item">
<Link
href={offerListHref({
...filters,
pending_reports: true,
})}
aria-current={
filters.pending_reports ? 'page' : undefined
}
>
Denúncias pendentes
</Link>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)}
</nav>
);
}
+13
View File
@@ -0,0 +1,13 @@
export type OfferListFilters = {
state?: string;
operational?: boolean;
pending_reports?: boolean;
};
export function offerListHref(filters: OfferListFilters = {}): string {
const query = new URLSearchParams();
if (filters.operational) query.set('operational', '1');
if (filters.pending_reports) query.set('pending_reports', '1');
if (filters.state) query.set('state', filters.state);
return `/minhas-oportunidades/ofertas${query.size ? `?${query}` : ''}`;
}
+20
View File
@@ -347,6 +347,26 @@ export function legacyPortalNavigation(
'Minhas oportunidades',
profile.mine,
),
{
id: 'private-offers',
label: 'Ofertas',
children: [
link(
'my-private-offers',
'As minhas ofertas',
'/minhas-oportunidades/ofertas',
),
...(profile.create
? [
link(
'new-private-offer',
'Preparar oferta',
'/minhas-oportunidades/ofertas/criar',
),
]
: []),
],
},
]
: []),
...(profile.create
@@ -1,5 +1,6 @@
import { Head, Link } from '@inertiajs/react';
import { offerStates } from '@/lib/offer-editorial';
import OfferNavigation from '@/components/offer-navigation';
export default function OfferPreparations({
records,
@@ -47,41 +48,7 @@ export default function OfferPreparations({
</Link>
)}
</header>
<nav
aria-label="Filtrar ofertas por estado"
className="flex flex-wrap gap-3 text-sm"
>
<Link
href="/minhas-oportunidades/ofertas"
aria-current={!filters.state ? 'page' : undefined}
>
Todas
</Link>
{Object.entries(offerStates).map(([state, label]) => (
<Link
key={state}
href={`/minhas-oportunidades/ofertas?state=${state}`}
aria-current={
filters.state === state ? 'page' : undefined
}
>
{label}
</Link>
))}
</nav>
{filters.operational && (
<nav
className="flex flex-wrap gap-4"
aria-label="Acompanhamento de ofertas"
>
<Link href="/minhas-oportunidades/ofertas?operational=1">
Todas no meu âmbito
</Link>
<Link href="/minhas-oportunidades/ofertas?operational=1&pending_reports=1">
Denúncias pendentes
</Link>
</nav>
)}
<OfferNavigation canCreate={canCreate} filters={filters} />
{!records.data.length && (
<p>Ainda não existem ofertas neste âmbito.</p>
)}
+3 -7
View File
@@ -1,4 +1,4 @@
import { Head, Link, router } from '@inertiajs/react';
import { Head, router } from '@inertiajs/react';
import { useState } from 'react';
import {
TerritoryFields,
@@ -16,6 +16,7 @@ import OfferParticularsFields, {
import OfferPrivateResources from '@/components/offer-private-resources';
import OfferConfidentialAccess from '@/components/offer-confidential-access';
import OfferOperations from '@/components/offer-operations';
import OfferNavigation from '@/components/offer-navigation';
type Offer = OfferParticulars & {
price_mode?: string | null;
@@ -169,12 +170,7 @@ export default function OfferPreparation({
return (
<main className="mx-auto w-full max-w-4xl space-y-6 p-4 md:p-8">
<Head title="Preparar oferta" />
<Link
href="/minhas-oportunidades/ofertas"
className="text-sm underline"
>
As minhas ofertas
</Link>
<OfferNavigation canCreate={contexts.length > 0} />
<header>
<h1 className="text-2xl font-semibold">Preparar oferta</h1>
<p className="text-muted-foreground mt-2">
+88
View File
@@ -0,0 +1,88 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { offerListHref } from '../../resources/js/lib/offer-navigation.ts';
import {
portalNavigation,
currentNavigationItem,
currentNavigationGroup,
} from '../../resources/js/lib/portal-navigation.ts';
await test('changing offer state preserves the operational and pending-report filters', () => {
const filters = {
operational: true,
pending_reports: true,
state: 'in_review',
};
const selected = new URL(offerListHref(filters), 'https://qa.invalid');
assert.equal(selected.searchParams.get('operational'), '1');
assert.equal(selected.searchParams.get('pending_reports'), '1');
assert.equal(selected.searchParams.get('state'), 'in_review');
const allStates = new URL(
offerListHref({ ...filters, state: '' }),
selected.origin,
);
assert.equal(allStates.searchParams.has('state'), false);
assert.equal(allStates.searchParams.get('pending_reports'), '1');
assert.equal(offerListHref(), '/minhas-oportunidades/ofertas');
assert.equal(
new URL(
offerListHref({ ...filters, pending_reports: false }),
selected.origin,
).searchParams.has('pending_reports'),
false,
);
});
await test('private offers use the existing work group and do not appear for an ungranted account', () => {
const profile = {
mine: '/minhas-oportunidades',
create: '/minhas-oportunidades/criar',
contexts: [],
request: '/perfil/promotor',
review: null,
administration: null,
};
const groups = portalNavigation({
authenticated: true,
manager: false,
profileAccess: profile,
});
const work = groups.find((group) => group.id === 'work');
const offers = work.children.find((item) => item.id === 'private-offers');
assert.deepEqual(
offers.children.map((item) => item.href),
[
'/minhas-oportunidades/ofertas',
'/minhas-oportunidades/ofertas/criar',
],
);
assert.equal(
currentNavigationItem(groups, '/minhas-oportunidades/ofertas'),
'my-private-offers',
);
assert.equal(
currentNavigationGroup(groups, '/minhas-oportunidades/ofertas/18'),
'work',
);
const reader = portalNavigation({
authenticated: true,
manager: false,
profileAccess: { ...profile, create: null },
});
assert.ok(!JSON.stringify(reader).includes('new-private-offer'));
for (const access of [
{ authenticated: false, manager: false },
{
authenticated: true,
manager: false,
profileAccess: { ...profile, mine: null, create: null },
},
]) {
assert.ok(
!JSON.stringify(portalNavigation(access)).includes(
'/minhas-oportunidades/ofertas',
),
);
}
assert.ok(!groups.some((group) => group.id === 'private-offers'));
});