diff --git a/apps/lfx-one/src/app/app.component.ts b/apps/lfx-one/src/app/app.component.ts index b1292477..9655580b 100644 --- a/apps/lfx-one/src/app/app.component.ts +++ b/apps/lfx-one/src/app/app.component.ts @@ -8,6 +8,7 @@ import { AuthContext } from '@lfx-one/shared/interfaces'; import { ToastModule } from 'primeng/toast'; import { FeatureFlagService } from './shared/services/feature-flag.service'; +import { PersonaService } from './shared/services/persona.service'; import { SegmentService } from './shared/services/segment.service'; import { UserService } from './shared/services/user.service'; @@ -19,6 +20,7 @@ import { UserService } from './shared/services/user.service'; }) export class AppComponent { private readonly userService = inject(UserService); + private readonly personaService = inject(PersonaService); private readonly segmentService = inject(SegmentService); private readonly featureFlagService = inject(FeatureFlagService); @@ -42,16 +44,20 @@ export class AppComponent { this.transferState.set(this.serverKey, this.auth); } - // Hydrate the auth s tate from the server, if it exists, otherwise set it to false and null + // Hydrate the auth state from the server, if it exists, otherwise set it to false and null this.auth = this.transferState.get(this.serverKey, { authenticated: false, user: null, + persona: null, }); if (this.auth?.authenticated && this.auth.user) { this.userService.authenticated.set(true); this.userService.user.set(this.auth.user); + // Initialize persona from backend (auto-detected from committee membership) + this.personaService.initializeFromAuth(this.auth.persona); + // Identify user with Segment tracking (pass entire Auth0 user object) this.segmentService.identifyUser(this.auth.user); diff --git a/apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html b/apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html index c95c73db..6c6329a2 100644 --- a/apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html +++ b/apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html @@ -4,7 +4,7 @@
@@ -23,7 +23,7 @@

Menu

- +
diff --git a/apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts b/apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts index 8504c26a..90fafdda 100644 --- a/apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts +++ b/apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts @@ -8,6 +8,7 @@ import { NavigationEnd, Router, RouterModule } from '@angular/router'; import { AppService } from '@app/shared/services/app.service'; import { FeatureFlagService } from '@app/shared/services/feature-flag.service'; import { SidebarComponent } from '@components/sidebar/sidebar.component'; +import { environment } from '@environments/environment'; import { COMMITTEE_LABEL } from '@lfx-one/shared/constants'; import { SidebarMenuItem } from '@lfx-one/shared/interfaces'; import { PersonaService } from '@services/persona.service'; @@ -35,6 +36,7 @@ export class MainLayoutComponent { // Feature flags private readonly showProjectsInSidebar = this.featureFlagService.getBooleanFlag('sidebar-projects', false); + private readonly enableProfileClick = this.featureFlagService.getBooleanFlag('sidebar-profile', false); // Base sidebar navigation items - matching React NavigationSidebar design private readonly baseSidebarItems: SidebarMenuItem[] = [ @@ -62,33 +64,48 @@ export class MainLayoutComponent { // Computed sidebar items based on feature flags protected readonly sidebarItems = computed(() => { - const items = [...this.baseSidebarItems]; + let items = [...this.baseSidebarItems]; // Filter out Projects if feature flag is disabled if (!this.showProjectsInSidebar()) { - return items.filter((item) => item.label !== 'Projects'); + items = items.filter((item) => item.label !== 'Projects'); } if (this.personaService.currentPersona() === 'board-member') { - return items.filter((item) => item.label !== COMMITTEE_LABEL.plural); + items = items.filter((item) => item.label !== COMMITTEE_LABEL.plural); } return items; }); // Sidebar footer items - matching React NavigationSidebar design - protected readonly sidebarFooterItems: SidebarMenuItem[] = [ - { - label: 'Settings', - icon: 'fa-light fa-gear', - routerLink: '/settings', - }, + protected readonly sidebarFooterItems = computed(() => [ { label: 'Profile', icon: 'fa-light fa-user', routerLink: '/profile', + disabled: !this.enableProfileClick(), // Disable when feature flag is false }, - ]; + { + label: 'Support', + icon: 'fa-light fa-question-circle', + url: environment.urls.support, + target: '_blank', + rel: 'noopener noreferrer', + }, + { + label: 'Permissions', + icon: 'fa-light fa-shield', + routerLink: '/settings', + }, + { + label: 'Logout', + icon: 'fa-light fa-sign-out', + url: '/logout', + target: '_self', + rel: '', + }, + ]); public constructor() { // Close mobile sidebar on navigation diff --git a/apps/lfx-one/src/app/modules/committees/committee-dashboard/committee-dashboard.component.ts b/apps/lfx-one/src/app/modules/committees/committee-dashboard/committee-dashboard.component.ts index b94c56aa..e73be582 100644 --- a/apps/lfx-one/src/app/modules/committees/committee-dashboard/committee-dashboard.component.ts +++ b/apps/lfx-one/src/app/modules/committees/committee-dashboard/committee-dashboard.component.ts @@ -53,7 +53,6 @@ export class CommitteeDashboardComponent { // Permission signals public isMaintainer: Signal; - public isNonFoundationProjectSelected: Signal; public canCreateGroup: Signal; // Statistics calculations @@ -68,8 +67,7 @@ export class CommitteeDashboardComponent { // Initialize permission checks this.isMaintainer = computed(() => this.personaService.currentPersona() === 'maintainer'); - this.isNonFoundationProjectSelected = computed(() => this.projectContextService.selectedProject() !== null); - this.canCreateGroup = computed(() => this.isMaintainer() && this.isNonFoundationProjectSelected()); + this.canCreateGroup = computed(() => this.isMaintainer()); // Initialize state this.committeesLoading = signal(true); diff --git a/apps/lfx-one/src/app/modules/dashboards/components/organization-involvement/organization-involvement.component.html b/apps/lfx-one/src/app/modules/dashboards/components/organization-involvement/organization-involvement.component.html index 98b5d7a5..53ae7e6b 100644 --- a/apps/lfx-one/src/app/modules/dashboards/components/organization-involvement/organization-involvement.component.html +++ b/apps/lfx-one/src/app/modules/dashboards/components/organization-involvement/organization-involvement.component.html @@ -48,68 +48,68 @@

{{ accountName() }}'s

Loading organization data...

- } @else { -
-
- @for (metric of primaryMetrics(); track metric.title) { - - @if (metric.isMembershipTier) { -
-
-
- -
{{ metric.title }}
-
+ } + +
+
+ @for (metric of primaryMetrics(); track metric.title) { + + @if (metric.isMembershipTier) { +
+
+
+ +
{{ metric.title }}
+
- -
-
- Tier - - {{ metric.tier }} - -
-
- Member Since - {{ metric.tierSince }} -
-
- Renewal Date - {{ metric.nextDue }} -
+ +
+
+ Tier + + {{ metric.tier }} + +
+
+ Member Since + {{ metric.tierSince }} +
+
+ Renewal Date + {{ metric.nextDue }}
- } @else { - -
-
-
- -
{{ metric.title }}
+
+ } @else { + +
+
+
+ +
{{ metric.title }}
+
+ @if (metric.chartData) { +
+
- @if (metric.chartData) { -
- -
+ } +
+
{{ metric.value }}
+ @if (metric.subtitle) { +
{{ metric.subtitle }}
} -
-
{{ metric.value }}
- @if (metric.subtitle) { -
{{ metric.subtitle }}
- } -
- } +
} -
+ }
- } +
diff --git a/apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html b/apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html index c90306ee..6faac12d 100644 --- a/apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html +++ b/apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html @@ -1,6 +1,8 @@ -
- -
+@if (!isAutoDetected()) { +
+ +
+} diff --git a/apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts b/apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts index 75100bf7..5d1b3f4b 100644 --- a/apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts +++ b/apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts @@ -21,6 +21,8 @@ export class PersonaSelectorComponent { private readonly projectContextService = inject(ProjectContextService); // Persona options available for selection protected readonly personaOptions = PERSONA_OPTIONS; + // Whether persona is auto-detected (read-only) + protected readonly isAutoDetected = this.personaService.isAutoDetected; public form: FormGroup; diff --git a/apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html b/apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html index 60d96dc4..5be3433b 100644 --- a/apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html +++ b/apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html @@ -76,8 +76,8 @@ @if (item.url) {