Repository navigation
Staging To Prod - #189
Merged
Merged
Staging To Prod#189
Conversation
Bumps the npm_and_yarn group with 7 updates in the / directory: | Package | From | To | | --- | --- | --- | | [dompurify](https://github.com/cure53/DOMPurify) | `3.4.11` | `3.4.13` | | [esbuild](https://github.com/evanw/esbuild) | `0.27.7` | `0.28.2` | | [fast-uri](https://github.com/fastify/fast-uri) | `3.1.2` | `3.1.5` | | [immutable](https://github.com/immutable-js/immutable-js) | `4.3.8` | `4.3.9` | | [shell-quote](https://github.com/ljharb/shell-quote) | `1.8.4` | `1.10.0` | | [svgo](https://github.com/svg/svgo) | `4.0.1` | `4.0.2` | | [tar](https://github.com/isaacs/node-tar) | `7.5.16` | `7.5.22` | Updates `dompurify` from 3.4.11 to 3.4.13 - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](cure53/DOMPurify@3.4.11...3.4.13) Updates `esbuild` from 0.27.7 to 0.28.2 - [Release notes](https://github.com/evanw/esbuild/releases) - [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md) - [Commits](evanw/esbuild@v0.27.7...v0.28.2) Updates `fast-uri` from 3.1.2 to 3.1.5 - [Release notes](https://github.com/fastify/fast-uri/releases) - [Commits](fastify/fast-uri@v3.1.2...v3.1.5) Updates `immutable` from 4.3.8 to 4.3.9 - [Release notes](https://github.com/immutable-js/immutable-js/releases) - [Changelog](https://github.com/immutable-js/immutable-js/blob/main/CHANGELOG.md) - [Commits](immutable-js/immutable-js@v4.3.8...v4.3.9) Updates `shell-quote` from 1.8.4 to 1.10.0 - [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md) - [Commits](ljharb/shell-quote@v1.8.4...v1.10.0) Updates `svgo` from 4.0.1 to 4.0.2 - [Release notes](https://github.com/svg/svgo/releases) - [Commits](svg/svgo@v4.0.1...v4.0.2) Updates `tar` from 7.5.16 to 7.5.22 - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](isaacs/node-tar@v7.5.16...v7.5.22) --- updated-dependencies: - dependency-name: dompurify dependency-version: 3.4.12 dependency-type: direct:production - dependency-name: esbuild dependency-version: 0.28.1 dependency-type: indirect - dependency-name: fast-uri dependency-version: 3.1.4 dependency-type: indirect - dependency-name: immutable dependency-version: 4.3.9 dependency-type: indirect - dependency-name: shell-quote dependency-version: 1.10.0 dependency-type: indirect - dependency-name: svgo dependency-version: 4.0.2 dependency-type: indirect - dependency-name: tar dependency-version: 7.5.21 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
not needed for Workspaces
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.
new-api.workspaces-dev.sidewalks.washington.edu currently resolves to the
frontend host, which 404s every path and makes the dev proxy hang (e.g.
/new-api/v1/workspaces/{id}/bbox never returns). The main backend
(api.workspaces-dev → ws-backend-dev) serves the same /api/v1/* endpoints,
so route /new-api there. Revert once new-api DNS is fixed in the dev env.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce useUserCapabilities composable to fetch and evaluate user project-group roles and creation permissions. Integrate capability checks across the app (AppNavbar, DatasetPicker, dashboard, and all workspace create flows) to filter datasets, populate/select eligible project groups, disable create actions when unauthorized, and redirect users without creation rights. Add raw dataset payload to Tdei types and map it through TdeiClient, update fixtures, and add unit and e2e tests covering role-based creation scenarios.
A multi-changeset import leaves its later batches out of the first-changeset common ancestor, so those elements read as "created" in both workspaces and were kept twice (e.g. ~191 duplicated ways in a real merge). When the two copies are content-identical — same geometry and tags, ignoring per-workspace metadata — they are the same imported element: collapse to one instead of remapping B's into a duplicate. Genuinely distinct same-id elements are still remapped, and a divergent copy is kept (not silently merged away). Adds elementContentEqual/tagsEqual to util/osm-merge, with regression tests. Surfacing geometry/tag conflicts on such batched-import elements still needs the full import in the ancestor; left as a follow-up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nction-ci Resolves a conflict in services/workspaces.ts deleteWorkspace: develop's PR #151 (report OSM cleanup failure) and this branch both reworked it. Took develop's version (parallel delete via Promise.allSettled returning DeleteWorkspaceResult), dropped the now-unused OsmApiClientError import, and removed this branch's obsolete OSM-first deleteWorkspace tests from test/unit/services/workspaces-lifecycle.test.ts (develop's workspaces.test.ts already covers the new behavior). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ents remapCollidingIds decided whether a created-on-both-sides element was a duplicate by comparing raw content, including a way's or relation's raw child IDs. When a child node was created on both sides but differs, it is re-identified, yet a parent that referenced it by the same raw ID still read as identical and was collapsed onto A's copy — dropping one side's parent and orphaning the re-identified child. Decide children before parents and compare a parent against its effective (post-remap) references, so a parent whose child was re-identified reads as distinct and is kept. Identical parents still collapse to one. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
#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 <noreply@anthropic.com>
The merge resolution kept this branch's vitest import line, but develop's deleteWorkspace tests use vi.fn(), failing typecheck. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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 <noreply@anthropic.com>
This is a branch for getting Rapid v3.0.0 prerelease 3 available in workspaces. Includes the following changes/fixes: - Override user interface elements and strings that refer to OpenStreetMap: https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/3618 - Better selection of background imagery layer https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/4007/ - Fix for switching workspaces after Rapid has loaded https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/4417/ - Add Custom Dataset screen (bring your own data) now supports files. This adds a file picker, drag-and-drop support, and various code related to custom datasets. In prerelease 2, we only supported loading Custom Datasets from a URL. Data files are stored in browser's `IndexedDB` storage so that they can be reloaded later. re: https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/3987/ - Rapid's edit history is now stored in `IndexedDB` too. - Before: - Single edit session stored in `LocalStorage` - Mutex lock prevented multiple browser tabs from backing up the user's edits - Serialization of the user's editing session blocked main thread (long edit sessions caused slowdowns) - Size limitations of `LocalStorage` ("you have too many edits to back up") - On restore screen, a simple "We found unsaved changes - Keep/Discard" with no detail about what the user did. - Now: - Multiple edit sessions can be saved, even across different browser tabs - `IndexedDB` is async - doesn't block main thread / no slowdowns - `IndexedDB` size can store much more data than `LocalStorage` - effectively no limit - New Restore screen, we now show the user a list of their unsaved edits from previous sessions, details about when, where, what they did, and offer options to restore/delete. - If a legacy edit session is found in `LocalStorage`, it will be upgraded to a new edit session in `IndexedDB`. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> - Hide Rapid editor messages and links that refer to OpenStreetMap. - Remove Rapid’s `nsi` service and replace OpenStreetMap-related localization strings with Workspace labels. - Customize the post-save screen with an empty community-index response and disable community-data rendering. - Update the end-to-end Rapid stub to include `nsi`, `UiSuccess`, and localization hooks. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
The dashboard's Pathways Editor button now links to the edit page with editor=rapid3 (falling back to the Pathways editor when Rapid 3 isn't configured). The edit page now honors editor=rapid3 for any datatype instead of only osw. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port the Pathways editor's preset data (workspaces-pathways-editor data/pathways*.json @ 9a0534a) into a Rapid 3 schema asset, and merge it in Rapid3Manager#preStart for pathways workspaces. The OSM presets and categories are deleted first; OSM fields are kept for Rapid's own UI. FontAwesome icons Rapid 3 doesn't bundle are swapped for bundled ones. The edit page passes the datatype to Rapid3Manager.init and reloads instead of reusing a Rapid 3 instance set up for another datatype. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Tag reversed_signposted_as (was reverse_signposted_as). - is_bidirectional and wheelchair_boarding offer the GTFS enum codes (0/1, 0/1/2) with readable labels, which Rapid3Manager copies into Rapid's tagging strings for pathways workspaces. - level_id, parent_station and zone_id are free-text IDs, not numbers or a paid/unpaid choice. - Drop level_id from pathway presets; it's a stops.txt column only. - Platform preset also matches vertices, so platforms that end a pathway are recognized. - Unit tests check presets against the stops.txt/pathways.txt columns and enum values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Features drawn in the editor have no stop_id/pathway_id tag, so they exported with empty IDs (and pathways ending at them with empty from/to_stop_id). Keep the tagged ID when present, since other feed files reference it, and otherwise use the OSM element ID with a ws-n/ws-w prefix. Duplicated tags (e.g. from copy-paste) stay on the first feature; later ones get generated IDs. Stops are now resolved before pathways, so element order doesn't matter, and untagged elements no longer throw. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Write all stops.txt and pathways.txt columns from the GTFS reference, filled from same-named tags, instead of a fixed subset (length, stop_code, wheelchair_boarding, stop_access, etc. were dropped). - Quote CSV fields containing commas, quotes or line breaks. - A pathway's to_stop_id is its way's last node, not its second, and untagged bend nodes are no longer exported as stops. - from/to_stop_id always come from the way's nodes, never stale tags. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Levels are drawn as areas tagged with the levels.txt columns (a Level preset; level_index marks the area as a level). A panel next to Rapid 3 on pathways workspaces: - draws a new level outline (Rapid's area mode, pre-tagged as a level), - lists levels by level_index and shows one level at a time, hiding stops, boxes and pathways on other levels while keeping connections to other levels (and their far ends) visible, - flags stops with no level_id and level areas with no level_id, and assigns the shown level to stops, - connects two stops picked from lists grouped by level (e.g. an elevator), as an undoable edit. Level visibility wraps Rapid's FilterSystem isHidden/filterScene, since a pathway's level comes from its end stops rather than its tags. The export writes levels.txt from level areas, keeping the original dataset's levels unless a drawn level replaces them, and no longer treats level boxes as pathways or their corners as stops. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Each level in the panel says whether it has an outline (or how many); levels only stops use get a button to draw one, keeping their level_id. - New level outlines get a generated level_id (L<index>, suffixed if taken); level areas missing one get a "Fill level_id" button. - Entrances are no longer flagged for a missing level: they're where riders enter from the street, and level_id is optional in GTFS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Remove the Connect stops section and the Rapid3LevelTools.connect it used. "Draw level" becomes "Add level", since it creates a level (by drawing its outline). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The level panel lists levels highest first. Levels with an outline can be dragged (or moved with the arrow keys on their handle) to reorder them, which renumbers level_index on their outlines as one undoable edit: the ground level (0) keeps 0 and the others are numbered by their distance above or below it. Levels only stops use stay at the bottom, since level_index lives on the outline. The index is no longer shown in each level's tile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each level row shows its outline status on a second line; levels without one read "No outline, add one", where "add one" starts drawing the outline. The status moved out of the level's select button so the link isn't a button nested in a button; the whole row now carries the selected highlight. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GTFS levels don't belong to a station; they're linked through stops, which carry both level_id and parent_station (a boarding area's via its platform). With more than one station, the panel lists each station's levels under its name, repeating shared levels (e.g. a street level), with levels no station's stops use yet grouped last. Reordering stays within a station. Levels without an outline now show a dimmed handle whose tooltip says to add an outline first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The level panel's top entry is now "No station": it shows only features not tied to a station, with the levels no station uses listed under it, and is hidden when there's nothing outside a station. Each station's group ends with "No level", showing that station's features without a level_id (e.g. its street entrances), the station itself and pathways touching them. Clicking the selected entry again shows everything, which is also the initial state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For pathways workspaces, the raw tag editor shows a muted label next to coded values (pathway_mode 5 -> Elevator, location_type, is_bidirectional, wheelchair_boarding, stop_access), by wrapping the editor's render; the input keeps the raw code. The labels live in one module, which the schema's field option labels are checked against. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For coded keys (pathway_mode, location_type, is_bidirectional,
wheelchair_boarding, stop_access) the raw tag editor's value dropdown now
lists every code with its label ("5 Elevator"), instead of taginfo's
bare values; picking one enters the code. Done by wrapping the taginfo
service's values lookup for those keys only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For pathways workspaces, a "GTFS references" validator warns when: - parent_station doesn't match a stop_id, or names the wrong kind of stop (a station; a platform for boarding areas), is set on a station, or is missing where GTFS requires it (entrances, generic nodes, boarding areas); - level_id doesn't match a drawn level outline; - a stop_id is shared by several stops. Issues show in Rapid's Issues panel and on the selected feature. The checks are plain functions over an index of stops and levels, built once per graph. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…first Clicking a station's name in the level panel selects the station in Rapid (opening it in the sidebar). Each station's "No level" entry is now "Street / No level" and comes first, above the station's levels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With no map location in the URL, the editors opened at zoom 2 over 0,0. Fetch the workspace's bbox first and put a location that fits it in the URL for the editor to start from. A location already in the URL is kept, and an empty workspace or a failed lookup keeps the editor's default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The background was chosen by what covers the middle of the view, so local imagery covering only part of a workspace could win and leave the rest of it black. Check imagery against points across the workspace's extent, and prefer what covers all of them, falling back to the old choice when nothing does or the extent can't be fetched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The create pages said only OpenSidewalks files could be imported, but GTFS Pathways files can be too. - Test that level_index values like 0.0 and 1.0 read as 0 and 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rapid's close_nodes check only tells points apart by OSM's level and layer tags, so on pathways workspaces it warned about stops stacked on different floors, and about a station beside a generic node. Allow points with different level_ids or location_types to share a spot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A level with no outline or no level_index now shows an error icon on its row, which stays below the numbered levels. - A pathway with no stops at its ends was listed nowhere; it's on no level, so it now appears under "No level". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Levels with stops but no outline were only outlined on first opening the editor, and not at all if Rapid offered to restore unsaved edits. Outline them after every whole-workspace load, and after the restore prompt is dismissed or a restore finishes, never during one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moving any level also numbered every level with a shape but no level_index, which cleared their errors without anyone choosing a number. Now only the moved level takes a number from its position. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Background imagery now comes from, in order: the URL's background=, the imagery the user last picked for this workspace in this browser, then our pick from imagery covering the whole workspace. A URL or saved choice only has to cover the center of the view, so a deliberate partial-coverage choice like county imagery stays. Adding a start location to the URL also keeps the rest of its hash. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
### Changes Implemented * **Permission Validation on Create:** Clicking "Create Workspace" now calls the permission check API first, blocking creation and displaying the server reason if permission is denied. * **In-Flight Visual Feedback:** The button displays a spinner with "Checking permissions..." and an informational banner while the check API runs. * **Dataset Clear Button:** Added a one-click clear (`✕`) button inside the dataset picker to easily reset selected or typed text. * **Dataset Picker Reset on Focus:** Re-focusing the dataset input after an unmatched search automatically restores the full list of datasets instead of staying stuck on "No datasets found". ### Test Steps 1. **Test Dataset Clear & Recovery:** * Go to `/workspace/create/tdei` and select a Project Group. * Type non-existent text in the Dataset field to trigger "No datasets found", click outside the field, then click back into it — verify all datasets reappear. * Select a dataset and click the `✕` button — verify the field clears and the dropdown resets. 2. **Test Denied Creation (Restricted User / Dataset):** * Select a dataset where you do not have creation access. * Click **Create Workspace** — verify the button briefly says "Checking permissions...", creation stops, and a red error banner shows the denial reason. 3. **Test Successful Creation (Authorized User):** * Select a valid dataset where you have creation access. * Click **Create Workspace** — verify "Checking permissions..." briefly appears, the check succeeds, and the workspace is created successfully. <img width="1470" height="956" alt="Screenshot 2026-10-29 at 6 06 39 PM" src="https://github.com/user-attachments/assets/ac027076-26e0-4f9f-9c2a-95d39e751397" /> <img width="1470" height="956" alt="Screenshot 2026-10-29 at 6 06 41 PM" src="https://github.com/user-attachments/assets/fed881dd-92c7-469a-9189-63b6bcca2914" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary - Added a clear button and focus/blur handling to `DatasetPicker`. The picker reloads the full dataset list when needed, including after an unmatched search. - Updated `useWorkspaceCreateCheck` to expose `checking` and `check`. The check returns the backend result when available and ignores stale results. - Updated the TDEI workspace creation flow to check permissions before starting creation. The page displays a checking status, disables the create button during the check, and displays the denial reason when creation is not allowed. - Added unit tests for dataset picker behavior and permission-check state and invocation. Test execution results were not provided. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
The export kept the first outline's tags, losing whatever the others said, and an outline with no level_index wiped the original's. Outlines now fill in each other's blanks and the original's, and ones that disagree stop the export with a message naming them. The editor flags any level with more than one outline, since it's one row in levels.txt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Choosing a background now fetches the workspace's extent, so these tests loaded services/index, whose caches open IndexedDB. The rejections failed the run even though the tests passed. Stub the client they need. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A pathway with no stops at its ends has no station, and the No station group had no contents list, so these were still shown nowhere. It now expands like No level, and shows when only such a pathway is there. - A row no longer repeats a name equal to the level_index. - Test the close-points filter with points differing only by level. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… it (#182) Makes the editors open somewhere useful, and stops black tiles when imagery covers only part of a workspace. **Start at the data's extent** - With no `#map=` in the URL, the editors opened at zoom 2 over 0,0. The page now fetches the workspace's bbox and puts a location that fits it in the URL before the editor loads, so it works for Rapid 2, Rapid 3 and the Pathways editor. - A location in the URL is kept. An empty workspace or a failed lookup keeps the editor's default. The rest of the hash, such as `background=`, is kept. **Background imagery order** The background was chosen by what covered the middle of the view, so local imagery covering part of a workspace could win and leave the rest black (King County ortho on Sound Transit: tiles outside the county return HTTP 400 or solid black). It now comes from, in order: 1. `background=` in the URL, if it covers the center of the view. 2. The user's saved pick for this workspace, if it covers the center of the view. Partial coverage is fine because they chose it. 3. Our pick, only from sources covering the whole extent (nine points across the bbox): the current imagery, then the area's best, then the first. Worldwide sources count as full coverage. 4. If nothing covers the whole extent, what covers the center of the view. Picks are saved per workspace in the browser's local storage, from the Background pane only, so they don't follow a user to another computer. **Known limitation:** Rapid doesn't draw workspace data below zoom 12, so a workspace that only fits at a lower zoom opens showing the area but none of its data until you zoom in. **Testing** - Tried on Stage in real Rapid 3: Sound Transit now chooses Bing Aerial instead of King County ortho. - Not yet tried in real Rapid: picks sticking across loads, start at extent, and Rapid 2. These have unit and e2e tests against fake editors. - Lint and all unit tests pass. In e2e, everything passed except the two sign-in tests that hard-code `localhost:3000`, because the suite ran on port 3100 beside a dev server; CI's run on 3000 is the full check. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Custom imagery declares no coverage, so it counted as worldwide and followed the user into workspaces it doesn't cover. Only a choice can show it now. Rapid has one custom slot, so a saved custom pick keeps its own template. Document the imagery order in CLAUDE.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Makes the Stations panel read like a building, and flags levels that GTFS can't export properly. **Level rows** - Rows run from the highest `level_index` down through 0 to the negative ones. Dragging and the arrow keys still renumber correctly: higher in the list means a higher floor. The services keep their lowest-first order, so the validators and level dropdowns are unchanged. - Each row shows its `level_index`, or `–` if it has none. A row doesn't repeat a `level_id` that equals the index, or a name that equals the ID. - A level with no outline or no `level_index` has a red error icon explaining why, and sits below the numbered levels. It gets a number when that level itself is moved; moving another level leaves it blank, so the error stays until someone chooses. - "Street / No level" is now "No level". It lists nodes with no `level_id` and the edges touching them. - "No station" expands the same way. A pathway with no stops at either end used to appear nowhere and is now listed there. **Automatic outlines** - Levels with stops but no outline were only outlined on first opening the editor, and not at all if Rapid offered to restore edits. They're now outlined after every whole-workspace load, including workspace switches, and after the restore prompt is dismissed or a restore finishes. It never runs during a restore. - A level still gets one outline, however many stations use it, so the POSM hierarchy matches `levels.txt`. A shared level across distant stations keeps its large box and its "N km across" warning, which can be ignored. **Exporting levels without losing data** - `levels.txt` kept the first outline's tags when a `level_id` had several, dropping whatever the others said, and a blank `level_index` wiped the original dataset's value. Outlines now fill in each other's blanks and the original's, and `1` and `1.0` count as the same index. - **Behavior change:** outlines that really disagree on `level_index` or `level_name` now stop the export (Download and TDEI), with an error naming the level and values. A workspace with such outlines today won't export until they're fixed. **Validation** - A level with more than one outline gets a warning, which says when the conflict will block export. - Pathways workspaces no longer get Rapid's "Point is too close to Station" warning for points with different `level_id`s or `location_type`s, since Rapid only compares OSM's level and layer tags. TDEI's `tdei_stops_share_position` is unchanged: it allows different levels but not different types on one level, and it's INFO only. **Create pages** - The file import text now says "OpenSidewalks or GTFS Pathways". **Testing** - Tried on Stage data in real Rapid 3: level order, dragging and "No level". - Not tried in real Rapid: the outlining after restores and workspace switches, numbering a moved blank level, the "No station" contents, and the repeated-outline warning. These have unit tests against a fake editor. - The export changes have unit tests only. - Lint and all unit tests pass. In e2e, everything passed except the two sign-in tests that hard-code `localhost:3000`, because the suite ran on port 3100 beside a dev server; CI's run on 3000 is the full check. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Follow-up to #182, whose branch got this commit just after it merged. Custom imagery declares no coverage, so #182's check treated it as worldwide. A custom layer chosen on one workspace then followed the user into workspaces it doesn't cover, and left them black. - **We never pick custom imagery.** Only someone choosing it for that workspace, or a `background=` in the URL, can show it. A new workspace resets to imagery covering its whole extent. - **A custom pick keeps its own template.** Rapid has one custom slot, so setting a different custom URL on another workspace would otherwise change this one. - **`CLAUDE.md`** gets a "Background imagery" section with the order for choosing imagery. A custom layer chosen for a workspace always sticks there, since we can't tell whether it covers the area. **Testing:** only against fake imagery, not real Rapid. Lint, the type check and unit tests pass with CI's commands. In e2e, everything passed except the two sign-in tests that hard-code `localhost:3000`, because the suite ran on port 3100 beside a dev server; CI's run on 3000 is the full check. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Replace the old kartaview util with a new util/street-images.ts that extracts ext:street_images or ext:kartaview_url tags and resolves legacy KartaView/OpenStreetCam storage URLs into the CDN-proxied form. Update components and pages: rename UI label from "KartaView" to "Street Image" and switch imports/logic in review.vue to use streetImageUrl and resolveStreetImageUrl. Remove util/kartaview.ts and add unit tests (test/unit/util/street-images.test.ts) covering extraction and URL resolution behavior.
Trim trailing blank lines at end of test/unit/util/street-images.test.ts and util/street-images.ts for code cleanliness. No functional changes are made.
## DevBoard Task https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/4639 ### Changes Implemented - Added support for reading street-level image URLs from both `ext:street_images` and `ext:kartaview_url` tags on reviewed map elements. - Updated image URL resolution so self-hosted Panoramax URLs (and other standard image URLs) are loaded directly as-is, while retaining CDN proxy conversion only for legacy KartaView/OpenStreetCam storage URLs. - Replaced KartaView-specific naming and UI caption text (`KartaView` → `Street Image`) with generic street-image terminology. - Added unit tests covering `ext:street_images`, `ext:kartaview_url`, Panoramax URLs, KartaView CDN URLs, and legacy KartaView/OpenStreetCam URLs. ### Impacted Areas for Testing - **Review Queue - Panoramax Image Display:** Select a changeset in the workspace review page and click a map feature containing an `ext:street_images` tag (e.g., a Panoramax `/api/pictures/.../hd.jpg` URL). Verify the image thumbnail loads in the bottom-left preview panel on desktop and via the **"View photo submission"** button on smaller screens. - **Review Queue - KartaView Backward Compatibility:** Click a map feature containing an `ext:kartaview_url` tag (both `cdn.kartaview.org` links and legacy `kartaview.org` / `openstreetcam.org` storage links) and verify the image still displays as expected. - **Image Viewer & External Link:** Click the thumbnail (or **"View photo submission"** button) to verify the full-screen photo viewer modal opens, and click the **Street Image** link in the thumbnail caption to confirm it opens the image URL in a new browser tab. - **Elements Without Photos:** Click a map feature that has neither `ext:street_images` nor `ext:kartaview_url` and confirm no image panel or photo button is shown. ### Screenshots <img width="1469" height="877" alt="Screenshot 2026-11-04 at 5 59 15 PM" src="https://github.com/user-attachments/assets/b0a4d6f4-86f5-42f1-800e-162ed3206703" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 11 52 43 AM" src="https://github.com/user-attachments/assets/84991967-c333-4dd9-8ec1-6cc72d58eb71" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary - Added `streetImageUrl` to read trimmed `ext:street_images` values, with `ext:kartaview_url` as a fallback. - Added `resolveStreetImageUrl` to preserve standard image URLs and existing KartaView CDN URLs. It converts URLs on legacy KartaView and OpenStreetCam hosts to CDN-proxied URLs. - Updated the review page to use the new helpers and changed the image link label to “Street Image.” - Added unit tests for tag extraction and URL resolution. ## Testing Test execution results are not available. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Add a user-scoped dashboard selection utility and integrate it into the dashboard UI. Introduce util/dashboard-selection.ts (read/write/get key/resolve) to persist the selected project group and a per-project-group remembered workspace in localStorage, with safe parsing and legacy sessionStorage handling. Update pages/dashboard.vue to load/save the selection, resolve project group IDs, remember per-group workspaces, clear stale ?workspace= query params when switching to an empty project group, and remove the old sessionStorage helper functions. Adjust workspace members messaging in pages/workspace/[id]/settings/members.vue to show an access-denied message when appropriate and update the E2E test to expect the new text. Add unit tests for dashboard selection persistence (test/unit/util/dashboard-selection.test.ts) and update the e2e spec (test/e2e/settings-members.spec.ts).
Make dashboard selection read/write resilient to storage failures: add try/catch in loadDashboardSelection and saveDashboardSelection, merge latest stored state before writing, and update save API to accept the updated project group/workspace. Add helper utilities and small JSDoc comments in util/dashboard-selection.ts, and guard against invalid workspace IDs. Update workspace members UI to show a conditional message when access is denied and adjust E2E tests to assert the new structure. Add unit tests to cover storage get/set failures and a small doc update in street-images.ts.
…d fix non-POC members tab message (#186) ## DevBoard Task https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/4601 **Changes Implemented** - Persist the selected project group and last selected workspace per group in `localStorage` (per user). - Stop previous workspace selections from overriding the active project group on return to the dashboard. - Clear stale `?workspace=` URL query parameters when switching to an empty project group. - Fall back to the first available project group if access to the saved group is removed. **Impacted Areas for Testing** - Select an empty project group, navigate away, and return to the dashboard to confirm the empty project group stays selected. - Select a non-default workspace in one project group, switch to another group and back, and confirm that workspace stays selected. - Open the dashboard in a new tab or reload to confirm the last selected project group persists. - Open a direct `/dashboard?workspace=<id>` link to confirm it still opens that workspace and its project group. <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 17 PM" src="https://github.com/user-attachments/assets/02fa466d-3b24-4060-b9eb-dedceabeb94c" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 26 PM" src="https://github.com/user-attachments/assets/d34533fd-c891-4ed8-85da-b03f6732ea14" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 34 PM" src="https://github.com/user-attachments/assets/7cb4de93-29c9-4d37-95f9-f1612dd758ce" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 45 PM" src="https://github.com/user-attachments/assets/96caaabd-4c21-4435-8c95-ace0b7a6ed5a" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 59 PM" src="https://github.com/user-attachments/assets/d5a7aa65-d85f-4c52-a8bd-714ee15dcbfa" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 53 46 PM" src="https://github.com/user-attachments/assets/01d4d8fb-c3c7-4a42-94ee-0caf2af66db5" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 53 57 PM" src="https://github.com/user-attachments/assets/6bb22db1-4135-4e62-bbcd-4142e065d399" /> --- ## DevBoard Task https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/4400 **Changes Implemented** - Replace `"No one has a TDEI POC role in this project group."` with `"You do not have permission to view the member list."` on the Members tab. - Show `"You do not have permission to view the member list."` in the Data Generators and Workspace Members sections when a non-POC user is denied access (403). **Impacted Areas for Testing** - View Workspace Settings -> Members as a non-POC user and confirm all three sections show `"You do not have permission to view the member list."` - View Workspace Settings -> Members as a POC user and confirm member lists and empty role messages still display normally. <img width="1470" height="880" alt="Screenshot 2026-11-05 at 6 11 46 PM" src="https://github.com/user-attachments/assets/4738ae9d-473d-4d8c-8f94-7cab244a6cb2" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary - Persist the selected project group and each group’s last selected workspace in user-scoped `localStorage`. Restore saved selections when available, fall back to the first available group or workspace, and clear stale `?workspace=` parameters for empty groups. Use the legacy session-stored project group as a fallback. - Show “You do not have permission to view the member list.” in the Project Group Admins, Data Generators, and Workspace Members sections when access is denied. Preserve the existing empty-list messages when access is allowed. - Add dashboard-selection unit tests and update the unauthorized-user E2E expectations. ## Checks - CI, build, and test results: not available. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## DevBoard Task https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/4639 ### Changes Implemented - Added support for reading street-level image URLs from both `ext:street_images` and `ext:kartaview_url` tags on reviewed map elements. - Updated image URL resolution so self-hosted Panoramax URLs (and other standard image URLs) are loaded directly as-is, while retaining CDN proxy conversion only for legacy KartaView/OpenStreetCam storage URLs. - Replaced KartaView-specific naming and UI caption text (`KartaView` → `Street Image`) with generic street-image terminology. - Added unit tests covering `ext:street_images`, `ext:kartaview_url`, Panoramax URLs, KartaView CDN URLs, and legacy KartaView/OpenStreetCam URLs. ### Impacted Areas for Testing - **Review Queue - Panoramax Image Display:** Select a changeset in the workspace review page and click a map feature containing an `ext:street_images` tag (e.g., a Panoramax `/api/pictures/.../hd.jpg` URL). Verify the image thumbnail loads in the bottom-left preview panel on desktop and via the **"View photo submission"** button on smaller screens. - **Review Queue - KartaView Backward Compatibility:** Click a map feature containing an `ext:kartaview_url` tag (both `cdn.kartaview.org` links and legacy `kartaview.org` / `openstreetcam.org` storage links) and verify the image still displays as expected. - **Image Viewer & External Link:** Click the thumbnail (or **"View photo submission"** button) to verify the full-screen photo viewer modal opens, and click the **Street Image** link in the thumbnail caption to confirm it opens the image URL in a new browser tab. - **Elements Without Photos:** Click a map feature that has neither `ext:street_images` nor `ext:kartaview_url` and confirm no image panel or photo button is shown. ### Screenshots <img width="1469" height="877" alt="Screenshot 2026-11-04 at 5 59 15 PM" src="https://github.com/user-attachments/assets/b0a4d6f4-86f5-42f1-800e-162ed3206703" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 11 52 43 AM" src="https://github.com/user-attachments/assets/84991967-c333-4dd9-8ec1-6cc72d58eb71" /> ## DevBoard Task https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/4601 **Changes Implemented** - Persist the selected project group and last selected workspace per group in `localStorage` (per user). - Stop previous workspace selections from overriding the active project group on return to the dashboard. - Clear stale `?workspace=` URL query parameters when switching to an empty project group. - Fall back to the first available project group if access to the saved group is removed. **Impacted Areas for Testing** - Select an empty project group, navigate away, and return to the dashboard to confirm the empty project group stays selected. - Select a non-default workspace in one project group, switch to another group and back, and confirm that workspace stays selected. - Open the dashboard in a new tab or reload to confirm the last selected project group persists. - Open a direct `/dashboard?workspace=<id>` link to confirm it still opens that workspace and its project group. <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 17 PM" src="https://github.com/user-attachments/assets/02fa466d-3b24-4060-b9eb-dedceabeb94c" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 26 PM" src="https://github.com/user-attachments/assets/d34533fd-c891-4ed8-85da-b03f6732ea14" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 34 PM" src="https://github.com/user-attachments/assets/7cb4de93-29c9-4d37-95f9-f1612dd758ce" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 45 PM" src="https://github.com/user-attachments/assets/96caaabd-4c21-4435-8c95-ace0b7a6ed5a" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 52 59 PM" src="https://github.com/user-attachments/assets/d5a7aa65-d85f-4c52-a8bd-714ee15dcbfa" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 53 46 PM" src="https://github.com/user-attachments/assets/01d4d8fb-c3c7-4a42-94ee-0caf2af66db5" /> <img width="1470" height="956" alt="Screenshot 2026-11-05 at 5 53 57 PM" src="https://github.com/user-attachments/assets/6bb22db1-4135-4e62-bbcd-4142e065d399" /> --- ## DevBoard Task https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/4400 **Changes Implemented** - Replace `"No one has a TDEI POC role in this project group."` with `"You do not have permission to view the member list."` on the Members tab. - Show `"You do not have permission to view the member list."` in the Data Generators and Workspace Members sections when a non-POC user is denied access (403). **Impacted Areas for Testing** - View Workspace Settings -> Members as a non-POC user and confirm all three sections show `"You do not have permission to view the member list."` - View Workspace Settings -> Members as a POC user and confirm member lists and empty role messages still display normally. <img width="1470" height="880" alt="Screenshot 2026-11-05 at 6 11 46 PM" src="https://github.com/user-attachments/assets/4738ae9d-473d-4d8c-8f94-7cab244a6cb2" />
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
MashB
approved these changes
Nov 10, 2026
sujata-m
approved these changes
Nov 10, 2026
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promote the current
stagingrelease toproduction.This release introduces comprehensive GTFS Pathways editing in Rapid 3, workspace merging with conflict resolution, expanded review workflows, improved workspace creation permissions, and imagery enhancements including Panoramax support. It also consolidates frontend API usage, updates core dependencies, and improves deployment caching, loading, and error reporting.
Changes
Features
fixmeitems in the review queue.Bug fixes
Maintenance
VITE_NEW_API_URL(Use one workspaces API URL, dropping the "new" API #175).Deployment considerations
VITE_NEW_API_URLis no longer used.VITE_API_URLmust point to the production API containing the consolidated endpoints.VITE_RAPID3_URLand Pathways-related service URLs before deployment.ENV=production, which is used as the Sentry environment./_nuxt/*assets are cached for one year, while build manifests remain uncached. Confirm Azure Static Web Apps applies the updated routing configuration.Testing
Tests were added or updated throughout this release, but no test commands were executed while preparing this PR summary.
npm run typecheck.npm test.Rollback
Redeploy the previous production commit,
9612488, if frontend issues are found.Because this release depends on consolidated backend endpoints and updated editor behavior, coordinate the rollback with any related backend or Rapid deployments if those services were changed for this release.