Skip to content

Conversation

@jordane
Copy link
Contributor

@jordane jordane commented Oct 9, 2025

Work in progress implementation for LFXV2-644. Adding foundational components and structure for the Core Developer Persona dashboard.

🤖 Generated with Claude Code

Work in progress implementation for LFXV2-644. Adding foundational
components and structure for the Core Developer Persona dashboard.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>
@Copilot Copilot AI review requested due to automatic review settings October 9, 2025 18:16
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conventional Commits FTW!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements the foundational structure for a Core Developer Persona dashboard as part of LFXV2-644. It introduces a persona-based UI switching system that allows users to toggle between a new "Core Developer" dashboard and the existing "Old UI" interface.

Key changes include:

  • Persona management service with localStorage persistence
  • New dashboard layout with sidebar navigation and metrics widgets
  • Route guards for persona-based access control

Reviewed Changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/shared/src/interfaces/persona.interface.ts Defines persona types and configuration interfaces
packages/shared/src/interfaces/components.interface.ts Adds component interfaces for sidebar, progress items, and dashboard widgets
apps/lfx-one/src/app/shared/services/persona.service.ts Core service for persona management and localStorage persistence
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.* Reusable sidebar navigation component
apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.* Dropdown component for persona switching
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.* New dashboard implementation with metrics and project widgets
apps/lfx-one/src/app/layouts/main-layout/main-layout.component.* Layout wrapper that includes sidebar navigation
apps/lfx-one/src/app/app.routes.ts Route configuration with persona-based guards

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@coderabbitai
Copy link

coderabbitai bot commented Oct 9, 2025

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Root route now renders a MainLayout with child routes (dashboard, projects) and adds a guarded old-ui route. Introduces MainLayout, Sidebar, PersonaSelector, PersonaService/constants, AppService for mobile sidebar, multiple dashboard widgets and meeting/project components, and renames user metadata job_titletitle across frontend and server.

Changes

Cohort / File(s) Summary
Routing & Main Layout
apps/lfx-one/src/app/app.routes.ts, apps/lfx-one/src/app/layouts/main-layout/*
Root route switched to MainLayoutComponent via loadComponent with children (''→Dashboard, projects→Home). New guarded old-ui route. Added MainLayout component, template, styles and mobile-overlay/sidebar wiring.
Sidebar component & interfaces
apps/lfx-one/src/app/shared/components/sidebar/*, packages/shared/src/interfaces/components.interface.ts
Added standalone SidebarComponent (main/footer nav, routerLink/url/command handling, testId enrichment). New dashboard/sidebar-related interfaces (SidebarMenuItem, SidebarProps, ProgressItem*, ProjectItem, etc.).
Header & Persona selector
apps/lfx-one/src/app/shared/components/header/*, apps/lfx-one/src/app/shared/components/persona-selector/*
Header template changed (mobile toggle, compact logo, auth block); added PersonaSelectorComponent (FormGroup, persona sync). Header now exposes userProfile/initials/fullName signals and delegates mobile toggle to AppService.
Persona service, constants & types
apps/lfx-one/src/app/shared/services/persona.service.ts, packages/shared/src/constants/persona.constants.ts, packages/shared/src/interfaces/persona.interface.ts, packages/shared/src/constants/index.ts, packages/shared/src/interfaces/index.ts
New PersonaService with currentPersona signal, localStorage persistence and route navigation. Added PERSONA_OPTIONS, PersonaType/PersonaOption and re-exports in shared indexes.
App UI state service
apps/lfx-one/src/app/shared/services/app.service.ts
New AppService managing mobile sidebar visibility via signals with toggleMobileSidebar, openMobileSidebar, closeMobileSidebar.
Dashboard & widgets
apps/lfx-one/src/app/modules/pages/dashboard/*
New DashboardComponent and widgets: RecentProgressComponent, PendingActionsComponent (emits actions), MyMeetingsComponent (loads/filters meetings, navigation), MyProjectsComponent (sample projects/charts). Templates, SCSS and testids added.
Meeting card component
apps/lfx-one/src/app/shared/components/dashboard-meeting-card/*
New DashboardMeetingCardComponent with inputs (meeting, occurrence), output (onSeeMeeting), computed signals for badge/flags/formatted time/title, and join/see actions.
Meeting enrichment & interfaces
apps/lfx-one/src/server/services/meeting.service.ts, packages/shared/src/interfaces/meeting.interface.ts
Meeting service enriched to resolve project_name via ProjectService; Meeting interface gains project_name: string.
Profile edit & server changes
apps/lfx-one/src/app/modules/profile/edit/*, apps/lfx-one/src/app/layouts/profile-layout/*, apps/lfx-one/src/server/controllers/profile.controller.ts, apps/lfx-one/src/server/services/user.service.ts, packages/shared/src/interfaces/user-profile.interface.ts
Renamed frontend form control and payload field job_titletitle; profile-layout uses profile.title; server controller and validation updated to use metadata?.title; shared interface updated.
UI templates & styles
apps/lfx-one/src/app/shared/components/*/*.html, *.scss, apps/lfx-one/src/app/modules/pages/dashboard/*.{html,scss}
New/updated templates and SCSS for header, sidebar, persona selector, dashboard widgets and layout (structure, testids, helpers like hide-scrollbar and :host rules).
Shared package & deps
packages/shared/package.json
Added peerDependency chart.js ^4.5.0 to support chart components.
Quality workflow
.github/workflows/quality-check.yml
Workflow trigger changed to manual workflow_dispatch and minor quoting/formatting tweaks.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User
    participant Header
    participant PersonaSelector
    participant PersonaService
    participant Router
    participant MainLayout
    participant AppService
    participant Sidebar

    User->>Header: open persona selector
    Header->>PersonaSelector: show options
    PersonaSelector->>PersonaService: setPersona(selected)
    Note right of PersonaService #DDEBF7: update signal & persist to localStorage
    PersonaService->>Router: navigate to "/" or "/old-ui"
    Router->>MainLayout: load (if route uses layout)
    MainLayout->>AppService: subscribe showMobileSidebar
    User->>Header: toggle mobile menu
    Header->>AppService: toggleMobileSidebar()
    AppService->>MainLayout: update overlay visibility
    MainLayout->>Sidebar: render items (reactive)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning Consider either removing the job_title → title renaming changes from this PR and submitting them as a separate focused PR, or updating the PR description to explicitly explain why these backend and profile interface changes are necessary for the dashboard implementation. This will clarify whether the changes are intentional refactoring work or inadvertently bundled changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The title "feat(dashboard): initial core persona developer dashboard implementation" is clear, specific, and directly relates to the primary changes in the pull request. It uses conventional commit format (feat scope) and accurately summarizes the main objective of adding foundational dashboard components for the Core Developer persona. The title is concise, avoids vague language, and provides sufficient context for understanding the changeset at a glance.
Linked Issues Check ✅ Passed The PR implements the primary objectives from LFXV2-644 by establishing the foundational dashboard structure and components for the Core Developer persona. Changes include the DashboardComponent with subcomponents (MyMeetingsComponent, MyProjectsComponent, PendingActionsComponent, RecentProgressComponent) featuring placeholder content, routing structure with main layout, persona selection functionality via PersonaSelectorComponent and PersonaService, and supporting infrastructure (AppService, MainLayoutComponent, SidebarComponent). These changes directly satisfy the requirement to build out the Core Developer Persona dashboard with foundational components.
Description Check ✅ Passed The description is clearly related to the changeset and provides meaningful context by referencing the linked issue (LFXV2-644) and describing the work as adding foundational components and structure for the Core Developer Persona dashboard. While brief, it conveys the purpose of the changes without using vague or generic terms. The description appropriately notes the WIP status and tool used for generation.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 29db102 and 8f7b0b4.

📒 Files selected for processing (1)
  • .github/workflows/quality-check.yml (3 hunks)

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Oct 9, 2025

🚀 Deployment Status

Your branch has been deployed to: https://ui-pr-119.dev.v2.cluster.linuxfound.info

Deployment Details:

  • Environment: Development
  • Namespace: ui-pr-119
  • ArgoCD App: ui-pr-119

The deployment will be automatically removed when this PR is closed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

♻️ Duplicate comments (2)
apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html (1)

8-8: Address the type safety concern with $any() cast.

The use of $any($event.target) bypasses TypeScript's type checking. As noted in previous reviews, this should be replaced with proper typing for better type safety and maintainability.

Consider updating the event handler signature to accept the native event type:

-    (change)="onPersonaChange({ value: $any($event.target).value })"
+    (change)="onPersonaChange($event)"

Then update the component method to extract the value with proper typing:

onPersonaChange(event: Event): void {
  const selectElement = event.target as HTMLSelectElement;
  // ... rest of implementation
}
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (1)

10-13: Using 'any' type defeats TypeScript's type safety.

This concern was previously raised in past review comments. Consider defining proper interfaces for chartData and chartOptions or using more specific types from your charting library.

🧹 Nitpick comments (3)
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html (1)

217-237: Consider moving inline chart configurations to the component.

The inline chart data and options objects (lines 217-237 for Code Activities, 249-269 for Non-Code Activities) duplicate the structure from the component's progressItems. This makes the template harder to maintain and violates separation of concerns.

Consider moving these configurations to the component TypeScript file as properties on each ProjectItem, similar to how progressItems includes chartData and chartOptions. This would:

  • Keep the template focused on presentation
  • Make chart configurations reusable and easier to test
  • Align with the pattern already established for progressItems

Also applies to: 249-269

apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts (1)

21-32: LGTM with optional refactor suggestion.

The hardcoded persona options work well for the current implementation. The component logic is clean and follows Angular best practices with the inject pattern and computed signals.

For future maintainability, consider moving the persona options to the PersonaService or a separate configuration file. This would centralize persona definitions and make them easier to extend:

// In persona.service.ts
public readonly personaOptions: PersonaOption[] = [
  {
    value: 'core-developer',
    label: 'Core Developer Persona',
    description: 'New streamlined developer experience',
  },
  {
    value: 'old-ui',
    label: 'Old UI',
    description: 'Classic LFX interface',
  },
];

// In persona-selector.component.ts
protected readonly personaOptions = this.personaService.personaOptions;
apps/lfx-one/src/app/shared/services/persona.service.ts (1)

31-40: Consider using computed signals for boolean checks.

The isNewUI() and isOldUI() methods re-evaluate on every call. For better performance and reactivity, consider using computed signals.

public readonly isNewUI = computed(() => this.currentPersona() === 'core-developer');
public readonly isOldUI = computed(() => this.currentPersona() === 'old-ui');

This change would:

  • Memoize the results automatically
  • Integrate better with Angular's change detection
  • Align with the computed pattern already used in PersonaSelectorComponent
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 526162b and 5a7a1fe.

📒 Files selected for processing (18)
  • apps/lfx-one/src/app/app.routes.ts (1 hunks)
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html (1 hunks)
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.scss (1 hunks)
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.scss (1 hunks)
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/components/header/header.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/header/header.component.ts (2 hunks)
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.scss (1 hunks)
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/services/persona.service.ts (1 hunks)
  • packages/shared/src/interfaces/components.interface.ts (1 hunks)
  • packages/shared/src/interfaces/index.ts (1 hunks)
  • packages/shared/src/interfaces/persona.interface.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
  • packages/shared/src/interfaces/persona.interface.ts
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts
  • packages/shared/src/interfaces/index.ts
  • apps/lfx-one/src/app/shared/components/header/header.component.ts
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts
  • packages/shared/src/interfaces/components.interface.ts
  • apps/lfx-one/src/app/shared/services/persona.service.ts
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
  • apps/lfx-one/src/app/app.routes.ts
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.scss
  • packages/shared/src/interfaces/persona.interface.ts
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.scss
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts
  • packages/shared/src/interfaces/index.ts
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html
  • apps/lfx-one/src/app/shared/components/header/header.component.ts
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.scss
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html
  • packages/shared/src/interfaces/components.interface.ts
  • apps/lfx-one/src/app/shared/components/header/header.component.html
  • apps/lfx-one/src/app/shared/services/persona.service.ts
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
  • apps/lfx-one/src/app/app.routes.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
  • packages/shared/src/interfaces/persona.interface.ts
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts
  • packages/shared/src/interfaces/index.ts
  • apps/lfx-one/src/app/shared/components/header/header.component.ts
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts
  • packages/shared/src/interfaces/components.interface.ts
  • apps/lfx-one/src/app/shared/services/persona.service.ts
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
  • apps/lfx-one/src/app/app.routes.ts
apps/lfx-one/src/**/*.html

📄 CodeRabbit inference engine (CLAUDE.md)

apps/lfx-one/src/**/*.html: Always add data-testid attributes when creating new Angular components for reliable test targeting
Use data-testid naming convention [section]-[component]-[element]

Files:

  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html
  • apps/lfx-one/src/app/shared/components/header/header.component.html
packages/shared/src/interfaces/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place all TypeScript interfaces in the shared package at packages/shared/src/interfaces

Files:

  • packages/shared/src/interfaces/persona.interface.ts
  • packages/shared/src/interfaces/index.ts
  • packages/shared/src/interfaces/components.interface.ts
**/index.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Do not use barrel exports; always use direct imports for standalone components

Files:

  • packages/shared/src/interfaces/index.ts
🧬 Code graph analysis (5)
apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (2)
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1)
  • Component (10-29)
packages/shared/src/interfaces/components.interface.ts (1)
  • SidebarMenuItem (265-284)
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (1)
packages/shared/src/interfaces/components.interface.ts (4)
  • ProgressItem (303-310)
  • PendingActionItem (316-329)
  • MeetingItem (335-342)
  • ProjectItem (348-363)
apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts (2)
apps/lfx-one/src/app/shared/components/header/header.component.ts (1)
  • Component (23-152)
packages/shared/src/interfaces/persona.interface.ts (2)
  • PersonaOption (14-23)
  • PersonaType (8-8)
apps/lfx-one/src/app/shared/services/persona.service.ts (1)
packages/shared/src/interfaces/persona.interface.ts (1)
  • PersonaType (8-8)
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (2)
apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (1)
  • Component (10-50)
packages/shared/src/interfaces/components.interface.ts (1)
  • SidebarMenuItem (265-284)
🪛 GitHub Actions: Quality Checks
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html

[warning] 1-1: Prettier formatting issues found in this file. Run 'yarn format:write' to fix.

apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html

[warning] 1-1: Prettier formatting issues found in this file. Run 'yarn format:write' to fix.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-push
🔇 Additional comments (1)
packages/shared/src/interfaces/persona.interface.ts (1)

8-8: Verify if literal union types are acceptable per coding guidelines.

The coding guideline states "Use TypeScript interfaces instead of union types for better maintainability." However, PersonaType is a string literal union, which is a common and idiomatic TypeScript pattern for representing a fixed set of string values.

Please confirm whether the guideline applies to literal unions like this, or if it's specifically targeting complex object unions. If literal unions are discouraged, consider using an enum or const object instead.

As per coding guidelines.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (3)

10-13: Replace any types with proper Chart.js types.

The use of any for chartData and chartOptions defeats TypeScript's type safety. Import the appropriate types from Chart.js.

Apply this diff to use proper types:

+import type { ChartData, ChartOptions } from 'chart.js';
+
-interface ProgressItemWithChart extends ProgressItem {
-  chartData: any;
-  chartOptions: any;
-}
+interface ProgressItemWithChart extends ProgressItem {
+  chartData: ChartData<'line'>;
+  chartOptions: ChartOptions<'line'>;
+}

26-195: Extract duplicate chartOptions to a shared constant.

The chartOptions object is duplicated across all six progress items (lines 45-53, 73-81, 101-109, 129-137, 157-165, 185-193), violating DRY principles.

Extract the common configuration:

+  private readonly commonChartOptions = {
+    responsive: true,
+    maintainAspectRatio: false,
+    plugins: { legend: { display: false }, tooltip: { enabled: false } },
+    scales: {
+      x: { display: false },
+      y: { display: false },
+    },
+  };
+
   protected readonly progressItems: ProgressItemWithChart[] = [
     {
       label: 'Pull requests merged',
       value: '12',
       trend: 'up',
       chartData: { /* ... */ },
-      chartOptions: {
-        responsive: true,
-        maintainAspectRatio: false,
-        plugins: { legend: { display: false }, tooltip: { enabled: false } },
-        scales: {
-          x: { display: false },
-          y: { display: false },
-        },
-      },
+      chartOptions: this.commonChartOptions,
     },
     // Apply to remaining items...

236-236: Fix broken Kubernetes logo URL.

The CNCF Kubernetes icon URL returns HTTP 404. Either update to a working URL or host the asset locally.

Replace the broken URL:

-      logo: 'https://www.cncf.io/wp-content/uploads/2023/04/kubernetes-icon-color.svg',
+      logo: 'https://kubernetes.io/images/kubernetes-horizontal-color.svg',

Or add the SVG to your assets folder and reference it locally for better reliability.

apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html (1)

1-296: Fix Prettier formatting issues.

The pipeline detected formatting issues. Run yarn format:write to fix before merging.

#!/bin/bash
yarn format:write apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html
🧹 Nitpick comments (2)
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html (2)

76-138: Consider extracting color class mapping to reduce duplication.

The same ngClass pattern for color-based styling is repeated four times within the Pending Actions section (lines 78-83, 88-93, 98-103, 116-121, 130-135).

You could optionally extract a helper method in the component to return the appropriate classes:

// In home-new.component.ts
protected getColorClasses(color: string, prefix: string): string {
  const colorMap = {
    amber: `${prefix}-amber`,
    blue: `${prefix}-blue`,
    green: `${prefix}-green`,
    purple: `${prefix}-purple`
  };
  return colorMap[color as keyof typeof colorMap] || '';
}

Then use it in the template:

<div [ngClass]="'bg-' + item.color + '-50 border-' + item.color + '-200'">

However, this is a minor optimization and can be deferred.


230-286: Avoid duplicating chart configuration in template.

The inline chart data and options in the template (lines 232-254 and 264-286) duplicate the chart configuration logic from the TypeScript component. This creates maintenance overhead.

Move the chart configurations to the component's projects array:

In home-new.component.ts, extend ProjectItem interface (or create a local extended interface) to include pre-configured chart objects:

interface ProjectItemWithCharts extends ProjectItem {
  codeChartData: ChartData<'line'>;
  codeChartOptions: ChartOptions<'line'>;
  nonCodeChartData: ChartData<'line'>;
  nonCodeChartOptions: ChartOptions<'line'>;
}

Then bind to these properties in the template:

<lfx-chart
  type="line"
  [data]="item.codeChartData"
  [options]="item.codeChartOptions"
  height="100%">
</lfx-chart>

This keeps the template clean and centralizes configuration.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5a7a1fe and 6075509.

📒 Files selected for processing (2)
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts
apps/lfx-one/src/**/*.html

📄 CodeRabbit inference engine (CLAUDE.md)

apps/lfx-one/src/**/*.html: Always add data-testid attributes when creating new Angular components for reliable test targeting
Use data-testid naming convention [section]-[component]-[element]

Files:

  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html
🧬 Code graph analysis (1)
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (1)
packages/shared/src/interfaces/components.interface.ts (4)
  • ProgressItem (303-310)
  • PendingActionItem (316-329)
  • MeetingItem (335-342)
  • ProjectItem (348-363)
🪛 GitHub Actions: Quality Checks
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html

[warning] 1-1: Prettier formatting issues detected in this file. Run 'yarn format:write' to fix.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-push

Reduce section header sizes from text-xl to text-lg for better visual hierarchy.
Enhance meetings section with modern card design, calendar icons, participant
badges, and Join buttons. Fix ESLint member ordering issues for LFXV2-644.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>
jordane and others added 3 commits October 10, 2025 12:16
Change sidebar from fixed to sticky positioning within a flex container.
This ensures the sidebar stays in its designated column and doesn't cover
content during horizontal scrolling. Updates for LFXV2-644.

- Wrap sidebar in flex-shrink-0 container with fixed width
- Change sidebar positioning from fixed to sticky
- Remove margin-left from main content, use min-w-0 for proper scrolling
- Maintain sticky behavior for vertical scrolling within column

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>
Change section headers from text-lg to text-base for a more compact
and modern dashboard appearance. Reduces visual hierarchy emphasis
on section titles in favor of content focus for LFXV2-644.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>
Replace hardcoded meeting data with live API integration that properly handles:
- Meeting occurrences for recurring meetings
- Time-based filtering with 40-minute buffer after meeting end
- Sorting by earliest time first
- Frontend limit to 5 meetings maximum
- Smart time formatting (Today/Tomorrow/Date)
- Total attendee count from registrants and committee members

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (3)
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (3)

11-14: Replace any types with proper Chart.js types.

Using any defeats TypeScript's type safety. Import and use the proper Chart.js types for chartData and chartOptions.

Apply this diff to add proper types:

+import type { ChartData, ChartOptions } from 'chart.js';
+
-interface ProgressItemWithChart extends ProgressItem {
-  chartData: any;
-  chartOptions: any;
-}
+interface ProgressItemWithChart extends ProgressItem {
+  chartData: ChartData<'line'>;
+  chartOptions: ChartOptions<'line'>;
+}

49-197: Extract duplicated chart options to eliminate repetition.

The chartOptions object is duplicated identically across all 6 progress items (lines 49-57, 77-85, 105-113, 133-141, 161-169, 189-197), violating DRY principles and making maintenance error-prone.

Extract the common configuration:

+  private readonly commonChartOptions: ChartOptions<'line'> = {
+    responsive: true,
+    maintainAspectRatio: false,
+    plugins: { legend: { display: false }, tooltip: { enabled: false } },
+    scales: {
+      x: { display: false },
+      y: { display: false },
+    },
+  };
+
   protected readonly progressItems: ProgressItemWithChart[] = [
     {
       label: 'Pull requests merged',
       value: '12',
       trend: 'up',
       chartData: {
         labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
         datasets: [
           {
             data: [3, 5, 2, 8, 6, 10, 12],
             borderColor: '#3b82f6',
             backgroundColor: 'rgba(59, 130, 246, 0.1)',
             fill: true,
             tension: 0.4,
             borderWidth: 2,
             pointRadius: 0,
           },
         ],
       },
-      chartOptions: {
-        responsive: true,
-        maintainAspectRatio: false,
-        plugins: { legend: { display: false }, tooltip: { enabled: false } },
-        scales: {
-          x: { display: false },
-          y: { display: false },
-        },
-      },
+      chartOptions: this.commonChartOptions,
     },
     // Apply to remaining items...

290-290: Fix or replace the broken Kubernetes logo URL.

The Kubernetes logo URL returns HTTP 404. Either update to a working CDN URL or host the asset locally for reliability.

Apply this diff to use a working URL or local asset:

-      logo: 'https://www.cncf.io/wp-content/uploads/2023/04/kubernetes-icon-color.svg',
+      logo: 'https://raw.githubusercontent.com/cncf/artwork/master/projects/kubernetes/icon/color/kubernetes-icon-color.svg',

Or host locally in your assets folder and reference via relative path.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6b1ed50 and 89a31a3.

📒 Files selected for processing (2)
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.html
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts
🧬 Code graph analysis (1)
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (2)
packages/shared/src/interfaces/components.interface.ts (4)
  • ProgressItem (303-310)
  • PendingActionItem (316-329)
  • MeetingItem (335-342)
  • ProjectItem (348-363)
packages/shared/src/interfaces/meeting.interface.ts (2)
  • Meeting (75-148)
  • MeetingOccurrence (154-165)
🪛 GitHub Actions: Quality Checks
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts

[warning] 1-1: Prettier formatting issues detected in this file. Run 'yarn format:check' with --write (or 'Prettier --write') to fix.

🔇 Additional comments (3)
apps/lfx-one/src/app/modules/pages/home-new/home-new.component.ts (3)

230-284: LGTM: Well-structured meeting filtering logic.

The computed signal properly handles both recurring and single meetings, applies a sensible 40-minute buffer for in-progress meetings, sorts by start time, and limits results to 5. The logic correctly filters out past meetings and maps to the required MeetingItem interface.


334-361: LGTM: Time formatting handles common cases well.

The formatMeetingTime method appropriately formats meetings as "Today"/"Tomorrow" or a full date, using Intl.DateTimeFormat for locale-aware formatting. The date comparison logic is correct, creating date-only versions to avoid time-of-day issues.


324-332: LGTM: Scroll methods are simple and effective.

The horizontal scroll methods use a fixed 300px offset with smooth behavior, providing a clean user experience for navigating the progress items.

- Replace home-new component with modular dashboard architecture
- Add persona-specific dashboard components (my-meetings, my-projects, pending-actions, recent-progress)
- Implement persona service with reactive persona selection
- Update sidebar with footer navigation support and improved styling
- Match sidebar border/shadow styling with PrimeNG card components
- Add persona selector component with dropdown interface
- Update header to integrate persona selector
- Add persona constants to shared package
- Update main layout to support dynamic persona-based routing
- Update profile layout to handle persona changes
- Server-side: Fix user profile persona field mapping

Technical improvements:
- Sidebar: Remove border, update border-radius to 12px, match card shadow
- Sidebar: Add footer items support with separate navigation section
- Sidebar: Improve accessibility with consistent text sizing (text-sm)
- Remove icon hover animations for visual consistency

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>
@asithade asithade changed the title wip(dashboard): initial core persona developer dashboard implementation feat(dashboard): initial core persona developer dashboard implementation Oct 20, 2025
- Remove getTestId() function calls from template
- Add testId property to SidebarMenuItem interface
- Create computed signals (itemsWithTestIds, footerItemsWithTestIds) for test ID generation
- Use Angular signals pattern for better performance and change detection

Performance improvements:
- Computed signals only recalculate when input changes
- Eliminates repeated function calls during template rendering
- Leverages Angular 19 zoneless change detection optimization

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

♻️ Duplicate comments (4)
apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html (1)

12-12: Update all data-testid values to comply with naming convention

Multiple data-testid attributes don't follow the required [section]-[component]-[element] pattern. This includes the previously flagged main-content and other test IDs in this layout.

As per coding guidelines

Suggested updates:

  • mobile-sidebar-overlaymain-layout-mobile-sidebar-overlay
  • mobile-sidebarmain-layout-mobile-sidebar
  • mobile-sidebar-closemain-layout-mobile-sidebar-close-button
  • main-contentmain-layout-content

Apply this diff:

   <!-- Sidebar - Mobile Overlay -->
   @if (showMobileSidebar()) {
-    <div class="lg:hidden fixed inset-0 z-40 bg-black bg-opacity-50" data-testid="mobile-sidebar-overlay" (click)="closeMobileSidebar()">
-      <div class="absolute top-0 left-0 bottom-0 w-72 bg-white shadow-xl" (click)="$event.stopPropagation()" data-testid="mobile-sidebar">
+    <div class="lg:hidden fixed inset-0 z-40 bg-black bg-opacity-50" data-testid="main-layout-mobile-sidebar-overlay" (click)="closeMobileSidebar()">
+      <div class="absolute top-0 left-0 bottom-0 w-72 bg-white shadow-xl" (click)="$event.stopPropagation()" data-testid="main-layout-mobile-sidebar">
         <div class="flex items-center justify-between p-4 border-b border-gray-200">
           <h2 class="text-lg font-semibold text-gray-900">Menu</h2>
           <button
@@ -18,7 +18,7 @@
             class="hover:opacity-80 transition-opacity p-2"
             (click)="closeMobileSidebar()"
             aria-label="Close menu"
-            data-testid="mobile-sidebar-close">
+            data-testid="main-layout-mobile-sidebar-close-button">
             <i class="fa-light fa-times text-gray-600 text-xl"></i>
           </button>
         </div>
@@ -30,7 +30,7 @@
   }
 
   <!-- Main Content Area -->
-  <main class="flex-1 min-w-0 transition-all duration-300 lg:ml-72" data-testid="main-content">
+  <main class="flex-1 min-w-0 transition-all duration-300 lg:ml-72" data-testid="main-layout-content">
     <router-outlet />
   </main>
 </div>

Also applies to: 13-13, 21-21, 33-33

apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html (1)

12-12: Update all data-testid values to comply with naming convention

The data-testid attributes don't follow the required [section]-[component]-[element] pattern, as previously noted in the earlier review. The sidebar test ID and dynamically generated item IDs need to be updated.

As per coding guidelines

As suggested in the previous review:

  • sidebarcore-dashboard-sidebar-container
  • Dynamic item IDs via getTestId() should generate values like core-dashboard-sidebar-item-<kebab-label>

Update the component's getTestId() method to return the properly prefixed and kebab-cased value, and update the static test ID in the template.

Also applies to: 24-24, 40-40, 57-57, 81-81, 97-97, 114-114

apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1)

27-28: Test ID convention not fully aligned with guidelines.

The current implementation generates test IDs like sidebar-item-home but the coding guidelines specify [section]-[component]-[element] format. For a reusable component like this sidebar, consider either:

  1. Accepting a section input to prefix test IDs appropriately for different contexts
  2. Documenting that the parent component should provide complete test IDs via a separate property

Based on learnings.

apps/lfx-one/src/app/shared/services/persona.service.ts (1)

17-28: Unsafe type assertion without validation (previously flagged).

Line 23 still uses an unsafe type assertion (as PersonaType) without validating the stored value. This issue was previously identified and remains unaddressed. If localStorage contains an invalid value due to corruption or manual editing, it could cause runtime issues.

As suggested in the previous review, apply this diff to add validation:

-    afterNextRender(() => {
-      const stored = localStorage.getItem(this.storageKey) as PersonaType;
-      if (stored) {
-        this.currentPersona.set(stored);
-      }
-    });
+    afterNextRender(() => {
+      const stored = localStorage.getItem(this.storageKey);
+      if (stored === 'core-developer' || stored === 'old-ui') {
+        this.currentPersona.set(stored);
+      }
+    });
🧹 Nitpick comments (7)
apps/lfx-one/src/server/services/user.service.ts (1)

160-160: Consider updating error message to match the field name.

The error message still says "Job title is too long" but now validates the title field. For consistency and clarity, consider updating the message.

Apply this diff:

-      throw new Error('Job title is too long');
+      throw new Error('Title is too long');
apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html (1)

67-75: Consider extracting duplicated chart options

The chart configuration object is identical in both code and non-code activity sections. Consider extracting this to a protected property in the component to reduce duplication.

Example in the component TypeScript file:

protected readonly chartOptions = {
  responsive: true,
  maintainAspectRatio: false,
  plugins: { legend: { display: false }, tooltip: { enabled: false } },
  scales: {
    x: { display: false },
    y: { display: false },
  },
};

Then reference it in the template:

<lfx-chart ... [options]="chartOptions" height="100%"></lfx-chart>

Also applies to: 104-112

apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html (1)

14-67: Consider extracting navigation item template to reduce duplication

The main navigation block (lines 14-67) and footer navigation block (lines 71-125) contain nearly identical markup with only minor differences. Consider extracting the navigation item rendering logic into a reusable ng-template to improve maintainability.

Example approach:

<ng-template #navItem let-item>
  @if (item.routerLink) {
    <a [routerLink]="item.routerLink" ...>
      <!-- item content -->
    </a>
  }
  @if (item.url) {
    <a [href]="item.url" ...>
      <!-- item content -->
    </a>
  }
  @if (item.command && !item.routerLink && !item.url) {
    <button (click)="item.command()" ...>
      <!-- item content -->
    </button>
  }
</ng-template>

<nav class="flex flex-col py-3 flex-grow overflow-y-auto">
  @for (item of items(); track item.label) {
    <ng-container *ngTemplateOutlet="navItem; context: { $implicit: item }"></ng-container>
  }
</nav>

This would reduce the ~110 lines to approximately 70 lines while maintaining the same functionality.

Also applies to: 71-125

apps/lfx-one/src/app/shared/components/header/header.component.ts (1)

157-160: Consider refactoring custom event pattern.

Using window custom events for component communication creates tight coupling and makes the code harder to test and maintain. Consider using a shared service with an observable or Angular's output/input signals for better type safety and testability.

Example with a service:

// layout.service.ts
@Injectable({ providedIn: 'root' })
export class LayoutService {
  private readonly _mobileSidebarToggle = signal(false);
  public readonly mobileSidebarVisible = this._mobileSidebarToggle.asReadonly();
  
  public toggleMobileSidebar(): void {
    this._mobileSidebarToggle.update(v => !v);
  }
}

Then inject and use in both header and layout components.

apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts (1)

11-48: Placeholder data as expected for WIP implementation.

The hardcoded project data aligns with the PR objectives for placeholder content. The component structure is clean and uses proper encapsulation with protected readonly.

Consider hosting the logo images locally or using a CDN to avoid potential availability or CORS issues with external URLs (GitHub, Wikipedia, nodejs.org) when this moves beyond the placeholder phase.

packages/shared/src/interfaces/components.interface.ts (1)

301-324: LGTM! Good use of interface extension for chart data.

The ProgressItemWithChart interface extends ProgressItem cleanly and properly types the chart.js integration with ChartData<'line'> and ChartOptions<'line'>.

Consider making the chart type generic if you need to support other chart types (bar, pie, etc.) in the future:

export interface ProgressItemWithChart<T extends keyof ChartTypeRegistry = 'line'> extends ProgressItem {
  chartData: ChartData<T>;
  chartOptions: ChartOptions<T>;
}
apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (1)

24-78: Consider configurability for the buffer and align null-safety patterns with existing defensive coding in the codebase.

The code is type-safe based on the Meeting interface, but two items merit attention:

  1. Line 27: The 40-minute buffer is hardcoded. Consider making this configurable (e.g., via a constant or service configuration).
  2. Line 76: While the interface defines individual_registrants_count and committee_members_count as required number fields, other components in the codebase (e.g., meeting-card.component.ts) use defensive || 0 checks on these fields. For consistency, apply the same pattern:
       .map((item) => ({
         title: item.occurrence.title,
         time: this.formatMeetingTime(item.occurrence.start_time),
-        attendees: item.meeting.individual_registrants_count + item.meeting.committee_members_count,
+        attendees: (item.meeting.individual_registrants_count || 0) + (item.meeting.committee_members_count || 0),
       }));
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 89a31a3 and 6d02a96.

📒 Files selected for processing (34)
  • apps/lfx-one/src/app/app.routes.ts (1 hunks)
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html (1 hunks)
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (1 hunks)
  • apps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.scss (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.scss (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.scss (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.scss (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.scss (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/profile/edit/profile-edit.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/profile/edit/profile-edit.component.ts (3 hunks)
  • apps/lfx-one/src/app/shared/components/header/header.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/header/header.component.ts (4 hunks)
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/services/persona.service.ts (1 hunks)
  • apps/lfx-one/src/server/server.ts (1 hunks)
  • apps/lfx-one/src/server/services/user.service.ts (1 hunks)
  • packages/shared/src/constants/index.ts (1 hunks)
  • packages/shared/src/constants/persona.constants.ts (1 hunks)
  • packages/shared/src/interfaces/components.interface.ts (2 hunks)
  • packages/shared/src/interfaces/user-profile.interface.ts (1 hunks)
✅ Files skipped from review due to trivial changes (6)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.scss
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.scss
  • apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.scss
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.scss
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.scss
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts
  • apps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts
  • packages/shared/src/interfaces/user-profile.interface.ts
  • packages/shared/src/constants/persona.constants.ts
  • apps/lfx-one/src/server/server.ts
  • apps/lfx-one/src/app/modules/profile/edit/profile-edit.component.ts
  • packages/shared/src/constants/index.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts
  • packages/shared/src/interfaces/components.interface.ts
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
  • apps/lfx-one/src/app/app.routes.ts
  • apps/lfx-one/src/server/services/user.service.ts
  • apps/lfx-one/src/app/shared/components/header/header.component.ts
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
  • apps/lfx-one/src/app/shared/services/persona.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts
  • apps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html
  • apps/lfx-one/src/app/modules/profile/edit/profile-edit.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts
  • packages/shared/src/interfaces/user-profile.interface.ts
  • packages/shared/src/constants/persona.constants.ts
  • apps/lfx-one/src/server/server.ts
  • apps/lfx-one/src/app/modules/profile/edit/profile-edit.component.ts
  • packages/shared/src/constants/index.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.html
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts
  • packages/shared/src/interfaces/components.interface.ts
  • apps/lfx-one/src/app/shared/components/header/header.component.html
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
  • apps/lfx-one/src/app/app.routes.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/server/services/user.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
  • apps/lfx-one/src/app/shared/components/header/header.component.ts
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
  • apps/lfx-one/src/app/shared/services/persona.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts
  • apps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts
  • packages/shared/src/interfaces/user-profile.interface.ts
  • packages/shared/src/constants/persona.constants.ts
  • apps/lfx-one/src/server/server.ts
  • apps/lfx-one/src/app/modules/profile/edit/profile-edit.component.ts
  • packages/shared/src/constants/index.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts
  • packages/shared/src/interfaces/components.interface.ts
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
  • apps/lfx-one/src/app/app.routes.ts
  • apps/lfx-one/src/server/services/user.service.ts
  • apps/lfx-one/src/app/shared/components/header/header.component.ts
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
  • apps/lfx-one/src/app/shared/services/persona.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts
apps/lfx-one/src/**/*.html

📄 CodeRabbit inference engine (CLAUDE.md)

apps/lfx-one/src/**/*.html: Always add data-testid attributes when creating new Angular components for reliable test targeting
Use data-testid naming convention [section]-[component]-[element]

Files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html
  • apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html
  • apps/lfx-one/src/app/modules/profile/edit/profile-edit.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.html
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.html
  • apps/lfx-one/src/app/shared/components/header/header.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
packages/shared/src/interfaces/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place all TypeScript interfaces in the shared package at packages/shared/src/interfaces

Files:

  • packages/shared/src/interfaces/user-profile.interface.ts
  • packages/shared/src/interfaces/components.interface.ts
packages/shared/src/constants/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place all reusable constants in the shared package at packages/shared/src/constants

Files:

  • packages/shared/src/constants/persona.constants.ts
  • packages/shared/src/constants/index.ts
**/index.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Do not use barrel exports; always use direct imports for standalone components

Files:

  • packages/shared/src/constants/index.ts
🧠 Learnings (3)
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to apps/lfx-one/src/**/*.html : Use data-testid naming convention [section]-[component]-[element]

Applied to files:

  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to apps/lfx-one/src/**/*.html : Always add data-testid attributes when creating new Angular components for reliable test targeting

Applied to files:

  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to packages/shared/src/constants/**/*.ts : Place all reusable constants in the shared package at packages/shared/src/constants

Applied to files:

  • packages/shared/src/constants/index.ts
🧬 Code graph analysis (10)
apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts (4)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (1)
  • Component (11-118)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts (1)
  • Component (11-48)
apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts (1)
  • Component (9-49)
apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.ts (1)
  • Component (10-200)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts (2)
apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts (1)
  • Component (10-17)
packages/shared/src/interfaces/components.interface.ts (1)
  • ProjectItem (362-377)
packages/shared/src/constants/persona.constants.ts (1)
packages/shared/src/interfaces/persona.interface.ts (1)
  • PersonaOption (14-23)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (3)
apps/lfx-one/src/server/services/meeting.service.ts (1)
  • MeetingService (29-498)
packages/shared/src/interfaces/meeting.interface.ts (2)
  • Meeting (75-148)
  • MeetingOccurrence (154-165)
packages/shared/src/interfaces/components.interface.ts (1)
  • MeetingItem (349-356)
apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (3)
apps/lfx-one/src/app/shared/components/header/header.component.ts (1)
  • Component (23-165)
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1)
  • Component (10-30)
packages/shared/src/interfaces/components.interface.ts (1)
  • SidebarMenuItem (267-286)
apps/lfx-one/src/app/shared/components/header/header.component.ts (1)
packages/shared/src/interfaces/user-profile.interface.ts (1)
  • CombinedProfile (17-20)
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (2)
apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (1)
  • Component (11-111)
packages/shared/src/interfaces/components.interface.ts (1)
  • SidebarMenuItem (267-286)
apps/lfx-one/src/app/shared/services/persona.service.ts (1)
packages/shared/src/interfaces/persona.interface.ts (1)
  • PersonaType (8-8)
apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts (2)
apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts (1)
  • Component (10-17)
packages/shared/src/interfaces/components.interface.ts (1)
  • PendingActionItem (330-343)
apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.ts (3)
apps/lfx-one/src/app/shared/components/header/header.component.ts (1)
  • Component (23-165)
packages/shared/src/constants/persona.constants.ts (1)
  • PERSONA_OPTIONS (9-20)
packages/shared/src/interfaces/persona.interface.ts (1)
  • PersonaType (8-8)
🔇 Additional comments (28)
apps/lfx-one/src/app/layouts/profile-layout/profile-layout.component.ts (1)

148-148: LGTM! Field rename aligned with interface changes.

The update from job_title to title is consistent with the UserMetadata interface change across the codebase.

apps/lfx-one/src/server/services/user.service.ts (1)

159-159: LGTM! Field rename aligned with interface changes.

The validation check correctly updated from job_title to title, consistent with the UserMetadata interface change.

packages/shared/src/interfaces/user-profile.interface.ts (1)

122-122: LGTM! Interface field renamed consistently.

The job_title to title rename in the UserMetadata interface is a cleaner, more concise name. The change is applied consistently across the codebase (frontend components, backend validation, display logic).

apps/lfx-one/src/app/modules/profile/edit/profile-edit.component.html (1)

100-100: LGTM! Control binding updated correctly.

The control name change from job_title to title aligns with the UserMetadata interface update and maintains consistency with the component's form definition.

apps/lfx-one/src/app/shared/components/persona-selector/persona-selector.component.html (1)

1-6: LGTM! Clean persona selector template.

The template correctly uses form binding with proper data-testid attributes for testing. The select component is properly configured with options, labels, and values.

apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.html (1)

1-22: LGTM! Well-structured dashboard layout.

The dashboard template has a clean, responsive structure with proper test attributes. The grid layout will adapt well across screen sizes.

packages/shared/src/constants/index.ts (1)

12-12: LGTM! Persona constants properly exported.

The export follows the established pattern and coding guidelines for placing reusable constants in the shared package.

Based on learnings

apps/lfx-one/src/server/server.ts (1)

163-163: The review comment is based on an incorrect technical assumption about the application architecture.

Frontend profile updates do not require the update:current_user_metadata scope because the application uses a backend-mediated pattern: the frontend collects form data and calls userService.updateUserProfile(), which sends a request to the backend. The backend then uses the token from the OIDC session to communicate with Auth0 via NATS (specifically the USER_METADATA_UPDATE subject handled by the auth-service).

Since the frontend never makes direct Auth0 Management API calls, it never needed this scope. The current scope configuration (openid email profile access:api offline_access) is correct for frontend authentication and backend API access.

Likely an incorrect or invalid review comment.

packages/shared/src/constants/persona.constants.ts (1)

1-20: LGTM!

The constant is correctly placed in the shared package constants directory, uses proper typing with the PersonaOption interface, and includes the required license header. The implementation is clean and follows project conventions.

apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts (1)

1-17: LGTM!

Clean container component with proper license header, appropriate imports, and standalone configuration. The structure is straightforward and follows Angular best practices.

apps/lfx-one/src/app/app.routes.ts (1)

12-23: Clean route structure with proper lazy loading.

The MainLayoutComponent with nested children routes follows Angular best practices. The lazy-loaded components and proper use of loadComponent ensure optimal bundle splitting.

apps/lfx-one/src/app/shared/components/header/header.component.html (2)

8-44: Header start template is well-structured.

The mobile toggle, home button, and authenticated user profile display are properly implemented with conditional rendering and appropriate data-testid attributes.


49-49: Good replacement of tools component with persona selector.

The PersonaSelectorComponent integration aligns with the PR's persona-switching feature and maintains the header's modular design.

apps/lfx-one/src/app/modules/profile/edit/profile-edit.component.ts (2)

89-89: Field rename applied correctly.

The job_title to title field rename is properly implemented and consistent with the interface changes in the shared package.


144-144: Payload construction uses renamed field correctly.

The title field is properly mapped in the userMetadata payload.

apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts (1)

19-44: Placeholder data aligns with PR objectives.

The static pendingActions array provides appropriate placeholder content for the WIP dashboard implementation. The structure follows the PendingActionItem interface correctly.

apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (1)

25-86: Sidebar navigation structure is well-organized.

The separation of main navigation items and footer items with appropriate disabled states for WIP features aligns with the PR's placeholder approach.

apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1)

19-22: Modern input signals pattern used correctly.

The signal-based input() and input.required() functions follow Angular's latest patterns, providing better type safety and performance.

apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts (1)

1-9: LGTM! Clean imports and proper license header.

The license header and imports follow the coding guidelines. The ProjectItem interface is correctly imported from the shared package.

packages/shared/src/interfaces/components.interface.ts (4)

263-286: LGTM! Well-structured sidebar menu interface.

The SidebarMenuItem interface is well-designed with:

  • Proper support for nested navigation via recursive items? field
  • Flexible routing with both routerLink and external url options
  • Good JSDoc documentation

288-299: LGTM! Clean sidebar props interface.

The SidebarProps interface provides a clean API for sidebar configuration.


326-343: LGTM! Well-defined action item interface.

The PendingActionItem interface provides a clear structure for task items with appropriate color theming options.


345-377: LGTM! Clean and well-documented interfaces.

Both MeetingItem and ProjectItem interfaces are well-structured and properly documented. The ProjectItem interface correctly matches its usage in the my-projects component.

apps/lfx-one/src/app/shared/services/persona.service.ts (2)

1-10: LGTM! Proper imports and service setup.

The service uses appropriate Angular APIs and the license header is present.


30-46: LGTM! Clean persona switching logic.

The setPersona method properly updates the signal, persists the choice, and navigates to the appropriate route based on the persona type.

apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (3)

1-9: LGTM! Proper license header and imports.

The imports are clean and appropriate for the component's needs.


11-23: LGTM! Clean component setup with reactive signals.

The component uses Angular signals appropriately for reactive state management and provides a proper output for meeting join events.


87-117: LGTM! Clean event handling and good i18n-aware date formatting.

The handleJoinMeeting method properly emits the meeting event, and formatMeetingTime uses Intl.DateTimeFormat for internationalization-friendly date formatting.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1)

24-37: Improve test ID slug generation to handle special characters.

The current test ID generation only replaces whitespace with hyphens. Labels containing special characters like &, /, (, ) will produce invalid or poorly-formed test IDs (e.g., "Events & Community""sidebar-item-events-&-community").

Apply this diff to strip non-alphanumeric characters:

   protected readonly itemsWithTestIds = computed(() =>
     this.items().map((item) => ({
       ...item,
-      testId: item.testId || `sidebar-item-${item.label.toLowerCase().replace(/\s+/g, '-')}`,
+      testId: item.testId || `sidebar-item-${item.label.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '')}`,
     }))
   );
 
   protected readonly footerItemsWithTestIds = computed(() =>
     this.footerItems().map((item) => ({
       ...item,
-      testId: item.testId || `sidebar-item-${item.label.toLowerCase().replace(/\s+/g, '-')}`,
+      testId: item.testId || `sidebar-item-${item.label.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '')}`,
     }))
   );
🧹 Nitpick comments (1)
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html (1)

4-12: Consider moving inline styles to the SCSS file.

The shadow and border-radius styles at lines 6-11 are currently inline. Moving them to the component's SCSS file would improve maintainability and allow for easier theming.

In sidebar.component.scss:

aside {
  border-radius: 12px;
  box-shadow: 
    rgba(0, 0, 0, 0.1) 0px 1px 3px 0px,
    rgba(0, 0, 0, 0.1) 0px 1px 2px -1px;
}

Then simplify the template:

 <aside
   class="h-[calc(100vh-8rem)] bg-white transition-all duration-300 w-64 ml-4 flex flex-col"
-  style="
-    border-radius: 12px;
-    box-shadow:
-      rgba(0, 0, 0, 0.1) 0px 1px 3px 0px,
-      rgba(0, 0, 0, 0.1) 0px 1px 2px -1px;
-  "
   data-testid="sidebar">
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6d02a96 and faf61c6.

📒 Files selected for processing (5)
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1 hunks)
  • apps/lfx-one/src/server/services/user.service.ts (1 hunks)
  • packages/shared/src/interfaces/components.interface.ts (2 hunks)
  • packages/shared/src/interfaces/user-profile.interface.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/lfx-one/src/server/services/user.service.ts
  • packages/shared/src/interfaces/user-profile.interface.ts
🧰 Additional context used
📓 Path-based instructions (5)
apps/lfx-one/src/**/*.html

📄 CodeRabbit inference engine (CLAUDE.md)

apps/lfx-one/src/**/*.html: Always add data-testid attributes when creating new Angular components for reliable test targeting
Use data-testid naming convention [section]-[component]-[element]

Files:

  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
  • packages/shared/src/interfaces/components.interface.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
  • packages/shared/src/interfaces/components.interface.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
  • packages/shared/src/interfaces/components.interface.ts
packages/shared/src/interfaces/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place all TypeScript interfaces in the shared package at packages/shared/src/interfaces

Files:

  • packages/shared/src/interfaces/components.interface.ts
🧠 Learnings (1)
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to apps/lfx-one/src/**/*.html : Use data-testid naming convention [section]-[component]-[element]

Applied to files:

  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts
🧬 Code graph analysis (1)
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (2)
apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (1)
  • Component (11-111)
packages/shared/src/interfaces/components.interface.ts (1)
  • SidebarMenuItem (267-288)
🔇 Additional comments (2)
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1)

1-16: LGTM! Clean component setup.

The license header, imports, and standalone component configuration are correct.

packages/shared/src/interfaces/components.interface.ts (1)

263-378: LGTM! Well-structured interface definitions.

All new interfaces are properly documented, follow TypeScript best practices, and use appropriate types. The optional fields are correctly marked, and the JSDoc comments provide clear descriptions.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
apps/lfx-one/src/app/shared/services/persona.service.ts (1)

22-27: Validate stored persona value before using it.

The code performs an unsafe type assertion without validating that the stored value is actually a valid PersonaType. If localStorage contains an invalid value (from corruption, manual editing, or version changes), it could cause runtime issues.

Apply this diff to add validation:

   afterNextRender(() => {
-    const stored = localStorage.getItem(this.storageKey) as PersonaType;
-    if (stored) {
+    const stored = localStorage.getItem(this.storageKey);
+    if (stored === 'core-developer' || stored === 'old-ui') {
       this.currentPersona.set(stored);
     }
   });
apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (1)

20-22: Good fix: subscription leak resolved via toSignal

Switching to toSignal() addresses the prior unmanaged subscription. ✅

🧹 Nitpick comments (10)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html (1)

45-117: Add data-testid attributes to chart containers for improved test coverage.

The Code Activities and Non-Code Activities chart containers (lines 45–80 and 82–117) lack data-testid attributes. For consistent test targeting across all significant dashboard elements, consider adding:

  • Line 47: data-testid="dashboard-my-projects-code-activities-chart"
  • Line 84: data-testid="dashboard-my-projects-non-code-activities-chart"

Apply this diff to add the missing test IDs:

          <!-- Code Activities -->
          <div
-           class="p-4 bg-gray-50 rounded-none lg:rounded-none border border-gray-200 border-b-0 border-t-0 lg:border-t lg:border-b lg:border-r-0 lg:border-l-0 w-full lg:flex-1">
+           class="p-4 bg-gray-50 rounded-none lg:rounded-none border border-gray-200 border-b-0 border-t-0 lg:border-t lg:border-b lg:border-r-0 lg:border-l-0 w-full lg:flex-1"
+           data-testid="dashboard-my-projects-code-activities-chart">
             <div class="text-sm text-gray-700">

          <!-- Non-Code Activities -->
          <div
-           class="p-4 bg-gray-50 rounded-b-lg lg:rounded-r-lg lg:rounded-l-none lg:rounded-b-lg border border-t-0 lg:border-t border-gray-200 lg:border-l-0 w-full lg:flex-1">
+           class="p-4 bg-gray-50 rounded-b-lg lg:rounded-r-lg lg:rounded-l-none lg:rounded-b-lg border border-t-0 lg:border-t border-gray-200 lg:border-l-0 w-full lg:flex-1"
+           data-testid="dashboard-my-projects-non-code-activities-chart">
             <div class="text-sm text-gray-700">
apps/lfx-one/src/app/shared/components/header/header.component.ts (1)

56-56: Consider extracting initials from both first and last names.

The current implementation only extracts the first character of first_name. For better UX, consider extracting initials from both first and last names as suggested in the previous review.

Apply this diff to extract initials from both names:

-  public initials = computed(() => this.userProfile()?.user.first_name?.slice(0, 1));
+  public initials = computed(() => {
+    const profile = this.userProfile();
+    if (!profile) return '';
+    const first = profile.user.first_name?.slice(0, 1) ?? '';
+    const last = profile.user.last_name?.slice(0, 1) ?? '';
+    return (first + last).toUpperCase();
+  });
apps/lfx-one/src/app/shared/services/persona.service.ts (1)

46-48: Guard localStorage access for SSR compatibility.

While afterNextRender ensures browser-only initialization, persistPersona is called from the public setPersona method which could theoretically be invoked during SSR, causing a runtime error.

Apply this diff to add a guard:

 private persistPersona(persona: PersonaType): void {
+  if (typeof window !== 'undefined' && window.localStorage) {
     localStorage.setItem(this.storageKey, persona);
+  }
 }
apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html (3)

16-16: Use a stable, unique track key to avoid DOM reuse issues

Tracking by item.time risks collisions. Short-term: use a composite key. Long-term: prefer a dedicated id.

Quick fix:

-      @for (item of meetings(); track item.time) {
+      @for (item of meetings(); track (item.title + '|' + item.time)) {

If you adopt the id/slug change in the TS (see my comment there), then:

-      @for (item of meetings(); track item.time) {
+      @for (item of meetings(); track item.id) {

19-19: Make data-testid deterministic and selector‑safe

Using raw titles can introduce spaces/special chars. Prefer a slug or unique id to keep selectors stable.

If adding id and slug in TS as suggested:

-          [attr.data-testid]="'dashboard-my-meetings-item-' + item.title">
+          [attr.data-testid]="'dashboard-my-meetings-item-' + item.slug">

Alternative (no TS change, but less robust): define a component helper and call it here:

[attr.data-testid]="toItemTestId(item.title)"

8-11: A11y: hide decorative icons and provide contextual button label

Mark icons decorative and include the meeting title in the join button’s aria-label.

-        <i class="fa-light fa-calendar-days text-2xl text-green-500"></i>
+        <i class="fa-light fa-calendar-days text-2xl text-green-500" aria-hidden="true"></i>
...
-                <i class="fa-light fa-calendar text-green-600"></i>
+                <i class="fa-light fa-calendar text-green-600" aria-hidden="true"></i>
...
-                <i class="fa-light fa-users text-xs"></i>
+                <i class="fa-light fa-users text-xs" aria-hidden="true"></i>
...
-                aria-label="Join meeting">
+                [attr.aria-label]="'Join meeting ' + item.title">

Also applies to: 23-24, 31-33, 35-41

apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (4)

12-18: Adopt OnPush change detection

Improves perf with signals; aligns with best practices for standalone components.

-import { Component, computed, inject, output } from '@angular/core';
+import { Component, ChangeDetectionStrategy, computed, inject, output } from '@angular/core';
...
 @Component({
   selector: 'lfx-my-meetings',
   standalone: true,
   imports: [CommonModule, CardComponent],
   templateUrl: './my-meetings.component.html',
   styleUrl: './my-meetings.component.scss',
+  changeDetection: ChangeDetectionStrategy.OnPush,
 })

21-22: Harden data stream: prevent template errors if API fails

If getMeetings() errors, toSignal can surface it during compute. Default to empty list on error.

-import { toSignal } from '@angular/core/rxjs-interop';
+import { toSignal } from '@angular/core/rxjs-interop';
+import { catchError, of } from 'rxjs';
...
-  private readonly allMeetings = toSignal(this.meetingService.getMeetings(), { initialValue: [] });
+  private readonly allMeetings = toSignal(
+    this.meetingService.getMeetings().pipe(
+      catchError(() => of([] as Meeting[]))
+    ),
+    { initialValue: [] as Meeting[] }
+  );

25-79: Provide stable id/slug for UI keys and test ids

Expose a deterministic id and slug for each item so the template can track item.id and build safe test ids.

-  protected readonly meetings = computed<MeetingItem[]>(() => {
+  type UiMeetingItem = MeetingItem & { id: string; slug: string };
+  protected readonly meetings = computed<UiMeetingItem[]>(() => {
@@
-    return upcomingMeetings
+    const slug = (s: string) => s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
+    return upcomingMeetings
       .sort((a, b) => a.sortTime - b.sortTime)
       .slice(0, 5)
-      .map((item) => ({
-        title: item.occurrence.title,
-        time: this.formatMeetingTime(item.occurrence.start_time),
-        attendees: item.meeting.individual_registrants_count + item.meeting.committee_members_count,
-      }));
+      .map((item) => {
+        const id = `${item.meeting.uid}:${item.occurrence.occurrence_id || item.occurrence.start_time}`;
+        const title = item.occurrence.title;
+        return {
+          id,
+          slug: slug(title),
+          title,
+          time: this.formatMeetingTime(item.occurrence.start_time),
+          attendees: (item.meeting.individual_registrants_count ?? 0) + (item.meeting.committee_members_count ?? 0),
+        };
+      });

Then update the template per my HTML comment to use track item.id and item.slug.


85-111: i18n-friendly date formatting

Use Angular’s locale to format dates; fall back to “Today/Tomorrow” labels as you do now.

-import { CommonModule } from '@angular/common';
+import { CommonModule, LOCALE_ID, formatDate } from '@angular/common';
...
-export class MyMeetingsComponent {
+export class MyMeetingsComponent {
   private readonly meetingService = inject(MeetingService);
+  private readonly locale = inject(LOCALE_ID);
@@
-    const timeFormatter = new Intl.DateTimeFormat('en-US', {
-      hour: 'numeric',
-      minute: '2-digit',
-      hour12: true,
-    });
-
-    const formattedTime = timeFormatter.format(meetingDate);
+    const formattedTime = formatDate(meetingDate, 'h:mm a', this.locale);
@@
-    const dateFormatter = new Intl.DateTimeFormat('en-US', {
-      weekday: 'long',
-      month: 'short',
-      day: 'numeric',
-    });
-    return `${dateFormatter.format(meetingDate)}, ${formattedTime}`;
+    return `${formatDate(meetingDate, 'EEEE, MMM d', this.locale)}, ${formattedTime}`;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between faf61c6 and c11c8fe.

📒 Files selected for processing (12)
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/header/header.component.ts (4 hunks)
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/services/app.service.ts (1 hunks)
  • apps/lfx-one/src/app/shared/services/persona.service.ts (1 hunks)
  • apps/lfx-one/src/server/controllers/profile.controller.ts (1 hunks)
  • packages/shared/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.html
  • apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.html
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • apps/lfx-one/src/server/controllers/profile.controller.ts
  • apps/lfx-one/src/app/shared/services/app.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts
  • apps/lfx-one/src/app/shared/components/header/header.component.ts
  • apps/lfx-one/src/app/shared/services/persona.service.ts
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • apps/lfx-one/src/server/controllers/profile.controller.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html
  • apps/lfx-one/src/app/shared/services/app.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
  • apps/lfx-one/src/app/shared/components/header/header.component.ts
  • apps/lfx-one/src/app/shared/services/persona.service.ts
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/server/controllers/profile.controller.ts
  • apps/lfx-one/src/app/shared/services/app.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts
  • apps/lfx-one/src/app/shared/components/header/header.component.ts
  • apps/lfx-one/src/app/shared/services/persona.service.ts
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
apps/lfx-one/src/**/*.html

📄 CodeRabbit inference engine (CLAUDE.md)

apps/lfx-one/src/**/*.html: Always add data-testid attributes when creating new Angular components for reliable test targeting
Use data-testid naming convention [section]-[component]-[element]

Files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
🧠 Learnings (2)
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to apps/lfx-one/src/**/*.html : Use data-testid naming convention [section]-[component]-[element]

Applied to files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to apps/lfx-one/src/**/*.html : Always add data-testid attributes when creating new Angular components for reliable test targeting

Applied to files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
🧬 Code graph analysis (5)
apps/lfx-one/src/app/shared/services/app.service.ts (1)
apps/lfx-one/src/app/shared/services/persona.service.ts (1)
  • Injectable (8-49)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (2)
packages/shared/src/interfaces/components.interface.ts (1)
  • MeetingItem (351-358)
packages/shared/src/interfaces/meeting.interface.ts (2)
  • Meeting (75-148)
  • MeetingOccurrence (154-165)
apps/lfx-one/src/app/shared/components/header/header.component.ts (1)
packages/shared/src/interfaces/user-profile.interface.ts (1)
  • CombinedProfile (17-20)
apps/lfx-one/src/app/shared/services/persona.service.ts (2)
apps/lfx-one/src/app/shared/services/app.service.ts (1)
  • Injectable (10-39)
packages/shared/src/interfaces/persona.interface.ts (1)
  • PersonaType (8-8)
apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (3)
apps/lfx-one/src/app/shared/components/header/header.component.ts (1)
  • Component (24-166)
apps/lfx-one/src/app/shared/components/sidebar/sidebar.component.ts (1)
  • Component (10-38)
packages/shared/src/interfaces/components.interface.ts (1)
  • SidebarMenuItem (267-288)
🔇 Additional comments (7)
apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html (1)

1-58: Well done incorporating the past review feedback!

The data-testid attributes now correctly follow the [section]-[component]-[element] naming convention throughout (dashboard-recent-progress-card, dashboard-recent-progress-scroll-left, dashboard-recent-progress-scroll-right, dashboard-recent-progress-items, dashboard-recent-progress-item-*, dashboard-recent-progress-trend-up/down). License headers are in place, accessibility attributes (aria-label) are properly included on interactive elements, and the template uses modern Angular 19.x control flow syntax appropriately.

apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html (2)

1-2: ✓ License headers properly included.

Headers are correctly formatted with copyright and SPDX-License-Identifier as required by coding guidelines.


4-4: ✓ data-testid naming convention compliance verified.

All data-testid attributes follow the required [section]-[component]-[element] pattern:

  • Line 4: dashboard-my-projects-card
  • Line 15: dashboard-my-projects-list
  • Line 17: dashboard-my-projects-item-[dynamic]
  • Line 23: dashboard-my-projects-logo

Previous review feedback has been properly incorporated. This aligns with coding guidelines for reliable test targeting.

Also applies to: 15-15, 17-17, 23-23

apps/lfx-one/src/app/shared/services/app.service.ts (1)

1-39: LGTM! Clean signal-based state management.

The service properly encapsulates mobile sidebar state using Angular signals with a private writable signal and public readonly exposure. The API is simple and well-documented.

apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts (1)

1-106: LGTM! Proper integration with AppService.

The component correctly integrates with AppService for mobile sidebar management and uses takeUntilDestroyed() for automatic cleanup of the router subscription. The previous issue with window event listeners has been resolved.

apps/lfx-one/src/app/shared/components/header/header.component.ts (1)

159-161: LGTM! Proper delegation to AppService.

The mobile sidebar toggle correctly delegates to the centralized AppService.

apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html (1)

1-2: LGTM: license header and test ids comply with guidelines

Headers present. data-testid values follow [section]-[component]-[element]. Nice.

As per coding guidelines

Also applies to: 4-4, 15-15, 31-31, 39-39

Signed-off-by: Asitha de Silva <[email protected]>
@github-actions
Copy link

github-actions bot commented Oct 20, 2025

❌ E2E Tests Failed

Browser: chromium
Status: failed

Some E2E tests failed. Check the test report for details.

Test Configuration

- Create reusable DashboardMeetingCardComponent for displaying meeting information
- Update MyMeetingsComponent to use new card component with Today/Upcoming sections
- Add conditional section rendering (hide sections when empty)
- Match React component styling with white card background, gray icons, rounded-xl borders
- Implement smart date filtering for today's meetings vs upcoming meetings
- Add meeting feature icons (YouTube, Recording, Transcripts, AI, Public/Private)
- Add DashboardMeetingCardProps and DashboardMeetingFeatures interfaces to shared package
- Update RecentProgressComponent styling to match React design
- Remove PrimeNG Card dependency in favor of semantic HTML with Tailwind

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/shared/src/interfaces/components.interface.ts (1)

4-4: chart.js dependency still not added to packages/shared/package.json.

The past review comment about adding chart.js to packages/shared/package.json has not been addressed. Since this package exports ProgressItemWithChart which uses ChartData and ChartOptions types, chart.js must be declared as a dependency.

🧹 Nitpick comments (4)
apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts (1)

57-93: Consider timezone-aware date formatting.

The formattedTime computation parses dates in the user's local timezone without accounting for the meeting.timezone field from the Meeting interface. This could cause confusion for international users when meeting times are displayed incorrectly relative to their local time.

Consider using a library like date-fns-tz or luxon to format dates according to the meeting's specified timezone, or clearly indicate which timezone is being displayed.

apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (3)

32-83: Add error handling for invalid date strings.

The todayMeetings computation assumes meeting.start_time and occurrence.start_time are always valid date strings. If the API returns malformed dates, new Date() will create an Invalid Date object, causing getTime() to return NaN and breaking the filtering logic.

Consider adding validation:

const startTime = new Date(occurrence.start_time);
if (isNaN(startTime.getTime())) {
  console.warn('Invalid start_time for occurrence:', occurrence.occurrence_id);
  continue;
}

Apply similar checks before date calculations to prevent silent failures.


85-132: Add error handling for invalid date strings.

Same issue as todayMeetings: the upcomingMeetings computation needs validation for date strings to prevent NaN-related bugs when API returns malformed dates.


14-18: Consider extracting synthetic occurrence creation to a helper method.

The synthetic MeetingOccurrence object is created identically in two places (lines 68-74 and 117-123). This duplication could lead to maintenance issues if the structure needs to change.

Consider extracting to a helper:

private createSyntheticOccurrence(meeting: Meeting): MeetingOccurrence {
  return {
    occurrence_id: '',
    title: meeting.title,
    description: meeting.description,
    start_time: meeting.start_time,
    duration: meeting.duration,
  };
}

Then use: occurrence: this.createSyntheticOccurrence(meeting)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c11c8fe and c245f33.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts (1 hunks)
  • packages/shared/src/interfaces/components.interface.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.ts
🧰 Additional context used
📓 Path-based instructions (5)
apps/lfx-one/src/**/*.html

📄 CodeRabbit inference engine (CLAUDE.md)

apps/lfx-one/src/**/*.html: Always add data-testid attributes when creating new Angular components for reliable test targeting
Use data-testid naming convention [section]-[component]-[element]

Files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.html
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
  • packages/shared/src/interfaces/components.interface.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.html
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts
packages/shared/src/interfaces/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place all TypeScript interfaces in the shared package at packages/shared/src/interfaces

Files:

  • packages/shared/src/interfaces/components.interface.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • packages/shared/src/interfaces/components.interface.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • packages/shared/src/interfaces/components.interface.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts
🧠 Learnings (2)
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to apps/lfx-one/src/**/*.html : Use data-testid naming convention [section]-[component]-[element]

Applied to files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to apps/lfx-one/src/**/*.html : Always add data-testid attributes when creating new Angular components for reliable test targeting

Applied to files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
🧬 Code graph analysis (2)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (2)
packages/shared/src/interfaces/meeting.interface.ts (2)
  • Meeting (75-148)
  • MeetingOccurrence (154-165)
apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts (1)
  • Component (15-143)
apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts (2)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.ts (1)
  • Component (20-141)
packages/shared/src/interfaces/meeting.interface.ts (2)
  • Meeting (75-148)
  • MeetingOccurrence (154-165)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: E2E Tests / Playwright E2E Tests
🔇 Additional comments (2)
apps/lfx-one/src/app/modules/pages/dashboard/components/recent-progress/recent-progress.component.html (1)

4-63: LGTM! data-testid naming convention properly applied.

All data-testid attributes now correctly follow the [section]-[component]-[element] pattern. The past review concerns have been addressed.

apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html (1)

4-64: data-testid attributes correctly follow naming convention.

All data-testid values properly implement the [section]-[component]-[element] pattern.

asithade and others added 2 commits October 22, 2025 18:29
- Remove LFX card wrapper from pending actions component
- Add consistent header with "View All" button to pending actions
- Simplify pending action button styling to white background with slate-100 hover
- Update dashboard meeting card to use project_name from meeting data
- Add project_name enrichment in meeting service
- Remove projectName input from dashboard meeting card component
- Add project_name field to Meeting interface

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>
- Replace card-based layout with lfx-table component
- Implement 4-column table structure (Project, Affiliations, Code Activities, Non-Code Activities)
- Apply React-style formatting:
  - Equal column widths (w-1/4 for each column)
  - Fixed chart container width (12.5rem)
  - Grey borders (border-gray-200) on table cells
  - Rounded table container with overflow handling
  - Blue project name links (#009aff)
  - Help icons for activity columns
- Update chart colors:
  - Code Activities: #009AFF (blue)
  - Non-Code Activities: #10b981 (green)
- Add generateLabels() helper method for dynamic chart labels
- Remove unused CardComponent import
- Maintain all existing test IDs for E2E compatibility

Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Asitha de Silva <[email protected]>
asithade
asithade previously approved these changes Oct 22, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts (2)

18-57: Plan for service integration in future iterations.

The component currently uses hardcoded placeholder data, which aligns with the WIP objectives. For production readiness, you'll need to:

  • Create a service (e.g., ProjectsService) to fetch user projects from the backend
  • Add loading states and error handling
  • Implement data refresh/polling if real-time updates are needed
  • Consider pagination if users may have many projects

This is expected for the current WIP phase but noting for future planning.


19-47: Add image error handler and consider dynamic logo loading to improve reliability.

While the template has a fallback UI for null/undefined logos (gray folder icon), it lacks an error handler for failed image requests. External URLs (GitHub avatars, Wikipedia, nodejs.org) remain vulnerable to downtime or broken links, which would render broken image icons rather than trigger the existing fallback.

Recommendations:

  • Add (error) event handler on the <img> tag to display the fallback when requests fail
  • Move logo URLs to a configuration service or backend API (avoids recompilation and centralizes management)
  • Consider hosting logos internally or via a reliable CDN for production deployments
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c245f33 and 29db102.

📒 Files selected for processing (9)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts (1 hunks)
  • apps/lfx-one/src/server/services/meeting.service.ts (5 hunks)
  • packages/shared/src/interfaces/meeting.interface.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.html
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.html
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.ts
  • apps/lfx-one/src/app/shared/components/dashboard-meeting-card/dashboard-meeting-card.component.html
🧰 Additional context used
📓 Path-based instructions (5)
packages/shared/src/interfaces/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place all TypeScript interfaces in the shared package at packages/shared/src/interfaces

Files:

  • packages/shared/src/interfaces/meeting.interface.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • packages/shared/src/interfaces/meeting.interface.ts
  • apps/lfx-one/src/server/services/meeting.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • packages/shared/src/interfaces/meeting.interface.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
  • apps/lfx-one/src/server/services/meeting.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • packages/shared/src/interfaces/meeting.interface.ts
  • apps/lfx-one/src/server/services/meeting.service.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts
  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts
apps/lfx-one/src/**/*.html

📄 CodeRabbit inference engine (CLAUDE.md)

apps/lfx-one/src/**/*.html: Always add data-testid attributes when creating new Angular components for reliable test targeting
Use data-testid naming convention [section]-[component]-[element]

Files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
🧠 Learnings (2)
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to apps/lfx-one/src/**/*.html : Use data-testid naming convention [section]-[component]-[element]

Applied to files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to apps/lfx-one/src/**/*.html : Always add data-testid attributes when creating new Angular components for reliable test targeting

Applied to files:

  • apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html
🧬 Code graph analysis (3)
apps/lfx-one/src/server/services/meeting.service.ts (2)
apps/lfx-one/src/server/services/project.service.ts (1)
  • ProjectService (19-584)
packages/shared/src/interfaces/meeting.interface.ts (1)
  • Meeting (75-150)
apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts (2)
apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts (1)
  • Component (10-17)
packages/shared/src/interfaces/components.interface.ts (1)
  • PendingActionItem (334-347)
apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts (2)
apps/lfx-one/src/app/modules/pages/dashboard/dashboard.component.ts (1)
  • Component (10-17)
packages/shared/src/interfaces/components.interface.ts (1)
  • ProjectItem (366-381)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: E2E Tests / Playwright E2E Tests
  • GitHub Check: build-and-push
🔇 Additional comments (7)
apps/lfx-one/src/app/modules/pages/dashboard/components/pending-actions/pending-actions.component.ts (3)

1-2: License header is correct.

The copyright and SPDX license identifier are properly included as required.


4-18: Component structure follows Angular best practices.

The standalone component setup, imports, and modern output() API usage are all correct. The PendingActionItem type is properly imported from shared interfaces.


20-53: Implementation is clean and appropriate for placeholder phase.

The hardcoded pendingActions data aligns with the PR objectives to establish foundational structure with placeholder content. The output emit methods are straightforward and type-safe. All data conforms to the PendingActionItem interface constraints.

apps/lfx-one/src/app/modules/pages/dashboard/components/my-meetings/my-meetings.component.html (1)

1-62: LGTM! Template structure and data-testid conventions are correct.

The template properly implements the My Meetings component with:

  • Correct data-testid naming following the [section]-[component]-[element] convention
  • Proper conditional rendering for Today/Upcoming sections
  • Clean empty state handling
  • Appropriate event bindings

The past review concerns about data-testid naming have been addressed in the current implementation.

packages/shared/src/interfaces/meeting.interface.ts (1)

148-149: LGTM! Field addition is properly documented and typed.

The project_name field is correctly added as a required response-only field, which aligns with the server-side enrichment that always provides a value (with empty string fallback when project lookup fails).

apps/lfx-one/src/app/modules/pages/dashboard/components/my-projects/my-projects.component.ts (2)

1-3: LGTM: License header is compliant.

The license header correctly follows the required format for Linux Foundation projects.


54-56: Verify the intent of returning empty string labels.

The generateLabels method returns an array of empty strings. While this may be intentional for sparkline-style charts that don't display x-axis labels, please confirm this is the desired behavior rather than a placeholder implementation.

If labels should eventually display meaningful text (e.g., dates, week numbers), this method will need to be updated.

Disabled automatic PR quality checks as project is moving away from old UI.
Changed trigger from pull_request to workflow_dispatch for manual runs only.

LFXV2-644

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>
@asithade asithade merged commit 3908f53 into main Oct 22, 2025
5 of 6 checks passed
@asithade asithade deleted the jme/LFXV2-644 branch October 22, 2025 11:49
@github-actions
Copy link

🧹 Deployment Removed

The deployment for PR #119 has been removed.

mauriciozanettisalomao pushed a commit that referenced this pull request Oct 24, 2025
…ion (#119)

* wip(dashboard): initial core persona developer dashboard implementation

Work in progress implementation for LFXV2-644. Adding foundational
components and structure for the Core Developer Persona dashboard.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* feat(dashboard): improve core developer persona dashboard UI

Reduce section header sizes from text-xl to text-lg for better visual hierarchy.
Enhance meetings section with modern card design, calendar icons, participant
badges, and Join buttons. Fix ESLint member ordering issues for LFXV2-644.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* fix(layout): prevent sidebar from floating during horizontal scroll

Change sidebar from fixed to sticky positioning within a flex container.
This ensures the sidebar stays in its designated column and doesn't cover
content during horizontal scrolling. Updates for LFXV2-644.

- Wrap sidebar in flex-shrink-0 container with fixed width
- Change sidebar positioning from fixed to sticky
- Remove margin-left from main content, use min-w-0 for proper scrolling
- Maintain sticky behavior for vertical scrolling within column

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* style(dashboard): further reduce section header sizes

Change section headers from text-lg to text-base for a more compact
and modern dashboard appearance. Reduces visual hierarchy emphasis
on section titles in favor of content focus for LFXV2-644.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* feat(dashboard): integrate meetings API with occurrence-based filtering

Replace hardcoded meeting data with live API integration that properly handles:
- Meeting occurrences for recurring meetings
- Time-based filtering with 40-minute buffer after meeting end
- Sorting by earliest time first
- Frontend limit to 5 meetings maximum
- Smart time formatting (Today/Tomorrow/Date)
- Total attendee count from registrants and committee members

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>

* feat(dashboard): implement persona-based dashboard architecture

- Replace home-new component with modular dashboard architecture
- Add persona-specific dashboard components (my-meetings, my-projects, pending-actions, recent-progress)
- Implement persona service with reactive persona selection
- Update sidebar with footer navigation support and improved styling
- Match sidebar border/shadow styling with PrimeNG card components
- Add persona selector component with dropdown interface
- Update header to integrate persona selector
- Add persona constants to shared package
- Update main layout to support dynamic persona-based routing
- Update profile layout to handle persona changes
- Server-side: Fix user profile persona field mapping

Technical improvements:
- Sidebar: Remove border, update border-radius to 12px, match card shadow
- Sidebar: Add footer items support with separate navigation section
- Sidebar: Improve accessibility with consistent text sizing (text-sm)
- Remove icon hover animations for visual consistency

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>

* refactor(sidebar): replace function calls with computed signals

- Remove getTestId() function calls from template
- Add testId property to SidebarMenuItem interface
- Create computed signals (itemsWithTestIds, footerItemsWithTestIds) for test ID generation
- Use Angular signals pattern for better performance and change detection

Performance improvements:
- Computed signals only recalculate when input changes
- Eliminates repeated function calls during template rendering
- Leverages Angular 19 zoneless change detection optimization

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>

* fix(dashboard): resolve pr comments

Signed-off-by: Asitha de Silva <[email protected]>

* fix(yarn): yarn.lock update

Signed-off-by: Asitha de Silva <[email protected]>

* feat(dashboard): implement dashboard meeting card component

- Create reusable DashboardMeetingCardComponent for displaying meeting information
- Update MyMeetingsComponent to use new card component with Today/Upcoming sections
- Add conditional section rendering (hide sections when empty)
- Match React component styling with white card background, gray icons, rounded-xl borders
- Implement smart date filtering for today's meetings vs upcoming meetings
- Add meeting feature icons (YouTube, Recording, Transcripts, AI, Public/Private)
- Add DashboardMeetingCardProps and DashboardMeetingFeatures interfaces to shared package
- Update RecentProgressComponent styling to match React design
- Remove PrimeNG Card dependency in favor of semantic HTML with Tailwind

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>

* refactor(dashboard): update pending actions and meeting card layout

- Remove LFX card wrapper from pending actions component
- Add consistent header with "View All" button to pending actions
- Simplify pending action button styling to white background with slate-100 hover
- Update dashboard meeting card to use project_name from meeting data
- Add project_name enrichment in meeting service
- Remove projectName input from dashboard meeting card component
- Add project_name field to Meeting interface

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>

* refactor(dashboard): update my-projects with table layout

- Replace card-based layout with lfx-table component
- Implement 4-column table structure (Project, Affiliations, Code Activities, Non-Code Activities)
- Apply React-style formatting:
  - Equal column widths (w-1/4 for each column)
  - Fixed chart container width (12.5rem)
  - Grey borders (border-gray-200) on table cells
  - Rounded table container with overflow handling
  - Blue project name links (#009aff)
  - Help icons for activity columns
- Update chart colors:
  - Code Activities: #009AFF (blue)
  - Non-Code Activities: #10b981 (green)
- Add generateLabels() helper method for dynamic chart labels
- Remove unused CardComponent import
- Maintain all existing test IDs for E2E compatibility

Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Asitha de Silva <[email protected]>

* ci(gha): disable automatic quality check workflow

Disabled automatic PR quality checks as project is moving away from old UI.
Changed trigger from pull_request to workflow_dispatch for manual runs only.

LFXV2-644

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>

---------

Signed-off-by: Jordan Evans <[email protected]>
Signed-off-by: Asitha de Silva <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Asitha de Silva <[email protected]>
mauriciozanettisalomao pushed a commit that referenced this pull request Oct 24, 2025
…ion (#119)

* wip(dashboard): initial core persona developer dashboard implementation

Work in progress implementation for LFXV2-644. Adding foundational
components and structure for the Core Developer Persona dashboard.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* feat(dashboard): improve core developer persona dashboard UI

Reduce section header sizes from text-xl to text-lg for better visual hierarchy.
Enhance meetings section with modern card design, calendar icons, participant
badges, and Join buttons. Fix ESLint member ordering issues for LFXV2-644.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* fix(layout): prevent sidebar from floating during horizontal scroll

Change sidebar from fixed to sticky positioning within a flex container.
This ensures the sidebar stays in its designated column and doesn't cover
content during horizontal scrolling. Updates for LFXV2-644.

- Wrap sidebar in flex-shrink-0 container with fixed width
- Change sidebar positioning from fixed to sticky
- Remove margin-left from main content, use min-w-0 for proper scrolling
- Maintain sticky behavior for vertical scrolling within column

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* style(dashboard): further reduce section header sizes

Change section headers from text-lg to text-base for a more compact
and modern dashboard appearance. Reduces visual hierarchy emphasis
on section titles in favor of content focus for LFXV2-644.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* feat(dashboard): integrate meetings API with occurrence-based filtering

Replace hardcoded meeting data with live API integration that properly handles:
- Meeting occurrences for recurring meetings
- Time-based filtering with 40-minute buffer after meeting end
- Sorting by earliest time first
- Frontend limit to 5 meetings maximum
- Smart time formatting (Today/Tomorrow/Date)
- Total attendee count from registrants and committee members

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>

* feat(dashboard): implement persona-based dashboard architecture

- Replace home-new component with modular dashboard architecture
- Add persona-specific dashboard components (my-meetings, my-projects, pending-actions, recent-progress)
- Implement persona service with reactive persona selection
- Update sidebar with footer navigation support and improved styling
- Match sidebar border/shadow styling with PrimeNG card components
- Add persona selector component with dropdown interface
- Update header to integrate persona selector
- Add persona constants to shared package
- Update main layout to support dynamic persona-based routing
- Update profile layout to handle persona changes
- Server-side: Fix user profile persona field mapping

Technical improvements:
- Sidebar: Remove border, update border-radius to 12px, match card shadow
- Sidebar: Add footer items support with separate navigation section
- Sidebar: Improve accessibility with consistent text sizing (text-sm)
- Remove icon hover animations for visual consistency

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>

* refactor(sidebar): replace function calls with computed signals

- Remove getTestId() function calls from template
- Add testId property to SidebarMenuItem interface
- Create computed signals (itemsWithTestIds, footerItemsWithTestIds) for test ID generation
- Use Angular signals pattern for better performance and change detection

Performance improvements:
- Computed signals only recalculate when input changes
- Eliminates repeated function calls during template rendering
- Leverages Angular 19 zoneless change detection optimization

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>

* fix(dashboard): resolve pr comments

Signed-off-by: Asitha de Silva <[email protected]>

* fix(yarn): yarn.lock update

Signed-off-by: Asitha de Silva <[email protected]>

* feat(dashboard): implement dashboard meeting card component

- Create reusable DashboardMeetingCardComponent for displaying meeting information
- Update MyMeetingsComponent to use new card component with Today/Upcoming sections
- Add conditional section rendering (hide sections when empty)
- Match React component styling with white card background, gray icons, rounded-xl borders
- Implement smart date filtering for today's meetings vs upcoming meetings
- Add meeting feature icons (YouTube, Recording, Transcripts, AI, Public/Private)
- Add DashboardMeetingCardProps and DashboardMeetingFeatures interfaces to shared package
- Update RecentProgressComponent styling to match React design
- Remove PrimeNG Card dependency in favor of semantic HTML with Tailwind

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>

* refactor(dashboard): update pending actions and meeting card layout

- Remove LFX card wrapper from pending actions component
- Add consistent header with "View All" button to pending actions
- Simplify pending action button styling to white background with slate-100 hover
- Update dashboard meeting card to use project_name from meeting data
- Add project_name enrichment in meeting service
- Remove projectName input from dashboard meeting card component
- Add project_name field to Meeting interface

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>

* refactor(dashboard): update my-projects with table layout

- Replace card-based layout with lfx-table component
- Implement 4-column table structure (Project, Affiliations, Code Activities, Non-Code Activities)
- Apply React-style formatting:
  - Equal column widths (w-1/4 for each column)
  - Fixed chart container width (12.5rem)
  - Grey borders (border-gray-200) on table cells
  - Rounded table container with overflow handling
  - Blue project name links (#009aff)
  - Help icons for activity columns
- Update chart colors:
  - Code Activities: #009AFF (blue)
  - Non-Code Activities: #10b981 (green)
- Add generateLabels() helper method for dynamic chart labels
- Remove unused CardComponent import
- Maintain all existing test IDs for E2E compatibility

Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Asitha de Silva <[email protected]>

* ci(gha): disable automatic quality check workflow

Disabled automatic PR quality checks as project is moving away from old UI.
Changed trigger from pull_request to workflow_dispatch for manual runs only.

LFXV2-644

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>

---------

Signed-off-by: Jordan Evans <[email protected]>
Signed-off-by: Asitha de Silva <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Asitha de Silva <[email protected]>
mauriciozanettisalomao pushed a commit that referenced this pull request Oct 24, 2025
…ion (#119)

* wip(dashboard): initial core persona developer dashboard implementation

Work in progress implementation for LFXV2-644. Adding foundational
components and structure for the Core Developer Persona dashboard.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* feat(dashboard): improve core developer persona dashboard UI

Reduce section header sizes from text-xl to text-lg for better visual hierarchy.
Enhance meetings section with modern card design, calendar icons, participant
badges, and Join buttons. Fix ESLint member ordering issues for LFXV2-644.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* fix(layout): prevent sidebar from floating during horizontal scroll

Change sidebar from fixed to sticky positioning within a flex container.
This ensures the sidebar stays in its designated column and doesn't cover
content during horizontal scrolling. Updates for LFXV2-644.

- Wrap sidebar in flex-shrink-0 container with fixed width
- Change sidebar positioning from fixed to sticky
- Remove margin-left from main content, use min-w-0 for proper scrolling
- Maintain sticky behavior for vertical scrolling within column

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* style(dashboard): further reduce section header sizes

Change section headers from text-lg to text-base for a more compact
and modern dashboard appearance. Reduces visual hierarchy emphasis
on section titles in favor of content focus for LFXV2-644.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Jordan Evans <[email protected]>

* feat(dashboard): integrate meetings API with occurrence-based filtering

Replace hardcoded meeting data with live API integration that properly handles:
- Meeting occurrences for recurring meetings
- Time-based filtering with 40-minute buffer after meeting end
- Sorting by earliest time first
- Frontend limit to 5 meetings maximum
- Smart time formatting (Today/Tomorrow/Date)
- Total attendee count from registrants and committee members

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>

* feat(dashboard): implement persona-based dashboard architecture

- Replace home-new component with modular dashboard architecture
- Add persona-specific dashboard components (my-meetings, my-projects, pending-actions, recent-progress)
- Implement persona service with reactive persona selection
- Update sidebar with footer navigation support and improved styling
- Match sidebar border/shadow styling with PrimeNG card components
- Add persona selector component with dropdown interface
- Update header to integrate persona selector
- Add persona constants to shared package
- Update main layout to support dynamic persona-based routing
- Update profile layout to handle persona changes
- Server-side: Fix user profile persona field mapping

Technical improvements:
- Sidebar: Remove border, update border-radius to 12px, match card shadow
- Sidebar: Add footer items support with separate navigation section
- Sidebar: Improve accessibility with consistent text sizing (text-sm)
- Remove icon hover animations for visual consistency

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>

* refactor(sidebar): replace function calls with computed signals

- Remove getTestId() function calls from template
- Add testId property to SidebarMenuItem interface
- Create computed signals (itemsWithTestIds, footerItemsWithTestIds) for test ID generation
- Use Angular signals pattern for better performance and change detection

Performance improvements:
- Computed signals only recalculate when input changes
- Eliminates repeated function calls during template rendering
- Leverages Angular 19 zoneless change detection optimization

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>

* fix(dashboard): resolve pr comments

Signed-off-by: Asitha de Silva <[email protected]>

* fix(yarn): yarn.lock update

Signed-off-by: Asitha de Silva <[email protected]>

* feat(dashboard): implement dashboard meeting card component

- Create reusable DashboardMeetingCardComponent for displaying meeting information
- Update MyMeetingsComponent to use new card component with Today/Upcoming sections
- Add conditional section rendering (hide sections when empty)
- Match React component styling with white card background, gray icons, rounded-xl borders
- Implement smart date filtering for today's meetings vs upcoming meetings
- Add meeting feature icons (YouTube, Recording, Transcripts, AI, Public/Private)
- Add DashboardMeetingCardProps and DashboardMeetingFeatures interfaces to shared package
- Update RecentProgressComponent styling to match React design
- Remove PrimeNG Card dependency in favor of semantic HTML with Tailwind

LFXV2-644

Signed-off-by: Asitha de Silva <[email protected]>

* refactor(dashboard): update pending actions and meeting card layout

- Remove LFX card wrapper from pending actions component
- Add consistent header with "View All" button to pending actions
- Simplify pending action button styling to white background with slate-100 hover
- Update dashboard meeting card to use project_name from meeting data
- Add project_name enrichment in meeting service
- Remove projectName input from dashboard meeting card component
- Add project_name field to Meeting interface

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>

* refactor(dashboard): update my-projects with table layout

- Replace card-based layout with lfx-table component
- Implement 4-column table structure (Project, Affiliations, Code Activities, Non-Code Activities)
- Apply React-style formatting:
  - Equal column widths (w-1/4 for each column)
  - Fixed chart container width (12.5rem)
  - Grey borders (border-gray-200) on table cells
  - Rounded table container with overflow handling
  - Blue project name links (#009aff)
  - Help icons for activity columns
- Update chart colors:
  - Code Activities: #009AFF (blue)
  - Non-Code Activities: #10b981 (green)
- Add generateLabels() helper method for dynamic chart labels
- Remove unused CardComponent import
- Maintain all existing test IDs for E2E compatibility

Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Asitha de Silva <[email protected]>

* ci(gha): disable automatic quality check workflow

Disabled automatic PR quality checks as project is moving away from old UI.
Changed trigger from pull_request to workflow_dispatch for manual runs only.

LFXV2-644

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>

---------

Signed-off-by: Jordan Evans <[email protected]>
Signed-off-by: Asitha de Silva <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Asitha de Silva <[email protected]>
Signed-off-by: Mauricio Zanetti Salomao <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants