Conversation
- Added new keys and translations for the patrol overview section in English, Spanish, French, Nepali, Portuguese, and Swahili localization files. - Updated AGENTS.md to clarify styling guidelines for component-specific styles and internationalization practices. - Refactored the KebabMenu component to improve accessibility and usability, including enhanced keyboard navigation and focus management. - Incremented the I18N_FILES_VERSION to reflect updates in localization files.
There was a problem hiding this comment.
🟡 Changes recommended
There are confirmed accessibility/runtime issues (time elements’ aria-label overriding content, non-keyboard-accessible clickable table rows, and a broken ref expectation in KebabMenu.Option) that should be addressed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR introduces a new Patrol Overview experience in the sidebar and refactors patrol track/geometry utilities and selectors to support multi-leg patrols, while also modernizing shared UI components (Date/Time, Kebab menu) and aligning sidebar detail-view sizing across screens.
Changes:
- Added the
SideBar/PatrolsManager/PatrolOverviewfeature (header/tabs/overview/history/footer) with initial scaffolding and tests. - Refactored patrol selectors/utils to build per-leg track data and combined patrol track/markers/bounds across legs.
- Reworked
KebabMenu,DateTime, andTimeAgocomponents and updated dependent tests/styles.
File summaries
| File | Description |
|---|---|
| vite.config.mjs | Adds Vite build configuration including JSX handling for .js sources and Osano injection. |
| src/utils/patrols.test.js | Adds unit coverage for new patrol utility helpers (bounds, markers, labels, icon selection). |
| src/utils/patrols.js | Refactors patrol type lookup, start/end time helpers, per-leg marker extraction, and bounds calculation. |
| src/utils/auth-recovery.test.js | Fixes async expectation usage for timer-based auth recovery timeouts. |
| src/TrackToggleButton/PatrolAwareTrackToggleButton.js | Adds preview-feature-aware patrol track toggling logic and adjusts props. |
| src/TimeAgo/index.js | Refactors elapsed-time rendering into a semantic <time> element. |
| src/SideBar/styles.module.scss | Fixes responsive sidebar transform and adds noHeader tab body styling. |
| src/SideBar/PatrolsManager/PatrolOverview/styles.module.scss | Adds layout and tab styling for the new Patrol Overview container. |
| src/SideBar/PatrolsManager/PatrolOverview/Overview/Legs/styles.module.scss | Adds table/button styling for legs list UI. |
| src/SideBar/PatrolsManager/PatrolOverview/Overview/Legs/index.test.js | Adds RTL coverage for legs table rendering, navigation, and zoom-to-bounds behavior. |
| src/SideBar/PatrolsManager/PatrolOverview/Overview/Legs/index.js | Implements legs table UI, per-leg bounds calculation, and navigation hooks. |
| src/SideBar/PatrolsManager/PatrolOverview/Overview/index.test.js | Adds basic Overview tab rendering coverage. |
| src/SideBar/PatrolsManager/PatrolOverview/Overview/index.js | Composes Legs + Activity sections for the Overview tab. |
| src/SideBar/PatrolsManager/PatrolOverview/Overview/Activity/styles.module.scss | Adds styling for the (scaffolded) activity section UI. |
| src/SideBar/PatrolsManager/PatrolOverview/Overview/Activity/index.js | Adds scaffolded Activity UI with placeholder feed/stats and translated labels. |
| src/SideBar/PatrolsManager/PatrolOverview/index.test.js | Adds RTL coverage for PatrolOverview data loading, tabs, and track-fetch behavior. |
| src/SideBar/PatrolsManager/PatrolOverview/index.js | Introduces PatrolOverview route component: fetch patrol + leg tracks, render header/tabs/footer. |
| src/SideBar/PatrolsManager/PatrolOverview/History/styles.module.scss | Adds styling for patrol history updates list and actions. |
| src/SideBar/PatrolsManager/PatrolOverview/History/index.test.js | Adds RTL coverage for history sorting and rendering updates/user names. |
| src/SideBar/PatrolsManager/PatrolOverview/History/index.js | Implements history list with sort toggle and aggregated updates from multiple sources. |
| src/SideBar/PatrolsManager/PatrolOverview/Header/styles.module.scss | Adds styling for breadcrumbs, actions, title editing, and status pill. |
| src/SideBar/PatrolsManager/PatrolOverview/Header/index.test.js | Adds RTL coverage for header actions (toggle track, jump, bounds, kebab menu, print/download). |
| src/SideBar/PatrolsManager/PatrolOverview/Header/index.js | Implements PatrolOverview header (breadcrumbs, actions, title input, printing, download track). |
| src/SideBar/PatrolsManager/PatrolOverview/Footer/styles.module.scss | Adds styling for footer action buttons and status dropdown. |
| src/SideBar/PatrolsManager/PatrolOverview/Footer/index.js | Adds scaffolded footer actions (notes/attachments/event/status/save). |
| src/SideBar/PatrolsManager/PatrolOverview/_shared.scss | Adds shared SCSS mixins for icon/chip buttons and card styling. |
| src/SideBar/PatrolsManager/index.test.js | Updates PatrolsManager tests to mock the new PatrolOverview route. |
| src/SideBar/PatrolsManager/index.js | Wires /patrols/:patrolId to the new PatrolOverview component. |
| src/SideBar/index.test.js | Adds coverage for hiding the default sidebar header when patrol schemas preview is active. |
| src/SideBar/index.js | Hides default sidebar header for patrol item view when patrol schemas preview is enabled. |
| src/selectors/patrols/index.js | Refactors patrol selectors to compute per-leg track data and combined patrol track/markers. |
| src/SchemaForm/formElements/Attachment/index.test.js | Normalizes string quoting in assertions for upload error messages. |
| src/ReportManager/ReportDetailView/styles.module.scss | Uses shared sidebar detail view width mixin for consistent sizing. |
| src/ReportManager/Header/styles.module.scss | Adjusts menu spacing. |
| src/PatrolTrackLayer/index.js | Updates patrol track rendering to render one track layer per leg. |
| src/PatrolTrackControls/index.js | Adjusts controls to use new patrol track selector structure and preview gating. |
| src/PatrolStartStopLayer/layer.js | Migrates to selectPatrolTrackData naming and updated patrol track data shape. |
| src/PatrolMenu/styles.module.scss | Adjusts dropdown link color to match app palette. |
| src/PatrolMenu/index.test.js | Updates tests to treat download option as a disabled button (not a disabled link). |
| src/PatrolMenu/index.js | Removes unused menuRef prop wiring. |
| src/PatrolListItem/index.test.js | Updates kebab-menu interaction tests to use aria-expanded behavior. |
| src/PatrolListItem/index.js | Updates to new usePatrol return shape and removes menu overlap workaround. |
| src/PatrolDetailView/styles.module.scss | Uses shared sidebar detail view width mixin for consistent sizing. |
| src/PatrolDetailView/index.js | Updates patrol snapshot state to use selectPatrolTrackData output. |
| src/PatrolDetailView/Header/styles.module.scss | Adjusts header menu spacing. |
| src/PatrolDetailView/Header/index.js | Updates distance component wiring to new patrol track data shape; adds menu className. |
| src/KebabMenuIcon/styles.module.scss | Removes deprecated kebab icon styling. |
| src/KebabMenuIcon/index.js | Removes deprecated KebabMenuIcon component. |
| src/KebabMenu/styles.module.scss | Replaces bootstrap dropdown styling with custom popover/menu styling. |
| src/KebabMenu/index.test.js | Adds comprehensive accessibility and keyboard navigation tests for the new KebabMenu. |
| src/KebabMenu/index.js | Reimplements KebabMenu using Overlay/Popover with focus management and menu semantics. |
| src/i18n.js | Bumps i18n file version to invalidate cached translations. |
| src/hooks/usePatrol/index.js | Switches to selectPatrolTrackData and updates derived values accordingly. |
| src/DateTime/styles.module.scss | Refactors DateTime styles and class naming for updated markup. |
| src/DateTime/index.js | Refactors DateTime to use semantic <time> and pass suffix through to TimeAgo. |
| src/common/styles/_layout.scss | Introduces a shared sidebar detail-view width constant + mixin. |
| src/common/images/icons/fit-screen.svg | Adds new icon asset used in patrol/leg zoom actions. |
| src/common/images/icons/arrow-right-from-line.svg | Adds new icon asset used in “New Patrol Leg” button. |
| src/__test-helpers/fixtures/patrols.js | Adds a multiLegPatrol fixture to support new multi-leg UI/tests. |
| public/locales/sw/patrols.json | Adds Patrol Overview translations (Swahili). |
| public/locales/pt/patrols.json | Adds Patrol Overview translations (Portuguese). |
| public/locales/ne-NP/patrols.json | Adds Patrol Overview translations and fixes an existing string (Nepali). |
| public/locales/fr/patrols.json | Adds Patrol Overview translations and adjusts existing strings (French). |
| public/locales/es/patrols.json | Adds Patrol Overview translations (Spanish). |
| public/locales/en-US/patrols.json | Adds Patrol Overview translations (English). |
| AGENTS.md | Updates styling + i18n documentation guidance to reflect current conventions. |
Review details
Suppressed comments (2)
src/utils/patrols.js:700
getBoundsForPatrolcan throw whenstartStopGeometriesis present buttrackData.trackis missing, because it unconditionally readspatrolTrack.features. SincepatrolHasGeoDataToDisplaytreatsstartStopGeometriesalone as sufficient geo data, this should safely handle a missing track by using an empty feature list.
src/KebabMenu/index.js:178- Same compatibility concern as above:
toReversed()can break in browsers without support. Replace withreverse()on the sliced arrays.
// Options before the current one, then wrap around to the options after
// (and including) it, both walked backwards.
[...options.slice(0, currentIndex).toReversed(), ...options.slice(currentIndex).toReversed()]
.some((option) => focusItemNode(option.nodeRef.current));
- Files reviewed: 64/68 changed files
- Comments generated: 7
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
…ssibility and consistency - Updated DateTime component to use a formatted date variable for aria-label and displayed text. - Enhanced TimeAgo component to include elapsed time in its accessible name. - Refactored KebabMenu component to improve keyboard navigation and focus management. - Added tests to ensure proper functionality of KebabMenu and TimeAgo components, including keyboard accessibility for the copy button in PatrolMenu.
- Bumped versions for @turf/buffer and @turf/turf to 7.4.0. - Updated dompurify to version 3.4.13. - Upgraded @testing-library/user-event to 14.6.3. - Incremented globals to version 17.9.0. - Removed deprecated entries from yarn.lock for @emnapi/core and @emnapi/runtime.
…ding and state management - Replaced downloadFileFromUrl with downloadJsonAsFile for downloading patrol track data in JSON format. - Implemented state synchronization for patrol title when the patrol changes without unmounting the component. - Updated tests to reflect changes in download functionality and added a test for title resynchronization.
…rieval - Replaced useLocation with useParams for improved URL parameter handling in PatrolOverview. - Updated tests to mock useParams for consistent patrol ID retrieval during testing. - Simplified track download functionality in the Header component by inlining the download logic.
- Updated sidebar width variables and mixins for consistency across components. - Replaced hardcoded sidebar widths with new variables in App.scss, PatrolDetailView, ReportDetailView, and SideBar styles. - Ensured responsive design by utilizing the updated mixin for sidebar width in PatrolOverview styles.
… management and accessibility - Refactored AddToPatrolModal to include timeSliderState and trackSettings in the default store value. - Updated DateTime component to utilize memo for performance optimization and improved aria-label handling. - Enhanced FeedListItem to prevent patrol opening when clicking on controls, with corresponding tests for click behavior. - Improved KebabMenu to support additional focusable elements and refined styles for better user interaction. - Updated PatrolTrackControls to integrate jump-to-location functionality based on patrol track data. - Added event filter and track settings to various components and tests for consistent state management across the application.
What does this PR do?
Adds the
PatrolOverviewcomponent, and improves existing reusable utilities, selectors, and components.Evidence
Relevant link(s)
Notes
The Activity section and the footer are not implemented yet. The PR was growing too much so I decided to divide the work in two PRs.