From 2f984935540097e19a8633441ac528dbf80499a7 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 13 Oct 2026 18:15:55 -0400 Subject: [PATCH 1/4] Remove NSI service (name-suggestion-index) not needed for Workspaces --- services/rapid3.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/rapid3.ts b/services/rapid3.ts index 903ae7f..7f726b4 100644 --- a/services/rapid3.ts +++ b/services/rapid3.ts @@ -142,6 +142,7 @@ export class Rapid3Manager { services.delete('geoscribble'); services.delete('keepright'); services.delete('mapwithai'); + services.delete('nsi'); services.delete('osmose'); } @@ -153,7 +154,7 @@ export class Rapid3Manager { const context = this.rapidContext // Customize Network system - // - Add request interceptor to apply TDEI headers to `/osm/api` requests only. + // - Add request interceptor to apply TDEI headers to `/api/0.6` requests only. const network = context.systems.network const interceptor = (url: string, init: RequestInit): RequestInit => { if (url.includes('/api/0.6')) { From c3f127e856938ad3d1ea10100e144dfe6e30ee44 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Wed, 14 Oct 2026 11:14:33 -0400 Subject: [PATCH 2/4] Replace/Remove language about OpenStreetMap in the Rapid user interface re: https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/3618 This uses a few tricks to remove language that references OpenStreetMap: - In `edit.vue` use CSS to hide blocks of text that are not needed - In `rapid3.ts` override the UiSuccess prototype so that it will avoid trying to fetch the OSM Community Index - In `rapid3.ts`, add a 'localechange' listener on the LocalizationSystem so that after language strings are loaded, we swap in our replacement strings. This will work for any language, but the strings will appear in English. We use `prependListener` here so that our replacements can sneak in before other parts of the UI try redrawing and relocalizing. --- pages/workspace/[id]/edit.vue | 12 ++++++++ services/rapid3.ts | 55 ++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/pages/workspace/[id]/edit.vue b/pages/workspace/[id]/edit.vue index 76d33df..70cef83 100644 --- a/pages/workspace/[id]/edit.vue +++ b/pages/workspace/[id]/edit.vue @@ -67,4 +67,16 @@ onMounted(() => { .editorContainer kbd { color: unset; } + +/* Remove extra language about OpenStreetmap */ +/* view on openstreetmap.org */ +.editorContainer .inspector-wrap .sidebar-footer, +/* your changes will be visible on maps that use OpenStreetMap */ +.editorContainer .save-section .commit-info, +/* your changes should appear on OpenStreetMap within a few minutes */ +.editorContainer .save-summary > p, +/* Like OpenStreetMap? Connect with others */ +.editorContainer .save-communityLinks { + display: none; +} diff --git a/services/rapid3.ts b/services/rapid3.ts index 7f726b4..9c78512 100644 --- a/services/rapid3.ts +++ b/services/rapid3.ts @@ -153,8 +153,10 @@ export class Rapid3Manager { #preInit() { const context = this.rapidContext + // // Customize Network system // - Add request interceptor to apply TDEI headers to `/api/0.6` requests only. + // const network = context.systems.network const interceptor = (url: string, init: RequestInit): RequestInit => { if (url.includes('/api/0.6')) { @@ -167,12 +169,59 @@ export class Rapid3Manager { }; network.addRequestInterceptor(interceptor); + // // Customize OSM service // - Override the `authenticated` check to use TDEI auth state // - Stub out`getUserDetailsAsync` (not needed for workspace-based changeset uploads). + // const osm = context.services.osm osm._oauth.authenticated = () => this.#tdeiAuth.ok - osm.getUserDetailsAsync = (): Promise => Promise.resolve(null) + osm.getUserDetailsAsync = () => Promise.resolve(null) + + // + // Customize UiSuccess screen (post-save) + // Remove the functions that load and render the community index + // + const empty_oci = { resources: [], defaults: {} }; + Rapid.UiSuccess.prototype._getCommunityIndexAsync = () => Promise.resolve(empty_oci); + Rapid.UiSuccess.prototype._renderCommunityData = () => null; + + // + // Customize Localization System + // When changing or setting up initial locale, override some strings with our own. + // + const l10n = context.systems.l10n; + l10n.prependListener('localechange', () => { + let code = l10n.localeCode; + // Note that internally, 'en-US' is actually stored under 'en' + if (code === 'en-US') { + code = 'en'; + } + // Change strings + const replacements = { + 'loading_auth': 'Connecting...', // was: "Connecting to OpenStreetMap..." + 'status.message.error': 'Unable to reach the API. Your edits are safe locally. Check your network connection.', + 'status.message.offline': 'The API is offline. Your edits are safe locally. Please come back later.', + 'status.message.readonly': 'The API is currently read-only. You can continue editing, but must wait to save your changes.', + 'status.message.ratelimit': 'You have downloaded too much data. Please try again in {seconds} seconds or switch accounts.', + 'save.help': 'Review and upload your changes.', + 'save.uploading': 'Uploading Changes...', // was: 'Uploading changes to OpenStreetMap... + 'commit.title': 'Upload Changes', // was: "Upload to OpenStreetMap" + 'success.just_edited': 'Changes Saved!', // was: "You just edited OpenStreetMap!" + 'success.view_on_osm': 'View Changes', // was: "View changes on OSM" + 'map_data.layers.osm.tooltip': 'Existing data in this Workspace', // was: "Map data from OpenStreetMap" + 'map_data.layers.osm.title': 'Workspace Data', // was: "OpenStreetMap Data" + 'map_data.layers.osm.feature': 'Workspace Data', // was: "OpenStreetMap Feature" + 'map_data.layers.notes.tooltip': 'Notes in this Workspace', // was: "Note data from OpenStreetMap" + 'map_data.layers.notes.title': 'Workspace Notes', // was: "OpenStreetMap Notes" + 'map_data.layers.osmhidden': 'These features have been automatically hidden because the Workspace layer is hidden.', + 'shortcuts.command.toggle_osm_data.label': 'Toggle Workspace data', // was: "Toggle OpenStreetMap data" + 'shortcuts.command.toggle_osm_notes.label': 'Toggle Workspace notes', // was: "Toggle OpenStreetMap notes" + }; + for (const [k, v] of Object.entries(replacements)) { + l10n._store.set(`${code}.core.${k}`, v); + } + }); } /** @@ -182,8 +231,10 @@ export class Rapid3Manager { #preStart() { const context = this.rapidContext + // // Customize Imagery system // - Remove unapproved imagery sources + // const imagery = context.systems.imagery const imageryOverrides = { assetID: 'tdei-imagery', @@ -199,8 +250,10 @@ export class Rapid3Manager { imagery.merge(imageryOverrides) imagery._overlayLayers.delete('mapbox_locator_overlay') + // // Customize Style system // - apply Gaussian overrides for WA-Proviso + // const styles = context.systems.styles const styleOverrides = { assetID: 'WA-Proviso-style', From a823ad89eb8c841b2f03e12055bfd102f9a78877 Mon Sep 17 00:00:00 2001 From: Jeff Maki Date: Thu, 15 Oct 2026 17:13:50 -0400 Subject: [PATCH 3/4] Stub Rapid.UiSuccess and l10n system in Rapid 3 e2e fake #preInit now patches Rapid.UiSuccess.prototype and registers an l10n localechange listener; the fake lacked both, so init() threw before initAsync() painted the editor. Co-Authored-By: Claude Opus 5.5 --- test/e2e/edit.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/e2e/edit.spec.ts b/test/e2e/edit.spec.ts index 1fbb71a..ff76235 100644 --- a/test/e2e/edit.spec.ts +++ b/test/e2e/edit.spec.ts @@ -61,13 +61,16 @@ const RAPID2_SCRIPT = (route: Route) => route.fulfill({ // completion and initAsync() paints the editor surface: // - Rapid.services.available (#prePrepare deletes optional services) // - context.systems.network (#preInit adds a request interceptor) +// - context.systems.l10n (#preInit overrides OSM-specific strings) +// - Rapid.UiSuccess (#preInit stubs the community index on its prototype) // - context.systems.imagery / .styles (#preStart merges overrides) const RAPID3_SCRIPT = (route: Route) => route.fulfill({ contentType: 'application/javascript', body: ` window.Rapid = { utilDetect: () => ({ isSupported: true }), - services: { available: new Set(['geoscribble', 'keepright', 'mapwithai', 'osmose']) }, + services: { available: new Set(['geoscribble', 'keepright', 'mapwithai', 'nsi', 'osmose']) }, + UiSuccess: class {}, Context: class { embed() {} async prepareAsync() {} @@ -79,6 +82,7 @@ const RAPID3_SCRIPT = (route: Route) => route.fulfill({ services = { osm: { _oauth: { fetch: () => {}, authenticated: () => true }, userDetails: () => {} } }; systems = { network: { addRequestInterceptor: () => {} }, + l10n: { prependListener: () => {}, localeCode: 'en', _store: new Map() }, imagery: { merge: () => {}, _overlayLayers: new Set(['mapbox_locator_overlay']) }, styles: { merge: () => {} } }; From caaa47cbae7e655bde6575724d5026e971225f25 Mon Sep 17 00:00:00 2001 From: Jeff Maki Date: Thu, 15 Oct 2026 17:38:55 -0400 Subject: [PATCH 4/4] Fix Rapid 3 OSM-branding overrides from PR review - Use the real l10n key map_data.osmhidden (was map_data.layers.osmhidden). - Apply the English string overrides only to English locales, writing to 'en' and the active variant, so other languages keep their translations. - Scope the OSM-hiding CSS to the Rapid 3 container so Rapid 2 and Pathways are unaffected. - Also hide the note editor's view-on-OSM / report footer. Co-Authored-By: Claude Opus 5.5 --- pages/workspace/[id]/edit.vue | 17 +++++++++++------ services/rapid3.ts | 22 ++++++++++++++-------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/pages/workspace/[id]/edit.vue b/pages/workspace/[id]/edit.vue index 70cef83..804d6a0 100644 --- a/pages/workspace/[id]/edit.vue +++ b/pages/workspace/[id]/edit.vue @@ -8,6 +8,7 @@
@@ -22,6 +23,7 @@ const editorContainer = ref(null); const oswManager = (editor === 'rapid3' && rapid3Manager) ? rapid3Manager : rapidManager const manager = datatype === 'osw' ? oswManager : pathwaysManager +const isRapid3 = manager === rapid3Manager; function onEditorLoaded() { editorContainer.value!.appendChild(manager.containerNode); @@ -68,15 +70,18 @@ onMounted(() => { color: unset; } -/* Remove extra language about OpenStreetmap */ -/* view on openstreetmap.org */ -.editorContainer .inspector-wrap .sidebar-footer, +/* Remove extra language about OpenStreetMap (Rapid 3 only; the l10n overrides + in services/rapid3.ts cover the rest) */ +/* view on openstreetmap.org: feature inspector */ +.editorContainer.rapid3 .inspector-wrap .sidebar-footer, +/* view on openstreetmap.org / report a note: note editor */ +.editorContainer.rapid3 .body:has(.note-editor) ~ .sidebar-footer, /* your changes will be visible on maps that use OpenStreetMap */ -.editorContainer .save-section .commit-info, +.editorContainer.rapid3 .save-section .commit-info, /* your changes should appear on OpenStreetMap within a few minutes */ -.editorContainer .save-summary > p, +.editorContainer.rapid3 .save-summary > p, /* Like OpenStreetMap? Connect with others */ -.editorContainer .save-communityLinks { +.editorContainer.rapid3 .save-communityLinks { display: none; } diff --git a/services/rapid3.ts b/services/rapid3.ts index 9c78512..28d9cbc 100644 --- a/services/rapid3.ts +++ b/services/rapid3.ts @@ -192,11 +192,15 @@ export class Rapid3Manager { // const l10n = context.systems.l10n; l10n.prependListener('localechange', () => { - let code = l10n.localeCode; - // Note that internally, 'en-US' is actually stored under 'en' - if (code === 'en-US') { - code = 'en'; + // The replacements below are English, so only apply them to English locales. + // Other locales keep Rapid's own translations. + const code = String(l10n.localeCode ?? '').toLowerCase(); + if (code !== 'en' && !code.startsWith('en-')) { + return; } + // Internally 'en-US' is stored under 'en'; other English variants (e.g. 'en-GB') + // fall back to 'en', so write the overrides there and under the variant itself. + const codes = code === 'en' || code === 'en-us' ? ['en'] : ['en', l10n.localeCode]; // Change strings const replacements = { 'loading_auth': 'Connecting...', // was: "Connecting to OpenStreetMap..." @@ -214,12 +218,14 @@ export class Rapid3Manager { 'map_data.layers.osm.feature': 'Workspace Data', // was: "OpenStreetMap Feature" 'map_data.layers.notes.tooltip': 'Notes in this Workspace', // was: "Note data from OpenStreetMap" 'map_data.layers.notes.title': 'Workspace Notes', // was: "OpenStreetMap Notes" - 'map_data.layers.osmhidden': 'These features have been automatically hidden because the Workspace layer is hidden.', + 'map_data.osmhidden': 'These features have been automatically hidden because the Workspace layer is hidden.', 'shortcuts.command.toggle_osm_data.label': 'Toggle Workspace data', // was: "Toggle OpenStreetMap data" - 'shortcuts.command.toggle_osm_notes.label': 'Toggle Workspace notes', // was: "Toggle OpenStreetMap notes" + 'shortcuts.command.toggle_osm_notes.label': 'Toggle Workspace notes' // was: "Toggle OpenStreetMap notes" }; - for (const [k, v] of Object.entries(replacements)) { - l10n._store.set(`${code}.core.${k}`, v); + for (const c of codes) { + for (const [k, v] of Object.entries(replacements)) { + l10n._store.set(`${c}.core.${k}`, v); + } } }); }