Commit cca73f6
authored
feat(nav): merge foundation and project lenses for hybrid personas (#713)
* feat(nav): merge foundation/project lenses for hybrid personas
- Add isHybridPersona signal to LensService; availableLenses suppresses
the separate foundation button for hybrid users
- Preload both lens item sets in NavigationService for hybrid users so
the merged dropdown has both ready immediately
- Add isLensActive() helper to LensSwitcherComponent so the merged
Projects button appears active for both foundation and project states
- Rewrite ProjectSelectorComponent with hybrid mode: All/Foundations/
Projects tabs, role-sorted items (ED→BM→alpha / Maintainer→Contributor
→alpha), projects nested under parent foundation in the All tab, and
a transparent/borderless search input
- Update SidebarComponent to switch the active lens based on
item.isFoundation when an item is selected in hybrid mode
- Update project lens constant: icon → fa-layer-group, label → Projects
Signed-off-by: Nuno Eufrasio <nuno.eufrasio@linuxfoundation.org>
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* fix(nav): exclude foundations from project lens dropdown
The project-lens API can include foundations the user has access to,
but those belong in the foundation lens (or the Foundations tab in
hybrid mode) — never in the projects list. Filter them out so a
project-only Contributor doesn't see foundation entries.
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* refactor(nav): refine role display in lens selector and me card
Polish how persona roles surface across the hybrid lens experience:
- selector trigger now shows a compact role-icon badge with tooltip instead of inline text, with left-aligned, truncating description
- dropdown rows render the role icon + label inline beneath each project/foundation name
- nested project connector lines align with the parent foundation logo
- me-lens user card collapses to inline "<icon> Role" for a single persona and to circular icon-only badges with a rich HTML tooltip (role name + bulleted project/foundation list) for multiple personas
- tooltip width hugs content so role/project entries never wrap
Generated with [Claude Code](https://claude.ai/code)
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* fix(nav): address review feedback on hybrid lens selector
- Scope hybrid pagination (hasMore/loadMore) to the active tab so the
Projects tab can keep advancing instead of exhausting foundations first.
- Restore `availableLenses` to the full allowed set and add a separate
`displayLenses` for the sidebar switcher, so downstream consumers
(NavigationService.applyVisibilityFilters / foundationVisibilityWatcher)
keep filtering foundations out of the project lens for hybrid users.
- Replace `[class]` with `[ngClass]` on role icons so the static
`text-[10px]` styling isn't wiped out.
- Make tooltip-only role badges (selector trigger + Me-card multi-role)
focusable via `tabindex="0"` + `role="img"` + `aria-label`, with a
focus ring so keyboard users can reveal the role info.
- Drop `role=tablist`/`role=tab` from the hybrid filter pills (they
aren't a true tabs widget); use `role=group` + `aria-pressed` instead.
- Swap hard-coded SVG hex fills on the fallback logo for `fill-blue-500`
and `fill-blue-800` tokens.
- Pre-group nested projects by parent uid so `buildAllTabItems` runs in
O(F + P) rather than O(F × P).
- Fix the stale comment that described the parent-uid map as the inverse
of what the code actually builds.
Generated with [Claude Code](https://claude.ai/code)
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* refactor(nav): apply second-round review feedback on lens merge
- Precompute per-row selector state (isSelected, roleLabel, roleIcon) into
DisplayLensItem so the template stops re-invoking methods on every
change-detection pass.
- Move DisplayLensItem + SelectorTab into @lfx-one/shared/interfaces.
- Restore the initializeXxx() pattern for complex computeds in
project-selector so the field block stays scannable.
- Replace lens-switcher.isLensActive() method with an activeLensId
computed and use it directly in templates.
- Replace sidebar persona-tooltip HTML-string building (with [escape]=false)
with structured data + an inline <ng-template> rendered through pTooltip,
so Angular handles escaping.
- Collapse the two remaining multi-line inline comments to single lines.
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* fix(nav): address third-round review feedback on lens merge
- Use a type-only import in lens.interface.ts to break a runtime
circular dependency with navigation.interface.ts.
- Reorder sidebar.onItemSelected so the project/foundation context is
set before the lens flips. NavigationService injects selected_uid from
ProjectContextService at reload time, and the previous ordering let
the lens reload run with the stale selection.
- Add a preloadSibling() path in NavigationService that triggers a
reload without setting pendingDefaultSelection and bails when the
sibling lens is already loaded or in flight, so hybrid preload can't
race with the active lens or overwrite the URL/context.
- Hybrid-aware emptyMessage on the project selector — show
'No results found' instead of a single-lens-specific copy when the
dropdown is rendering mixed All/Foundations/Projects tabs.
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* fix(nav): fall back to user persona when item lookup misses
For non-hybrid users, personaProjects only contains projects with
explicit role detections, but the navigation API returns every
accessible project. The role badge/description was missing whenever a
listed item had no detection entry — even though the user's scope
(board-only or project-only) makes the role unambiguous.
When the per-item lookup misses for a non-hybrid user, surface the
highest-priority persona they hold (executive-director → board-member,
maintainer → contributor) so every row in the dropdown and the trigger
badge consistently show the role icon and label.
Generated with [Claude Code](https://claude.ai/code)
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* fix(nav): address PR #713 review feedback
- project-selector.component.html: remove nested tabindex="0" from role
badge span inside trigger button; the parent button already handles
focus/hover for the pTooltip, so the inner span doesn't need its own
tab stop (invalid HTML).
- navigation.service.ts: add hybridTransitionPreloader so the sibling
lens preloads when a persona refresh promotes the user to hybrid
mid-session without an activeLens change.
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* fix(nav): address PR #713 fourth-round review feedback
- sidebar.component.ts: project-only users see foundations in their
project list (NavigationService only filters foundations out when the
foundation lens is visible). onItemSelected now treats foundation rows
as a project context for those users so setLens('foundation') doesn't
silently no-op and leave the selection unchanged.
- sidebar.component.html: switch persona tooltip @for from `track name`
to `track $index` — project/foundation names can legitimately repeat
and would produce duplicate track keys.
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* fix(nav): address PR #713 fifth-round review feedback
- project-selector.component.ts: remove unused `items` signal alias —
template binds to `displayedItems()` and the class never reads it.
- sidebar.component.ts/html: include the associated project names in
the persona badge `aria-label` so screen-reader users get the same
info as the hover tooltip without relying on hover-only UI.
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
* fix(nav): stop double-filtering foundations from project lens
NavigationService.applyVisibilityFilters already strips foundations
from the project lens for users who can switch to the foundation lens
(hybrid + ED/Board-only). For project-only users it intentionally keeps
them so they can still be selected. The component-level filter was
redundant for the first group and silently hid foundations from
project-only users — also bypassing sidebar.onItemSelected's path
for handling foundation rows in that case.
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>
---------
Signed-off-by: Nuno Eufrasio <nuno.eufrasio@linuxfoundation.org>
Signed-off-by: Nuno Eufrasio <nmeufrasio@gmail.com>1 parent a8d8397 commit cca73f6
11 files changed
Lines changed: 492 additions & 88 deletions
File tree
Lines changed: 4 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
12 | | - | |
13 | | - | |
| 13 | + | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
65 | 66 | | |
66 | 67 | | |
67 | 68 | | |
68 | | - | |
| 69 | + | |
69 | 70 | | |
70 | 71 | | |
71 | 72 | | |
| |||
Lines changed: 8 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
39 | 45 | | |
40 | 46 | | |
41 | 47 | | |
| |||
Lines changed: 81 additions & 25 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | | - | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
23 | 36 | | |
24 | 37 | | |
25 | 38 | | |
| |||
34 | 47 | | |
35 | 48 | | |
36 | 49 | | |
| 50 | + | |
37 | 51 | | |
38 | | - | |
| 52 | + | |
39 | 53 | | |
40 | 54 | | |
41 | 55 | | |
42 | 56 | | |
43 | 57 | | |
44 | 58 | | |
45 | | - | |
| 59 | + | |
46 | 60 | | |
47 | 61 | | |
48 | 62 | | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
49 | 83 | | |
50 | | - | |
51 | | - | |
| 84 | + | |
| 85 | + | |
52 | 86 | | |
53 | 87 | | |
54 | 88 | | |
| |||
57 | 91 | | |
58 | 92 | | |
59 | 93 | | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
74 | 127 | | |
75 | 128 | | |
76 | | - | |
77 | 129 | | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
82 | 138 | | |
83 | 139 | | |
84 | 140 | | |
| |||
0 commit comments