Skip to content

Commit

Permalink
#705 change test data to new structure
Browse files Browse the repository at this point in the history
+ load user in frontend on startup and set filters based on this user
  • Loading branch information
janikEndtner committed Dec 22, 2023
1 parent 75b4de3 commit 0e87836
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ch.puzzle.okr.dto.UserDto;
import ch.puzzle.okr.mapper.UserMapper;
import ch.puzzle.okr.service.authorization.AuthorizationService;
import ch.puzzle.okr.service.authorization.UserAuthorizationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
Expand All @@ -19,10 +20,16 @@
public class UserController {

private final UserAuthorizationService userAuthorizationService;
private final AuthorizationService authorizationService;
private final UserMapper userMapper;

public UserController(UserAuthorizationService userAuthorizationService, UserMapper userMapper) {
public UserController(
UserAuthorizationService userAuthorizationService,
AuthorizationService authorizationService,
UserMapper userMapper
) {
this.userAuthorizationService = userAuthorizationService;
this.authorizationService = authorizationService;
this.userMapper = userMapper;
}

Expand All @@ -34,4 +41,13 @@ public List<UserDto> getAllUsers() {
return userAuthorizationService.getAllUsers().stream().map(userMapper::toDto).toList();
}

@Operation(summary = "Get Current User", description = "Get all current logged in user.")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returned current logged in user.", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = UserDto.class)) }), })
@GetMapping(path = "/current")
public UserDto getCurrentUser() {
var currentUser = this.authorizationService.getAuthorizationUser().user();
return userMapper.toDto(currentUser);
}

}
2 changes: 1 addition & 1 deletion backend/src/main/java/ch/puzzle/okr/dto/UserTeamDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public record UserTeamDto(
Long id,
int version,
TeamDto teamDto,
TeamDto team,
boolean isTeamAdmin
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- add [email protected] as a user. we set it as champion in dev application properties
INSERT INTO person (id, email, firstname, lastname, version, is_okr_champion)
VALUES (61, '[email protected]', 'Jaya', 'Norris', 1, FALSE);

-- map existing users to teams
INSERT INTO person_team (id, version, person_id, team_id, is_team_admin)
-- [email protected]
VALUES (1, 1, 1, 4, TRUE),
(2, 1, 1, 5, FALSE),
-- [email protected]
(3, 1, 11, 6, FALSE),
-- [email protected]
(4, 1, 21, 8, FALSE),
-- [email protected]
(5, 1, 31, 8, TRUE),
-- egiman@puzzlech
(6, 1, 41, 4, FALSE),
-- [email protected]
(7, 1, 51, 6, TRUE),
-- [email protected]
(8, 1, 61, 5, TRUE),
(9, 1, 61, 6, FALSE);
17 changes: 16 additions & 1 deletion frontend/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { NgModule } from '@angular/core';
import { inject, NgModule } from '@angular/core';
import { ActivatedRouteSnapshot, ResolveFn, RouterModule, Routes } from '@angular/router';
import { OverviewComponent } from './overview/overview.component';
import { EMPTY, of } from 'rxjs';
import { SidepanelComponent } from './shared/custom/sidepanel/sidepanel.component';
import { authGuard } from './shared/guards/auth.guard';
import { UserService } from './shared/services/user.service';
import { User } from './shared/types/model/User';
import { OAuthService } from 'angular-oauth2-oidc';

/**
* Resolver for get the id from url like `/objective/42` or `/keyresult/42`.
Expand All @@ -18,10 +21,22 @@ export const getIdFromPathResolver: ResolveFn<number> = (route: ActivatedRouteSn
}
};

const currentUserResolver: ResolveFn<User | undefined> = () => {
const oauthService = inject(OAuthService);
const userService = inject(UserService);
if (oauthService.hasValidIdToken()) {
return userService.initCurrentUser();
}
return of(undefined);
};

const routes: Routes = [
{
path: '',
component: OverviewComponent,
resolve: {
user: currentUserResolver,
},
children: [
{
path: 'objective/:id',
Expand Down
22 changes: 20 additions & 2 deletions frontend/src/app/shared/services/user.service.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Observable, of, tap } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { User } from '../types/model/User';

@Injectable({
providedIn: 'root',
})
export class UserService {
private readonly API_URL = 'api/v1/users';

private _user: User | undefined;

constructor(private httpClient: HttpClient) {}

public initCurrentUser(): Observable<User> {
if (this._user) {
return of(this._user);
}
return this.httpClient.get<User>(this.API_URL + '/current').pipe(tap((u) => (this._user = u)));
}

public getUsers(): Observable<User[]> {
return this.httpClient.get<User[]>('api/v1/users');
return this.httpClient.get<User[]>(this.API_URL);
}

public getCurrentUser(): User {
if (!this._user) {
throw new Error('user should not be undefined here');
}
return this._user;
}
}
3 changes: 0 additions & 3 deletions frontend/src/app/shared/types/model/Team.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { Organisation } from './Organisation';

export interface Team {
id: number;
version: number;
name: string;
organisations: Organisation[];
filterIsActive: boolean;
}
10 changes: 10 additions & 0 deletions frontend/src/app/shared/types/model/User.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { UserTeam } from './UserTeam';

export interface User {
id: number;
firstname: string;
lastname: string;
email: string;
userTeamList: UserTeam[];
isOkrChampion: boolean;
isWriteable: boolean;
}

export const extractTeamsFromUser = (user: User) => {
return user.userTeamList.map((u) => u.team);
};
7 changes: 7 additions & 0 deletions frontend/src/app/shared/types/model/UserTeam.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {Team} from "./Team";

export interface UserTeam {
id: number;
team: Team;
isTeamAdmin: boolean;
}
5 changes: 4 additions & 1 deletion frontend/src/app/team-filter/team-filter.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { TeamService } from '../shared/services/team.service';
import { ActivatedRoute, Router } from '@angular/router';
import { areEqual, getValueFromQuery, optionalReplaceWithNulls, trackByFn } from '../shared/common';
import { RefreshDataService } from '../shared/services/refresh-data.service';
import { UserService } from '../shared/services/user.service';
import { extractTeamsFromUser } from '../shared/types/model/User';

@Component({
selector: 'app-team-filter',
Expand All @@ -21,6 +23,7 @@ export class TeamFilterComponent implements OnInit {
private route: ActivatedRoute,
private router: Router,
private refreshDataService: RefreshDataService,
private userService: UserService,
) {
this.refreshDataService.reloadOverviewSubject.subscribe(() => {
this.teamService.getAllTeams().subscribe((teams) => {
Expand All @@ -37,7 +40,7 @@ export class TeamFilterComponent implements OnInit {
const teamIds = getValueFromQuery(teamQuery);
const knownTeams = this.getAllTeamIds().filter((teamId) => teamIds?.includes(teamId));
if (knownTeams.length == 0) {
this.activeTeams = teams.filter((e) => e.filterIsActive).map((team) => team.id);
this.activeTeams = extractTeamsFromUser(this.userService.getCurrentUser()).map((team) => team.id);
} else {
this.activeTeams = knownTeams;
}
Expand Down

0 comments on commit 0e87836

Please sign in to comment.