From c5884b1171cf644058e98a5594ec23238715a087 Mon Sep 17 00:00:00 2001 From: Asitha de Silva Date: Thu, 23 Oct 2025 04:16:53 +0800 Subject: [PATCH] feat(ui): comprehensive ui improvements and persona system enhancement Multiple enhancements across the application: - LFXV2-670: Relocate footer to main layout for consistency - LFXV2-671: Replace "old-ui" with "home" persona and simplify routing - LFXV2-672: Add scrollable containers and refactor dashboard charts - LFXV2-673: Add meeting attachments display with file type icons - LFXV2-674: Enhance meeting join with password support and new tab - LFXV2-675: Improve error handling and null safety across services Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Asitha de Silva --- apps/lfx-one/src/app/app.component.html | 3 - apps/lfx-one/src/app/app.component.ts | 3 +- apps/lfx-one/src/app/app.routes.ts | 6 - .../main-layout/main-layout.component.html | 2 + .../main-layout/main-layout.component.ts | 3 +- .../my-meetings/my-meetings.component.html | 2 +- .../my-projects/my-projects.component.html | 56 +------- .../my-projects/my-projects.component.ts | 127 +++++++++++++----- .../pending-actions.component.html | 2 +- .../dashboards/dashboard.component.html | 4 +- .../modules/dashboards/dashboard.component.ts | 12 +- .../modules/pages/home/home.component.html | 2 +- .../components/button/button.component.html | 4 +- .../components/button/button.component.ts | 1 + .../dashboard-meeting-card.component.html | 30 +++-- .../dashboard-meeting-card.component.ts | 30 ++++- .../components/header/header.component.ts | 11 +- .../persona-selector.component.ts | 10 +- .../app/shared/services/analytics.service.ts | 6 +- .../app/shared/services/persona.service.ts | 16 +-- apps/lfx-one/src/server/server.ts | 5 +- .../shared/src/constants/persona.constants.ts | 4 +- .../src/interfaces/components.interface.ts | 8 +- .../src/interfaces/persona.interface.ts | 2 +- 24 files changed, 192 insertions(+), 157 deletions(-) diff --git a/apps/lfx-one/src/app/app.component.html b/apps/lfx-one/src/app/app.component.html index ce32d1bc..080fe9de 100644 --- a/apps/lfx-one/src/app/app.component.html +++ b/apps/lfx-one/src/app/app.component.html @@ -8,6 +8,3 @@
- - - diff --git a/apps/lfx-one/src/app/app.component.ts b/apps/lfx-one/src/app/app.component.ts index 56e9aa64..92da9806 100644 --- a/apps/lfx-one/src/app/app.component.ts +++ b/apps/lfx-one/src/app/app.component.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: MIT import { CommonModule } from '@angular/common'; -import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, makeStateKey, REQUEST_CONTEXT, TransferState } from '@angular/core'; +import { Component, inject, makeStateKey, REQUEST_CONTEXT, TransferState } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import { AuthContext } from '@lfx-one/shared/interfaces'; import { ToastModule } from 'primeng/toast'; @@ -16,7 +16,6 @@ import { UserService } from './shared/services/user.service'; imports: [RouterOutlet, HeaderComponent, CommonModule, ToastModule], templateUrl: './app.component.html', styleUrl: './app.component.scss', - schemas: [CUSTOM_ELEMENTS_SCHEMA], }) export class AppComponent { private readonly userService = inject(UserService); diff --git a/apps/lfx-one/src/app/app.routes.ts b/apps/lfx-one/src/app/app.routes.ts index b4766849..c9df9282 100644 --- a/apps/lfx-one/src/app/app.routes.ts +++ b/apps/lfx-one/src/app/app.routes.ts @@ -21,12 +21,6 @@ export const routes: Routes = [ }, ], }, - // Old UI route - shows when "Old UI" persona is selected - { - path: 'old-ui', - canActivate: [authGuard], - loadComponent: () => import('./modules/pages/home/home.component').then((m) => m.HomeComponent), - }, { path: 'meetings', loadChildren: () => import('./modules/meeting/meeting.routes').then((m) => m.MEETING_ROUTES), 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 d2c3c23e..eb012b6b 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 @@ -32,5 +32,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 a9a77c92..48334a9c 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 @@ -2,7 +2,7 @@ // SPDX-License-Identifier: MIT import { CommonModule } from '@angular/common'; -import { Component, inject } from '@angular/core'; +import { Component, CUSTOM_ELEMENTS_SCHEMA, inject } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { NavigationEnd, Router, RouterModule } from '@angular/router'; import { AppService } from '@app/shared/services/app.service'; @@ -16,6 +16,7 @@ import { filter } from 'rxjs'; imports: [CommonModule, RouterModule, SidebarComponent], templateUrl: './main-layout.component.html', styleUrl: './main-layout.component.scss', + schemas: [CUSTOM_ELEMENTS_SCHEMA], }) export class MainLayoutComponent { private readonly router = inject(Router); diff --git a/apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.html b/apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.html index 02521b3a..d818f00b 100644 --- a/apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.html +++ b/apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.html @@ -17,7 +17,7 @@

My Meetings

-
+
@if (todayMeetings().length > 0 || upcomingMeetings().length > 0) { diff --git a/apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.html b/apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.html index 43de6589..9bd9cc84 100644 --- a/apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.html +++ b/apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.html @@ -57,66 +57,14 @@

My Projects

- - +
- - +
diff --git a/apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.ts b/apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.ts index 45e2fd87..3e5e20c2 100644 --- a/apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.ts +++ b/apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.ts @@ -6,8 +6,17 @@ import { Component } from '@angular/core'; import { ChartComponent } from '@components/chart/chart.component'; import { TableComponent } from '@components/table/table.component'; +import type { ChartData, ChartOptions } from 'chart.js'; import type { ProjectItem } from '@lfx-one/shared/interfaces'; +/** + * Extended project item with pre-generated chart data + */ +interface ProjectItemWithCharts extends ProjectItem { + codeActivitiesChartData: ChartData<'line'>; + nonCodeActivitiesChartData: ChartData<'line'>; +} + @Component({ selector: 'lfx-my-projects', standalone: true, @@ -16,42 +25,96 @@ import type { ProjectItem } from '@lfx-one/shared/interfaces'; styleUrl: './my-projects.component.scss', }) export class MyProjectsComponent { - protected readonly projects: ProjectItem[] = [ - { - name: 'Kubernetes', - logo: 'https://avatars.githubusercontent.com/u/13455738?s=280&v=4', - role: 'Maintainer', - affiliations: ['CNCF', 'Google'], - codeActivities: [28, 32, 30, 35, 38, 40, 42], - nonCodeActivities: [8, 10, 12, 11, 13, 14, 15], - status: 'active', - }, - { - name: 'Linux Kernel', - logo: 'https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg', - role: 'Contributor', - affiliations: ['Linux Foundation'], - codeActivities: [15, 18, 20, 22, 24, 26, 28], - nonCodeActivities: [3, 4, 5, 6, 7, 7, 8], - status: 'active', - }, - { - name: 'Node.js', - logo: 'https://nodejs.org/static/logos/nodejsHex.svg', - role: 'Reviewer', - affiliations: ['OpenJS Foundation'], - codeActivities: [18, 16, 15, 14, 13, 12, 12], - nonCodeActivities: [8, 7, 6, 6, 5, 5, 5], - status: 'archived', + /** + * Chart options for activity charts + */ + protected readonly chartOptions: ChartOptions<'line'> = { + responsive: true, + maintainAspectRatio: false, + plugins: { legend: { display: false }, tooltip: { enabled: false } }, + scales: { + x: { display: false }, + y: { display: false }, }, - ]; + }; + + /** + * Projects with pre-generated chart data + */ + protected readonly projects: ProjectItemWithCharts[]; + + public constructor() { + // Initialize projects with randomized chart data + const baseProjects: ProjectItem[] = [ + { + name: 'Kubernetes', + logo: 'https://avatars.githubusercontent.com/u/13455738?s=280&v=4', + role: 'Maintainer', + affiliations: ['CNCF', 'Google'], + codeActivities: this.generateRandomData(7, 25, 45), + nonCodeActivities: this.generateRandomData(7, 8, 16), + status: 'active', + }, + { + name: 'Linux Kernel', + logo: 'https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg', + role: 'Contributor', + affiliations: ['Linux Foundation'], + codeActivities: this.generateRandomData(7, 12, 30), + nonCodeActivities: this.generateRandomData(7, 3, 9), + status: 'active', + }, + { + name: 'Node.js', + logo: 'https://nodejs.org/static/logos/nodejsHex.svg', + role: 'Reviewer', + affiliations: ['OpenJS Foundation'], + codeActivities: this.generateRandomData(7, 10, 20), + nonCodeActivities: this.generateRandomData(7, 4, 10), + status: 'archived', + }, + ]; + + // Generate chart data for each project + this.projects = baseProjects.map((project) => ({ + ...project, + codeActivitiesChartData: this.createChartData(project.codeActivities, '#009AFF', 'rgba(0, 154, 255, 0.1)'), + nonCodeActivitiesChartData: this.createChartData(project.nonCodeActivities, '#10b981', 'rgba(16, 185, 129, 0.1)'), + })); + } /** - * Generates labels for chart based on data length + * Generates random data array * @param length - Number of data points - * @returns Array of empty strings for chart labels + * @param min - Minimum value + * @param max - Maximum value + * @returns Array of random numbers + */ + private generateRandomData(length: number, min: number, max: number): number[] { + return Array.from({ length }, () => Math.floor(Math.random() * (max - min + 1)) + min); + } + + /** + * Creates chart data configuration + * @param data - Array of values + * @param borderColor - Chart border color + * @param backgroundColor - Chart background color + * @returns Chart.js data configuration */ - protected generateLabels(length: number): string[] { - return Array.from({ length }, () => ''); + private createChartData(data: number[], borderColor: string, backgroundColor: string): ChartData<'line'> { + return { + labels: Array.from({ length: data.length }, () => ''), + datasets: [ + { + data, + borderColor, + backgroundColor, + fill: true, + tension: 0.4, + borderWidth: 2, + pointRadius: 0, + }, + ], + }; } } diff --git a/apps/lfx-one/src/app/modules/dashboards/components/pending-actions/pending-actions.component.html b/apps/lfx-one/src/app/modules/dashboards/components/pending-actions/pending-actions.component.html index aba816ff..06f2a762 100644 --- a/apps/lfx-one/src/app/modules/dashboards/components/pending-actions/pending-actions.component.html +++ b/apps/lfx-one/src/app/modules/dashboards/components/pending-actions/pending-actions.component.html @@ -17,7 +17,7 @@

Pending Actions

-
+
@for (item of pendingActions(); track item.text) {
} - @default { - + @case ('projects') { + } } diff --git a/apps/lfx-one/src/app/modules/dashboards/dashboard.component.ts b/apps/lfx-one/src/app/modules/dashboards/dashboard.component.ts index 4dc160b3..aba03c5a 100644 --- a/apps/lfx-one/src/app/modules/dashboards/dashboard.component.ts +++ b/apps/lfx-one/src/app/modules/dashboards/dashboard.component.ts @@ -1,8 +1,11 @@ // Copyright The Linux Foundation and each contributor to LFX. // SPDX-License-Identifier: MIT -import { Component, computed, inject } from '@angular/core'; +import { Component, computed, inject, Signal } from '@angular/core'; import { PersonaService } from '@app/shared/services/persona.service'; +import { PersonaType } from '@lfx-one/shared/interfaces'; + +import { HomeComponent } from '../pages/home/home.component'; import { CoreDeveloperDashboardComponent } from './core-developer/core-developer-dashboard.component'; import { MaintainerDashboardComponent } from './maintainer/maintainer-dashboard.component'; @@ -13,7 +16,7 @@ import { MaintainerDashboardComponent } from './maintainer/maintainer-dashboard. @Component({ selector: 'lfx-dashboard', standalone: true, - imports: [CoreDeveloperDashboardComponent, MaintainerDashboardComponent], + imports: [CoreDeveloperDashboardComponent, MaintainerDashboardComponent, HomeComponent], templateUrl: './dashboard.component.html', }) export class DashboardComponent { @@ -23,9 +26,8 @@ export class DashboardComponent { * Computed signal that determines which dashboard to display * based on the current persona selection */ - protected readonly dashboardType = computed(() => { + protected readonly dashboardType: Signal = computed(() => { const persona = this.personaService.currentPersona(); - // Filter out 'old-ui' as it has its own route - return persona === 'old-ui' ? 'core-developer' : persona; + return persona; }); } diff --git a/apps/lfx-one/src/app/modules/pages/home/home.component.html b/apps/lfx-one/src/app/modules/pages/home/home.component.html index 109858a1..6353e570 100644 --- a/apps/lfx-one/src/app/modules/pages/home/home.component.html +++ b/apps/lfx-one/src/app/modules/pages/home/home.component.html @@ -1,7 +1,7 @@ -
+

Your personalized control panel for managing projects, committees, and meetings. diff --git a/apps/lfx-one/src/app/shared/components/button/button.component.html b/apps/lfx-one/src/app/shared/components/button/button.component.html index f9865a10..0985ea50 100644 --- a/apps/lfx-one/src/app/shared/components/button/button.component.html +++ b/apps/lfx-one/src/app/shared/components/button/button.component.html @@ -54,7 +54,9 @@ [pTooltip]="tooltip()" [tooltipPosition]="tooltipPosition()" (onClick)="handleClick($event)" - [routerLink]="routerLink()"> + [routerLink]="routerLink()" + [queryParams]="queryParams()" + [target]="target()"> } diff --git a/apps/lfx-one/src/app/shared/components/button/button.component.ts b/apps/lfx-one/src/app/shared/components/button/button.component.ts index 7d5e81ea..4c4fe249 100644 --- a/apps/lfx-one/src/app/shared/components/button/button.component.ts +++ b/apps/lfx-one/src/app/shared/components/button/button.component.ts @@ -55,6 +55,7 @@ export class ButtonComponent { public readonly href = input(undefined); public readonly target = input(undefined); public readonly rel = input(undefined); + public readonly queryParams = input>({}); // Events public readonly onClick = output(); diff --git a/apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.html b/apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.html index 80c548e2..319d2905 100644 --- a/apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.html +++ b/apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.html @@ -70,18 +70,22 @@

{{ meetingTitle() }}

-
-
- + @if (attachments().length > 0) { +
+ @for (attachment of attachments(); track attachment.id; let index = $index) { + + + + }
-
- -
-
+ }
@@ -106,6 +110,10 @@

} diff --git a/apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts b/apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts index 689daea7..02568747 100644 --- a/apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts +++ b/apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts @@ -1,11 +1,16 @@ // Copyright The Linux Foundation and each contributor to LFX. // SPDX-License-Identifier: MIT +import { ClipboardModule } from '@angular/cdk/clipboard'; import { CommonModule } from '@angular/common'; -import { Component, computed, input, output, Signal } from '@angular/core'; +import { Component, computed, inject, input, output, Signal } from '@angular/core'; +import { toObservable, toSignal } from '@angular/core/rxjs-interop'; +import { FileTypeIconPipe } from '@app/shared/pipes/file-type-icon.pipe'; import { ButtonComponent } from '@components/button/button.component'; -import { Meeting, MeetingOccurrence } from '@lfx-one/shared'; +import { Meeting, MeetingAttachment, MeetingOccurrence } from '@lfx-one/shared'; +import { MeetingService } from '@services/meeting.service'; import { TooltipModule } from 'primeng/tooltip'; +import { catchError, of, switchMap } from 'rxjs'; interface MeetingTypeBadge { label: string; @@ -15,14 +20,18 @@ interface MeetingTypeBadge { @Component({ selector: 'lfx-dashboard-meeting-card', standalone: true, - imports: [CommonModule, ButtonComponent, TooltipModule], + imports: [CommonModule, ButtonComponent, TooltipModule, ClipboardModule, FileTypeIconPipe], templateUrl: './dashboard-meeting-card.component.html', }) export class DashboardMeetingCardComponent { + private readonly meetingService = inject(MeetingService); + public readonly meeting = input.required(); public readonly occurrence = input(null); public readonly onSeeMeeting = output(); + public readonly attachments: Signal; + // Computed values public readonly meetingTypeInfo: Signal = computed(() => { const type = this.meeting().meeting_type?.toLowerCase(); @@ -136,6 +145,21 @@ export class DashboardMeetingCardComponent { return occurrence?.title || meeting.title; }); + public constructor() { + // Convert meeting input signal to observable and create reactive attachment stream + const meeting$ = toObservable(this.meeting); + const attachments$ = meeting$.pipe( + switchMap((meeting) => { + if (meeting.uid) { + return this.meetingService.getMeetingAttachments(meeting.uid).pipe(catchError(() => of([]))); + } + return of([]); + }) + ); + + this.attachments = toSignal(attachments$, { initialValue: [] }); + } + public handleSeeMeeting(): void { this.onSeeMeeting.emit(this.meeting().uid); } diff --git a/apps/lfx-one/src/app/shared/components/header/header.component.ts b/apps/lfx-one/src/app/shared/components/header/header.component.ts index af5f2426..d5d1485e 100644 --- a/apps/lfx-one/src/app/shared/components/header/header.component.ts +++ b/apps/lfx-one/src/app/shared/components/header/header.component.ts @@ -6,10 +6,10 @@ import { Component, computed, CUSTOM_ELEMENTS_SCHEMA, ElementRef, inject, Signal import { toSignal } from '@angular/core/rxjs-interop'; import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { Router, RouterModule } from '@angular/router'; +import { AppService } from '@app/shared/services/app.service'; import { AvatarComponent } from '@components/avatar/avatar.component'; import { MenubarComponent } from '@components/menubar/menubar.component'; import { PersonaSelectorComponent } from '@components/persona-selector/persona-selector.component'; -import { AppService } from '@app/shared/services/app.service'; import { CombinedProfile, Project } from '@lfx-one/shared/interfaces'; import { ProjectService } from '@services/project.service'; import { UserService } from '@services/user.service'; @@ -161,6 +161,13 @@ export class HeaderComponent { } private initializeUserProfile(): Signal { - return toSignal(this.userService.getCurrentUserProfile(), { initialValue: null }); + return toSignal( + this.userService.getCurrentUserProfile().pipe( + catchError(() => { + return of(null); + }) + ), + { initialValue: null } + ); } } 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 24c9145f..e41a732a 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 @@ -1,7 +1,7 @@ // Copyright The Linux Foundation and each contributor to LFX. // SPDX-License-Identifier: MIT -import { Component, effect, inject } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { PERSONA_OPTIONS } from '@lfx-one/shared/constants'; @@ -25,13 +25,7 @@ export class PersonaSelectorComponent { public constructor() { this.form = new FormGroup({ - persona: new FormControl('core-developer', [Validators.required]), - }); - - effect(() => { - if (this.form.get('persona')?.value !== this.personaService.currentPersona()) { - this.form.get('persona')?.setValue(this.personaService.currentPersona()); - } + persona: new FormControl(this.personaService.currentPersona(), [Validators.required]), }); this.form diff --git a/apps/lfx-one/src/app/shared/services/analytics.service.ts b/apps/lfx-one/src/app/shared/services/analytics.service.ts index 5cb8d23e..6d4dd54a 100644 --- a/apps/lfx-one/src/app/shared/services/analytics.service.ts +++ b/apps/lfx-one/src/app/shared/services/analytics.service.ts @@ -82,6 +82,10 @@ export class AnalyticsService { * @param auth0User Auth0 user object */ public identifyUser(auth0User: unknown): void { + if (!auth0User) { + return; + } + // If analytics is not ready yet, queue the identify call if (!this.analyticsReady || !this.analytics) { this.identifyQueue.push({ user: auth0User }); @@ -132,7 +136,7 @@ export class AnalyticsService { let attempts = 0; while (attempts < maxAttempts) { - if (window.LfxAnalytics?.LfxSegmentsAnalytics) { + if (window?.LfxAnalytics?.LfxSegmentsAnalytics) { this.analytics = window.LfxAnalytics.LfxSegmentsAnalytics.getInstance(); try { diff --git a/apps/lfx-one/src/app/shared/services/persona.service.ts b/apps/lfx-one/src/app/shared/services/persona.service.ts index 9279c9b2..6aa5133e 100644 --- a/apps/lfx-one/src/app/shared/services/persona.service.ts +++ b/apps/lfx-one/src/app/shared/services/persona.service.ts @@ -1,7 +1,7 @@ // Copyright The Linux Foundation and each contributor to LFX. // SPDX-License-Identifier: MIT -import { afterNextRender, inject, Injectable, signal, WritableSignal } from '@angular/core'; +import { inject, Injectable, signal, WritableSignal } from '@angular/core'; import { Router } from '@angular/router'; import { PersonaType } from '@lfx-one/shared/interfaces'; @@ -17,14 +17,6 @@ export class PersonaService { public constructor() { // Initialize with default value this.currentPersona = signal('core-developer'); - - // Load from localStorage after render (browser only) - afterNextRender(() => { - const stored = localStorage.getItem(this.storageKey) as PersonaType; - if (stored) { - this.currentPersona.set(stored); - } - }); } /** @@ -35,11 +27,7 @@ export class PersonaService { this.currentPersona.set(persona); this.persistPersona(persona); - if (persona === 'old-ui') { - this.router.navigate(['/old-ui']); - } else { - this.router.navigate(['/']); - } + this.router.navigate(['/']); } } diff --git a/apps/lfx-one/src/server/server.ts b/apps/lfx-one/src/server/server.ts index 256776fa..e73f3cf2 100644 --- a/apps/lfx-one/src/server/server.ts +++ b/apps/lfx-one/src/server/server.ts @@ -237,8 +237,9 @@ app.use('/**', async (req: Request, res: Response, next: NextFunction) => { }, 'Failed to fetch user info, using basic user data' ); - // Fall back to basic user info from token - auth.user = req.oidc?.user as User; + + res.oidc.logout(); + return; } } diff --git a/packages/shared/src/constants/persona.constants.ts b/packages/shared/src/constants/persona.constants.ts index b5a31cc8..709eaaa2 100644 --- a/packages/shared/src/constants/persona.constants.ts +++ b/packages/shared/src/constants/persona.constants.ts @@ -18,8 +18,8 @@ export const PERSONA_OPTIONS: PersonaOption[] = [ description: 'Project maintainer focused experience', }, { - value: 'old-ui', - label: 'Old UI', + value: 'projects', + label: 'Projects', description: 'Classic LFX interface', }, ]; diff --git a/packages/shared/src/interfaces/components.interface.ts b/packages/shared/src/interfaces/components.interface.ts index 4de53aff..b53adb32 100644 --- a/packages/shared/src/interfaces/components.interface.ts +++ b/packages/shared/src/interfaces/components.interface.ts @@ -1,7 +1,7 @@ // Copyright The Linux Foundation and each contributor to LFX. // SPDX-License-Identifier: MIT -import { ChartData, ChartOptions } from 'chart.js'; +import { ChartData, ChartOptions, ChartType } from 'chart.js'; /** * Badge severity level options @@ -320,11 +320,11 @@ export interface ProgressItem { */ export interface ProgressItemWithChart extends ProgressItem { /** Chart type - line or bar */ - chartType: 'line' | 'bar'; + chartType: ChartType; /** Chart.js data configuration - supports line and bar charts */ - chartData: ChartData<'line' | 'bar'>; + chartData: ChartData; /** Chart.js options configuration - supports line and bar charts */ - chartOptions: ChartOptions<'line' | 'bar'>; + chartOptions: ChartOptions; /** Optional subtitle text displayed below the value */ subtitle?: string; } diff --git a/packages/shared/src/interfaces/persona.interface.ts b/packages/shared/src/interfaces/persona.interface.ts index 33d5c389..9641d041 100644 --- a/packages/shared/src/interfaces/persona.interface.ts +++ b/packages/shared/src/interfaces/persona.interface.ts @@ -5,7 +5,7 @@ * Available persona types for UI customization * @description Defines the different user personas that can be selected */ -export type PersonaType = 'core-developer' | 'maintainer' | 'old-ui'; +export type PersonaType = 'core-developer' | 'maintainer' | 'projects'; /** * Persona option configuration