From 68fe6dc5056da193e74f0994cb3cd8e1816e149d Mon Sep 17 00:00:00 2001 From: Jonathan Payne Date: Thu, 1 Oct 2026 11:55:41 -0400 Subject: [PATCH 1/6] closes OpenConceptLab/ocl_issues#2869 | TBv2's apps menu links to the OCL Mapper The tile uses the Tools menu's Mapper icon and toMapperURL(), and opens in a new tab like the Tools entry. The popper widens to 390px so the three tiles come out equal. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/components/common/AppsMenu.jsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/common/AppsMenu.jsx b/src/components/common/AppsMenu.jsx index d3ceb19a..d44fef6f 100644 --- a/src/components/common/AppsMenu.jsx +++ b/src/components/common/AppsMenu.jsx @@ -2,9 +2,10 @@ import React from 'react'; import { Link } from 'react-router-dom'; import { useLocation } from 'react-router'; import { Apps as AppsIcon , Web as MetadataBrowserIcon, Publish as ImportsIcon } from '@mui/icons-material'; +import MapperIcon from '@mui/icons-material/MotionPhotosAutoOutlined'; import { Tooltip, IconButton, Box, Typography } from '@mui/material'; import useToggle from '../../hooks/useToggle'; -import { getSiteTitle } from '../../common/utils'; +import { getSiteTitle, toMapperURL } from '../../common/utils'; import PopperGrow from './PopperGrow'; const SITE_TITLE = getSiteTitle() @@ -35,7 +36,7 @@ const AppsMenu = props => { - +
{ @@ -60,6 +61,14 @@ const AppsMenu = props => { } + + + + + OCL
Mapper +
+
+
From 4bf01e1f220dca8b82e573d8ade9d5291f3960c1 Mon Sep 17 00:00:00 2001 From: Jonathan Payne Date: Thu, 1 Oct 2026 11:59:23 -0400 Subject: [PATCH 2/6] OpenConceptLab/ocl_issues#2869 | Demo's Mapper link goes to map.qa, and the apps menu fits phone screens toMapperURL()'s generic app.*.openconceptlab.org branch overwrote the explicit demo/QA mapping, so app.demo linked to map.demo, which doesn't resolve. The branches are now else-if. The apps menu's min width is capped at the viewport (min(390px, 100vw - 16px)). From Codex review pass 1. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/common/utils.js | 4 ++-- src/components/common/AppsMenu.jsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/utils.js b/src/common/utils.js index 5a98e9a4..a1e8d44e 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -1183,9 +1183,9 @@ export const toMapperURL = path => { let url = 'https://map.openconceptlab.org' if(window.location.host?.includes('localhost')) url = 'http://localhost:4004' - if(['app.qa.openconceptlab.org', 'app.demo.openconceptlab.org'].includes(window.location.host)) + else if(['app.qa.openconceptlab.org', 'app.demo.openconceptlab.org'].includes(window.location.host)) url = 'https://map.qa.openconceptlab.org' - if(window.location.host.match('app.*.openconceptlab.org')) + else if(window.location.host.match('app.*.openconceptlab.org')) url = window.location.origin.replace('//app.', '//map.') let referrerParams = `referrer=${window.location.href}` diff --git a/src/components/common/AppsMenu.jsx b/src/components/common/AppsMenu.jsx index d44fef6f..cb3c6c60 100644 --- a/src/components/common/AppsMenu.jsx +++ b/src/components/common/AppsMenu.jsx @@ -36,7 +36,7 @@ const AppsMenu = props => { - +
{ From c0525806b73f134ad021bd4493ac81aec431ed75 Mon Sep 17 00:00:00 2001 From: Jonathan Payne Date: Thu, 1 Oct 2026 12:02:23 -0400 Subject: [PATCH 3/6] OpenConceptLab/ocl_issues#2869 | Signed-in users reach the Mapper signed in from TBv2 pages that have a query string The Mapper reads auth=true from the segment after the first '?' in the referrer's hash. A TBv2 URL with its own query (search, concept lists) put that query there instead, so the Mapper didn't start sign-in. toMapperURL() now drops the page's query from the referrer; the Mapper only uses the referrer to recognise OCL clients and read auth. From Codex review pass 2. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/common/utils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/utils.js b/src/common/utils.js index a1e8d44e..ea12de4d 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -1188,7 +1188,8 @@ export const toMapperURL = path => { else if(window.location.host.match('app.*.openconceptlab.org')) url = window.location.origin.replace('//app.', '//map.') - let referrerParams = `referrer=${window.location.href}` + // The Mapper reads auth only from the segment after the first '?' in the referrer's hash, so drop this page's own query + let referrerParams = `referrer=${window.location.href.split('?')[0]}` if(isLoggedIn()) referrerParams += '?auth=true' From 4d6dc68d0f49f44397229269a5f4a7c3333bcc97 Mon Sep 17 00:00:00 2001 From: Jonathan Payne Date: Thu, 1 Oct 2026 12:05:48 -0400 Subject: [PATCH 4/6] OpenConceptLab/ocl_issues#2869 | toMapperURL() matches only real *.openconceptlab.org app hosts CodeQL flagged the unescaped, unanchored 'app.*.openconceptlab.org' pattern on the line this PR touched. The anchored regex matches the same OCL hosts (prod, staging, qa, demo) and no longer matches lookalikes such as app.x.openconceptlab.org.evil.com. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/common/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/utils.js b/src/common/utils.js index ea12de4d..40ea82ff 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -1185,7 +1185,7 @@ export const toMapperURL = path => { url = 'http://localhost:4004' else if(['app.qa.openconceptlab.org', 'app.demo.openconceptlab.org'].includes(window.location.host)) url = 'https://map.qa.openconceptlab.org' - else if(window.location.host.match('app.*.openconceptlab.org')) + else if(/^app\.([a-z0-9-]+\.)*openconceptlab\.org$/.test(window.location.host)) url = window.location.origin.replace('//app.', '//map.') // The Mapper reads auth only from the segment after the first '?' in the referrer's hash, so drop this page's own query From 669a6473bf189906e6da6fb93816acc05fdeea3e Mon Sep 17 00:00:00 2001 From: Jonathan Payne Date: Thu, 1 Oct 2026 12:08:50 -0400 Subject: [PATCH 5/6] OpenConceptLab/ocl_issues#2869 | toMapperURL() compares hostnames, so an OCL host with a port still maps location.host includes the port, which the anchored regex rejected (the old unanchored pattern accepted it). Both host checks now use location.hostname; the origin replacement still keeps the port. From Codex review pass 4. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/common/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/utils.js b/src/common/utils.js index 40ea82ff..5252c188 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -1183,9 +1183,9 @@ export const toMapperURL = path => { let url = 'https://map.openconceptlab.org' if(window.location.host?.includes('localhost')) url = 'http://localhost:4004' - else if(['app.qa.openconceptlab.org', 'app.demo.openconceptlab.org'].includes(window.location.host)) + else if(['app.qa.openconceptlab.org', 'app.demo.openconceptlab.org'].includes(window.location.hostname)) url = 'https://map.qa.openconceptlab.org' - else if(/^app\.([a-z0-9-]+\.)*openconceptlab\.org$/.test(window.location.host)) + else if(/^app\.([a-z0-9-]+\.)*openconceptlab\.org$/.test(window.location.hostname)) url = window.location.origin.replace('//app.', '//map.') // The Mapper reads auth only from the segment after the first '?' in the referrer's hash, so drop this page's own query From fbb3d3bac0865250098488971062943e50305d94 Mon Sep 17 00:00:00 2001 From: Jonathan Payne Date: Thu, 1 Oct 2026 13:28:41 -0400 Subject: [PATCH 6/6] OpenConceptLab/ocl_issues#2869 | Restore toMapperURL()'s host routing: demo links to demo, qa to qa Reverts the else-if, anchored-regex and hostname changes from 4bf01e1f, 4d6dc68d and 669a6473. Each environment's TBv2 links to its own Mapper, which the original routing already did. The referrer query fix (c0525806) stays. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/common/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/utils.js b/src/common/utils.js index 5252c188..ad89b2d3 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -1183,9 +1183,9 @@ export const toMapperURL = path => { let url = 'https://map.openconceptlab.org' if(window.location.host?.includes('localhost')) url = 'http://localhost:4004' - else if(['app.qa.openconceptlab.org', 'app.demo.openconceptlab.org'].includes(window.location.hostname)) + if(['app.qa.openconceptlab.org', 'app.demo.openconceptlab.org'].includes(window.location.host)) url = 'https://map.qa.openconceptlab.org' - else if(/^app\.([a-z0-9-]+\.)*openconceptlab\.org$/.test(window.location.hostname)) + if(window.location.host.match('app.*.openconceptlab.org')) url = window.location.origin.replace('//app.', '//map.') // The Mapper reads auth only from the segment after the first '?' in the referrer's hash, so drop this page's own query