diff --git a/pages/workspace/[id]/edit.vue b/pages/workspace/[id]/edit.vue
index 76d33df..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);
@@ -67,4 +69,19 @@ onMounted(() => {
.editorContainer kbd {
color: unset;
}
+
+/* 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.rapid3 .save-section .commit-info,
+/* your changes should appear on OpenStreetMap within a few minutes */
+.editorContainer.rapid3 .save-summary > p,
+/* Like OpenStreetMap? Connect with others */
+.editorContainer.rapid3 .save-communityLinks {
+ display: none;
+}
diff --git a/services/rapid3.ts b/services/rapid3.ts
index 903ae7f..28d9cbc 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');
}
@@ -152,8 +153,10 @@ export class Rapid3Manager {
#preInit() {
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')) {
@@ -166,12 +169,65 @@ 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', () => {
+ // 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..."
+ '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.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 c of codes) {
+ for (const [k, v] of Object.entries(replacements)) {
+ l10n._store.set(`${c}.core.${k}`, v);
+ }
+ }
+ });
}
/**
@@ -181,8 +237,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',
@@ -198,8 +256,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',
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: () => {} }
};