Replace navigateLean with getWithChildren for the timeline view - #1138
Replace navigateLean with getWithChildren for the timeline view#1138aasandei-vsp wants to merge 3 commits into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## PER-10679-replace-navigate-lean-publish #1138 +/- ##
===========================================================================
- Coverage 52.83% 52.16% -0.67%
===========================================================================
Files 355 360 +5
Lines 12154 12542 +388
Branches 2206 2274 +68
===========================================================================
+ Hits 6422 6543 +121
- Misses 5504 5764 +260
- Partials 228 235 +7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
229dc80 to
ac8d6e8
Compare
01eddfb to
f22d6d7
Compare
ac8d6e8 to
8aeaf3b
Compare
8aeaf3b to
28badda
Compare
f22d6d7 to
476f085
Compare
28badda to
99b406c
Compare
In order for the migration of the timeline to be complete, we needed to map some extra fields to stela: folderLinkIds, archiveNumbers, accessRole. And for deep links, we needed to be able to get folders using the properties mentioned above, so we needed an extra call to the old API, because if the user is deep in a folder and uses the browser refresh, the only way to identity the folder you were in, would be using the archiveNbr and the folder_linkId, which is not possible using the stela endpoints. Issue: PER-10677
Lean folder response uses now getWithChildren instead of navigateLean and returns consistently a promise, no observable. Stela rejects with a raw http error, which is different from the old backend, so a specific error message handler was needed. Issue: PER-10677
The timeline folder navigation, going into a folder used the navigateLean endpoint, so we replaced it with getWithChildren. The fact that we are making a BE call from a component that otherwise does not have this kind of logic is counterintuitive, but the needed refactoring to extract this logic is out of scope for the current work and it would need testing many other places. Issue: PER-10677
99b406c to
3bae6b8
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Breadcrumb identifier handling can still produce invalid null/undefined path segments and the deep-link resolver currently passes folder_linkId as a string instead of a number, risking incorrect navigation and requests.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR migrates timeline navigation (and lean folder resolving) from the legacy navigateLean v1 endpoint to Stela-backed getWithChildren via a new getWithChildrenByIdentifier helper, while also translating Stela accessRole values into the app’s access.role.* permissions model.
Changes:
- Update timeline folder navigation and lean folder resolver to use
getWithChildrenByIdentifierand unify error handling viagetFolderErrorMessage. - Extend Stela folder/record conversion to map breadcrumbs (
pathAsArchiveNbr,pathAsFolder_linkId) and translateaccessRole. - Add/expand unit tests for timeline view, timeline breadcrumbs, access-role translation, folder repo behavior, and lean folder resolver.
File summaries
| File | Description |
|---|---|
| src/app/views/components/timeline-view/timeline-view.component.ts | Switch folder navigation to getWithChildrenByIdentifier with toast error handling. |
| src/app/views/components/timeline-view/timeline-view.component.spec.ts | Add unit tests around onFolderClick success/error behavior. |
| src/app/views/components/timeline-view/timeline-breadcrumbs/timeline-breadcrumbs.component.spec.ts | Add breadcrumb construction tests from currentFolder path arrays. |
| src/app/shared/utilities/folder-error-message.ts | Introduce shared helper for deriving a translatable folder-load error key. |
| src/app/shared/services/api/record.repo.ts | Translate Stela accessRole into access.role.* and preserve optionality. |
| src/app/shared/services/api/record.repo.spec.ts | Add tests for access-role translation and merging behavior. |
| src/app/shared/services/api/folder.repo.ts | Map breadcrumb arrays from Stela payload and add getWithChildrenByIdentifier. |
| src/app/shared/services/api/folder.repo.spec.ts | Add tests for breadcrumb mapping, identifier resolution, and role translation. |
| src/app/models/access-role.ts | Add Stela archive-membership role types + translation utilities. |
| src/app/models/access-role.spec.ts | Add tests ensuring translation coverage and compatibility with existing enums. |
| src/app/core/resolves/lean-folder-resolve.service.ts | Convert resolver to async/await and use getWithChildrenByIdentifier + shared error message helper. |
| src/app/core/resolves/lean-folder-resolve.service.spec.ts | Add resolver tests for defaults, deep links, share record case, and error redirects. |
Review details
Suppressed comments (1)
src/app/core/resolves/lean-folder-resolve.service.ts:35
folder_linkIdonFolderVOis anumber, but the deep-link resolver passes the raw route param string through. This can break strict-equality comparisons and can lead to malformed requests when the repo expects numeric link ids; coerce it to a finite number (or leave it undefined so the existing error path can redirect).
if (route.params.archiveNbr && route.params.folderLinkId) {
targetFolder = new FolderVO({
archiveNbr: route.params.archiveNbr,
folder_linkId: route.params.folderLinkId,
});
- Files reviewed: 12/12 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| pathAsText: stelaFolder.paths?.names, | ||
| pathAsArchiveNbr: stelaFolder.paths?.archiveNumbers, | ||
| pathAsFolder_linkId: stelaFolder.paths?.folderLinkIds?.map((folderLinkId) => | ||
| toFolderLinkId(folderLinkId), | ||
| ), |
| expect(requestedFolder.archiveNbr).toBe('0001-0005'); | ||
| expect(requestedFolder.folder_linkId).toBe('99' as any); | ||
| expect(requestedFolder.folderId).toBeUndefined(); |
| it('should map the breadcrumb archive numbers', async () => { | ||
| const folder = await convertFolder({ | ||
| paths: { | ||
| names: ['My Files', 'Photos'], | ||
| folderLinkIds: ['11', '22'], |
Warning
Do not merge before #1135 , this PR depends on the mappings from that specific PR
Depends on accessRole being on stela records and folders
Manual test cases — timeline view moved from navigateLean to getWithChildren
Note
The timeline folder tiles no longer show an
N itemscount. That is expected — Stela'sfolder payload has no record-count field. The tile renders without the count line rather
than showing zero.
Timeline navigation ⭐
Scenario — loading the timeline
Scenario — clicking a folder in the timeline
Scenario — clicking a breadcrumb
change. It does not just zoom or refit in place.
Scenario — deep link
/app/private/view/timeline/{archiveNbr}/{folderLinkId}and open it in a fresh tab.
Permissions ⭐
(run as both the owner and the Viewer account — the point is that the two differ)
Stela reports the caller's role as
owner/viewer, which this PR translates intoaccess.role.owner/access.role.viewer. Untranslated, every gate denied.Scenario — owner keeps their actions
Scenario — viewer is still restricted
Breadcrumbs outside the timeline
Scenario — unlisted share breadcrumbs
nullorundefinedsegment such as/private/null/194781.Shared record via share preview
Scenario — open a shared record
Error handling
Scenario — deep link to a folder that does not exist
folderLinkIdand load it./private. Previouslythis threw a
TypeErrorinside the error handler, because the deep-link target has notypeto call.includes('root')on.