Skip to content

Commit

Permalink
#705 member-list ui
Browse files Browse the repository at this point in the history
  • Loading branch information
janikEndtner committed Dec 28, 2023
1 parent 227db46 commit a043a06
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import "../style/variables";
.key-result {
background-color: $keyResult-bg;
border: 1px solid $keyResult-border;
background-color: $dark-grey;
border: 1px solid $dark-grey-border;
word-wrap: break-word;

&:hover {
Expand Down
14 changes: 12 additions & 2 deletions frontend/src/app/services/team.service.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Team } from '../shared/types/model/Team';
import { Observable } from 'rxjs';
import { Observable, of, take, tap } from 'rxjs';

@Injectable({
providedIn: 'root',
})
export class TeamService {
constructor(private http: HttpClient) {}

private teams: Team[] | undefined;

getAllTeams(): Observable<Team[]> {
return this.http.get<Team[]>('/api/v2/teams');
if (this.teams) {
return of(this.teams).pipe(take(1));
}
return this.http.get<Team[]>('/api/v2/teams').pipe(tap((teams) => (this.teams = teams)));
}

reloadTeams(): Observable<Team[]> {
this.teams = undefined;
return this.getAllTeams();
}

createTeam(team: Team): Observable<Team> {
Expand Down
13 changes: 11 additions & 2 deletions frontend/src/app/services/user.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { Observable, of, tap } from 'rxjs';
import { Observable, of, take, tap } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { User } from '../shared/types/model/User';

Expand All @@ -10,6 +10,7 @@ export class UserService {
private readonly API_URL = 'api/v1/users';

private _user: User | undefined;
private users: User[] | undefined;

constructor(private httpClient: HttpClient) {}

Expand All @@ -21,7 +22,15 @@ export class UserService {
}

public getUsers(): Observable<User[]> {
return this.httpClient.get<User[]>(this.API_URL);
if (this.users) {
return of(this.users).pipe(take(1));
}
return this.httpClient.get<User[]>(this.API_URL).pipe(tap((users) => (this.users = users)));
}

public reloadUsers(): Observable<User[]> {
this.users = undefined;
return this.getUsers();
}

public getCurrentUser(): User {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
<div>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<div id="member-header">
<div>
<h3 *ngIf="selectedTeam">{{ selectedTeam?.name }}</h3>
<h3 *ngIf="!selectedTeam">Alle Teams</h3>
<p>Members: {{ dataSource.length }}</p>
</div>
</div>

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 okr-table">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->

<!-- Position Column -->
<ng-container matColumnDef="icon">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<mat-icon>person_outline</mat-icon>
</td>
</ng-container>

<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let element">{{ element.firstname }} {{ element.lastname }}</td>
</ng-container>

<!-- Name Column -->
<ng-container matColumnDef="roles">
<th mat-header-cell *matHeaderCellDef>Rolle</th>
<td mat-cell *matCellDef="let element">{{ element.roles | roles }}</td>
</ng-container>

<!-- Weight Column -->
<ng-container matColumnDef="teams">
<th mat-header-cell *matHeaderCellDef>Teams</th>
<td mat-cell *matCellDef="let element" [title]="element.teams | teams: undefined">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
@import "../../../style/_variables.scss";

div {
width: 100%;

#member-header {
display: flex;
align-items: center;
background-color: $dark-grey;
width: 100%;
min-height: 57px;

div {
display: flex;
align-items: end;
h3 {
margin: 0 2rem 0 1rem;
}
p {
font-size: 0.75rem;
margin-bottom: 4px;
}
}
}

.mat-column-icon {
width: 50px;
}

.mat-column-name {
width: 30%;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { ActivatedRoute } from '@angular/router';
import { combineLatest, map, ReplaySubject, Subscription } from 'rxjs';
import { User } from '../../shared/types/model/User';
import { convertFromUsers, UserTableEntry } from '../../shared/types/model/UserTableEntry';
import { TeamService } from '../../services/team.service';
import { Team } from '../../shared/types/model/Team';

@Component({
selector: 'app-member-list',
Expand All @@ -12,26 +14,34 @@ import { convertFromUsers, UserTableEntry } from '../../shared/types/model/UserT
})
export class MemberListComponent implements OnInit, OnDestroy {
dataSource: UserTableEntry[] = [];
selectedTeam: Team | undefined;

private allUsersSubj: ReplaySubject<User[]> = new ReplaySubject<User[]>(1);

private subscription!: Subscription;
private allColumns = ['name', 'roles', 'teams'];
private teamColumns = ['name', 'roles'];
private allColumns = ['icon', 'name', 'roles', 'teams'];
private teamColumns = ['icon', 'name', 'roles'];

displayedColumns: string[] = this.allColumns;

public constructor(
private readonly userService: UserService,
private readonly route: ActivatedRoute,
private readonly cd: ChangeDetectorRef,
private readonly teamService: TeamService,
) {}

public ngOnInit(): void {
this.userService.getUsers().subscribe((users) => this.allUsersSubj.next(users));
const teamId$ = this.route.paramMap.pipe(map((params) => params.get('teamId')));
this.subscription = combineLatest([this.allUsersSubj.asObservable(), teamId$]).subscribe(([users, teamIdParam]) =>
this.setDataSource(users, teamIdParam),
);
this.subscription = combineLatest([
this.allUsersSubj.asObservable(),
teamId$,
this.teamService.getAllTeams(),
]).subscribe(([users, teamIdParam, teams]) => {
this.setDataSource(users, teamIdParam);
this.setSelectedTeam(teams, teamIdParam);
});
}

private setDataSource(users: User[], teamIdParam: string | null) {
Expand All @@ -50,4 +60,13 @@ export class MemberListComponent implements OnInit, OnDestroy {
public ngOnDestroy(): void {
this.subscription.unsubscribe();
}

private setSelectedTeam(teams: Team[], teamIdParam: string | null) {
if (!teamIdParam) {
this.selectedTeam = undefined;
return;
}
this.selectedTeam = teams.find((t) => t.id === parseInt(teamIdParam));
this.cd.markForCheck();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ div {
> mat-nav-list {
padding: 0;

background-color: $light-grey;

.selected {
background-color: $pz-dark-blue;

Expand Down
2 changes: 2 additions & 0 deletions frontend/src/app/team-management/team-management.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { MatListModule } from '@angular/material/list';
import { MatTableModule } from '@angular/material/table';
import { RolesPipe } from './roles.pipe';
import { TeamsPipe } from './teams.pipe';
import { MatIconModule } from '@angular/material/icon';

@NgModule({
declarations: [
Expand All @@ -36,6 +37,7 @@ import { TeamsPipe } from './teams.pipe';
NgOptimizedImage,
MatListModule,
MatTableModule,
MatIconModule,
],
})
export class TeamManagementModule {}
5 changes: 3 additions & 2 deletions frontend/src/style/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ $pz-dark-blue: #1e5a96;
$error: #ba3838;
$eggshell: #f6f7f8;

$keyResult-border: #5d6974;
$keyResult-bg: #e5e8eb;
$light-grey: #f8f8f8;
$dark-grey: #e5e8eb;
$dark-grey-border: #5d6974;

$top-bar-height: 48px;

Expand Down
21 changes: 21 additions & 0 deletions frontend/src/style/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,24 @@ mat-form-field.quarter-filter .mat-mdc-text-field-wrapper {
app-team-management-banner > #okrBanner {
position: relative;
}

table.okr-table {
border-collapse: separate;
border-spacing: 0 0.5rem;
border: none;
box-shadow: none;
tr {
height: 40px;

> td {
border: none;
background-color: $light-grey;
}
> th {
vertical-align: bottom;
font-size: 0.75rem;
border: none;
background-color: white;
}
}
}

0 comments on commit a043a06

Please sign in to comment.