Skip to content

Commit 3cabfdf

Browse files
asithademauriciozanettisalomao
authored andcommitted
feat(ui): comprehensive ui improvements and persona system enhancement (#128)
Multiple enhancements across the application: - LFXV2-670: Relocate footer to main layout for consistency - LFXV2-671: Replace "old-ui" with "home" persona and simplify routing - LFXV2-672: Add scrollable containers and refactor dashboard charts - LFXV2-673: Add meeting attachments display with file type icons - LFXV2-674: Enhance meeting join with password support and new tab - LFXV2-675: Improve error handling and null safety across services Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Asitha de Silva <[email protected]>
1 parent b110d51 commit 3cabfdf

24 files changed

+192
-157
lines changed

apps/lfx-one/src/app/app.component.html

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,3 @@
88
<div class="top-20">
99
<router-outlet />
1010
</div>
11-
12-
<!-- Footer Component -->
13-
<lfx-footer class="py-8"></lfx-footer>

apps/lfx-one/src/app/app.component.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: MIT
33

44
import { CommonModule } from '@angular/common';
5-
import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, makeStateKey, REQUEST_CONTEXT, TransferState } from '@angular/core';
5+
import { Component, inject, makeStateKey, REQUEST_CONTEXT, TransferState } from '@angular/core';
66
import { RouterOutlet } from '@angular/router';
77
import { AuthContext } from '@lfx-one/shared/interfaces';
88
import { ToastModule } from 'primeng/toast';
@@ -16,7 +16,6 @@ import { UserService } from './shared/services/user.service';
1616
imports: [RouterOutlet, HeaderComponent, CommonModule, ToastModule],
1717
templateUrl: './app.component.html',
1818
styleUrl: './app.component.scss',
19-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
2019
})
2120
export class AppComponent {
2221
private readonly userService = inject(UserService);

apps/lfx-one/src/app/app.routes.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ export const routes: Routes = [
2121
},
2222
],
2323
},
24-
// Old UI route - shows when "Old UI" persona is selected
25-
{
26-
path: 'old-ui',
27-
canActivate: [authGuard],
28-
loadComponent: () => import('./modules/pages/home/home.component').then((m) => m.HomeComponent),
29-
},
3024
{
3125
path: 'meetings',
3226
loadChildren: () => import('./modules/meeting/meeting.routes').then((m) => m.MEETING_ROUTES),

apps/lfx-one/src/app/layouts/main-layout/main-layout.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,7 @@ <h2 class="text-lg font-semibold text-gray-900">Menu</h2>
3232
<!-- Main Content Area -->
3333
<main class="flex-1 min-w-0 transition-all duration-300 lg:ml-72" data-testid="main-content">
3434
<router-outlet />
35+
<!-- Footer Component -->
36+
<lfx-footer class="py-8"></lfx-footer>
3537
</main>
3638
</div>

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: MIT
33

44
import { CommonModule } from '@angular/common';
5-
import { Component, inject } from '@angular/core';
5+
import { Component, CUSTOM_ELEMENTS_SCHEMA, inject } from '@angular/core';
66
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
77
import { NavigationEnd, Router, RouterModule } from '@angular/router';
88
import { AppService } from '@app/shared/services/app.service';
@@ -16,6 +16,7 @@ import { filter } from 'rxjs';
1616
imports: [CommonModule, RouterModule, SidebarComponent],
1717
templateUrl: './main-layout.component.html',
1818
styleUrl: './main-layout.component.scss',
19+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
1920
})
2021
export class MainLayoutComponent {
2122
private readonly router = inject(Router);

apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ <h2 class="font-display font-semibold text-gray-900">My Meetings</h2>
1717
</div>
1818

1919
<!-- Scrollable Content -->
20-
<div class="flex flex-col flex-1">
20+
<div class="flex flex-col flex-1 max-h-[28.125rem] overflow-y-auto">
2121
<div class="flex flex-col gap-6" data-testid="dashboard-my-meetings-list">
2222
@if (todayMeetings().length > 0 || upcomingMeetings().length > 0) {
2323
<!-- TODAY Section - only show if there are meetings today -->

apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.html

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -57,66 +57,14 @@ <h2 class="font-display font-semibold text-[16px]">My Projects</h2>
5757
<!-- Code Activities Chart -->
5858
<td class="py-2 px-3 border-t border-gray-200">
5959
<div class="h-12 w-[12.5rem]">
60-
<lfx-chart
61-
type="line"
62-
[data]="{
63-
labels: generateLabels(project.codeActivities.length),
64-
datasets: [
65-
{
66-
data: project.codeActivities,
67-
borderColor: '#009AFF',
68-
backgroundColor: 'rgba(0, 154, 255, 0.1)',
69-
fill: true,
70-
tension: 0.4,
71-
borderWidth: 2,
72-
pointRadius: 0,
73-
},
74-
],
75-
}"
76-
[options]="{
77-
responsive: true,
78-
maintainAspectRatio: false,
79-
plugins: { legend: { display: false }, tooltip: { enabled: false } },
80-
scales: {
81-
x: { display: false },
82-
y: { display: false },
83-
},
84-
}"
85-
height="100%">
86-
</lfx-chart>
60+
<lfx-chart type="line" [data]="project.codeActivitiesChartData" [options]="chartOptions" height="100%"></lfx-chart>
8761
</div>
8862
</td>
8963

9064
<!-- Non-Code Activities Chart -->
9165
<td class="py-2 px-3 border-t border-gray-200">
9266
<div class="h-12 w-[12.5rem]">
93-
<lfx-chart
94-
type="line"
95-
[data]="{
96-
labels: generateLabels(project.nonCodeActivities.length),
97-
datasets: [
98-
{
99-
data: project.nonCodeActivities,
100-
borderColor: '#10b981',
101-
backgroundColor: 'rgba(16, 185, 129, 0.1)',
102-
fill: true,
103-
tension: 0.4,
104-
borderWidth: 2,
105-
pointRadius: 0,
106-
},
107-
],
108-
}"
109-
[options]="{
110-
responsive: true,
111-
maintainAspectRatio: false,
112-
plugins: { legend: { display: false }, tooltip: { enabled: false } },
113-
scales: {
114-
x: { display: false },
115-
y: { display: false },
116-
},
117-
}"
118-
height="100%">
119-
</lfx-chart>
67+
<lfx-chart type="line" [data]="project.nonCodeActivitiesChartData" [options]="chartOptions" height="100%"></lfx-chart>
12068
</div>
12169
</td>
12270
</tr>

apps/lfx-one/src/app/modules/dashboards/components/my-projects/my-projects.component.ts

Lines changed: 95 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,17 @@ import { Component } from '@angular/core';
66
import { ChartComponent } from '@components/chart/chart.component';
77
import { TableComponent } from '@components/table/table.component';
88

9+
import type { ChartData, ChartOptions } from 'chart.js';
910
import type { ProjectItem } from '@lfx-one/shared/interfaces';
1011

12+
/**
13+
* Extended project item with pre-generated chart data
14+
*/
15+
interface ProjectItemWithCharts extends ProjectItem {
16+
codeActivitiesChartData: ChartData<'line'>;
17+
nonCodeActivitiesChartData: ChartData<'line'>;
18+
}
19+
1120
@Component({
1221
selector: 'lfx-my-projects',
1322
standalone: true,
@@ -16,42 +25,96 @@ import type { ProjectItem } from '@lfx-one/shared/interfaces';
1625
styleUrl: './my-projects.component.scss',
1726
})
1827
export class MyProjectsComponent {
19-
protected readonly projects: ProjectItem[] = [
20-
{
21-
name: 'Kubernetes',
22-
logo: 'https://avatars.githubusercontent.com/u/13455738?s=280&v=4',
23-
role: 'Maintainer',
24-
affiliations: ['CNCF', 'Google'],
25-
codeActivities: [28, 32, 30, 35, 38, 40, 42],
26-
nonCodeActivities: [8, 10, 12, 11, 13, 14, 15],
27-
status: 'active',
28-
},
29-
{
30-
name: 'Linux Kernel',
31-
logo: 'https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg',
32-
role: 'Contributor',
33-
affiliations: ['Linux Foundation'],
34-
codeActivities: [15, 18, 20, 22, 24, 26, 28],
35-
nonCodeActivities: [3, 4, 5, 6, 7, 7, 8],
36-
status: 'active',
37-
},
38-
{
39-
name: 'Node.js',
40-
logo: 'https://nodejs.org/static/logos/nodejsHex.svg',
41-
role: 'Reviewer',
42-
affiliations: ['OpenJS Foundation'],
43-
codeActivities: [18, 16, 15, 14, 13, 12, 12],
44-
nonCodeActivities: [8, 7, 6, 6, 5, 5, 5],
45-
status: 'archived',
28+
/**
29+
* Chart options for activity charts
30+
*/
31+
protected readonly chartOptions: ChartOptions<'line'> = {
32+
responsive: true,
33+
maintainAspectRatio: false,
34+
plugins: { legend: { display: false }, tooltip: { enabled: false } },
35+
scales: {
36+
x: { display: false },
37+
y: { display: false },
4638
},
47-
];
39+
};
40+
41+
/**
42+
* Projects with pre-generated chart data
43+
*/
44+
protected readonly projects: ProjectItemWithCharts[];
45+
46+
public constructor() {
47+
// Initialize projects with randomized chart data
48+
const baseProjects: ProjectItem[] = [
49+
{
50+
name: 'Kubernetes',
51+
logo: 'https://avatars.githubusercontent.com/u/13455738?s=280&v=4',
52+
role: 'Maintainer',
53+
affiliations: ['CNCF', 'Google'],
54+
codeActivities: this.generateRandomData(7, 25, 45),
55+
nonCodeActivities: this.generateRandomData(7, 8, 16),
56+
status: 'active',
57+
},
58+
{
59+
name: 'Linux Kernel',
60+
logo: 'https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg',
61+
role: 'Contributor',
62+
affiliations: ['Linux Foundation'],
63+
codeActivities: this.generateRandomData(7, 12, 30),
64+
nonCodeActivities: this.generateRandomData(7, 3, 9),
65+
status: 'active',
66+
},
67+
{
68+
name: 'Node.js',
69+
logo: 'https://nodejs.org/static/logos/nodejsHex.svg',
70+
role: 'Reviewer',
71+
affiliations: ['OpenJS Foundation'],
72+
codeActivities: this.generateRandomData(7, 10, 20),
73+
nonCodeActivities: this.generateRandomData(7, 4, 10),
74+
status: 'archived',
75+
},
76+
];
77+
78+
// Generate chart data for each project
79+
this.projects = baseProjects.map((project) => ({
80+
...project,
81+
codeActivitiesChartData: this.createChartData(project.codeActivities, '#009AFF', 'rgba(0, 154, 255, 0.1)'),
82+
nonCodeActivitiesChartData: this.createChartData(project.nonCodeActivities, '#10b981', 'rgba(16, 185, 129, 0.1)'),
83+
}));
84+
}
4885

4986
/**
50-
* Generates labels for chart based on data length
87+
* Generates random data array
5188
* @param length - Number of data points
52-
* @returns Array of empty strings for chart labels
89+
* @param min - Minimum value
90+
* @param max - Maximum value
91+
* @returns Array of random numbers
92+
*/
93+
private generateRandomData(length: number, min: number, max: number): number[] {
94+
return Array.from({ length }, () => Math.floor(Math.random() * (max - min + 1)) + min);
95+
}
96+
97+
/**
98+
* Creates chart data configuration
99+
* @param data - Array of values
100+
* @param borderColor - Chart border color
101+
* @param backgroundColor - Chart background color
102+
* @returns Chart.js data configuration
53103
*/
54-
protected generateLabels(length: number): string[] {
55-
return Array.from({ length }, () => '');
104+
private createChartData(data: number[], borderColor: string, backgroundColor: string): ChartData<'line'> {
105+
return {
106+
labels: Array.from({ length: data.length }, () => ''),
107+
datasets: [
108+
{
109+
data,
110+
borderColor,
111+
backgroundColor,
112+
fill: true,
113+
tension: 0.4,
114+
borderWidth: 2,
115+
pointRadius: 0,
116+
},
117+
],
118+
};
56119
}
57120
}

apps/lfx-one/src/app/modules/dashboards/components/pending-actions/pending-actions.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ <h2 class="font-display font-semibold text-gray-900">Pending Actions</h2>
1717
</div>
1818

1919
<!-- Scrollable Content -->
20-
<div class="flex flex-col flex-1">
20+
<div class="flex flex-col flex-1 max-h-[28.125rem] overflow-y-auto">
2121
<div class="flex flex-col gap-3" data-testid="dashboard-pending-actions-list">
2222
@for (item of pendingActions(); track item.text) {
2323
<div

apps/lfx-one/src/app/modules/dashboards/dashboard.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
@case ('maintainer') {
99
<lfx-maintainer-dashboard />
1010
}
11-
@default {
12-
<lfx-core-developer-dashboard />
11+
@case ('projects') {
12+
<lfx-home />
1313
}
1414
}

0 commit comments

Comments
 (0)