From f4292d13f32bd0e69eee446822d4431d3f453128 Mon Sep 17 00:00:00 2001 From: Paula-Kli Date: Tue, 17 Oct 2023 11:51:09 +0200 Subject: [PATCH] feat: Add user profile page Users can now look at common projects with another user or have a look at their personal profile page. --- backend/capellacollab/projects/routes.py | 34 +++++++++++++++ backend/tests/users/test_users.py | 43 +++++++++++++++++++ frontend/src/app/app-routing.module.ts | 6 +++ frontend/src/app/app.module.ts | 2 + .../app/general/header/header.component.html | 10 ++++- .../project-user-settings.component.html | 8 +++- .../app/projects/service/project.service.ts | 9 ++++ .../src/app/services/user/user.service.ts | 4 ++ .../users-profile/users-profile.component.css | 4 ++ .../users-profile.component.html | 27 ++++++++++++ .../users-profile/users-profile.component.ts | 41 ++++++++++++++++++ 11 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 backend/tests/users/test_users.py create mode 100644 frontend/src/app/users/users-profile/users-profile.component.css create mode 100644 frontend/src/app/users/users-profile/users-profile.component.html create mode 100644 frontend/src/app/users/users-profile/users-profile.component.ts diff --git a/backend/capellacollab/projects/routes.py b/backend/capellacollab/projects/routes.py index 34f703d1ef..6ab63929ba 100644 --- a/backend/capellacollab/projects/routes.py +++ b/backend/capellacollab/projects/routes.py @@ -68,6 +68,40 @@ def get_projects( return projects +@router.get( + "/common/{user_id}", response_model=list[models.Project], tags=["Projects"] +) +def get_common_projects( + user_for_common_projects: users_models.DatabaseUser = fastapi.Depends( + users_injectables.get_existing_user + ), + user: users_models.DatabaseUser = fastapi.Depends( + users_injectables.get_own_user + ), + log: logging.LoggerAdapter = fastapi.Depends( + core_logging.get_request_logger + ), +) -> list[models.DatabaseProject]: + current_users_projects = [ + association.project + for association in user.projects + if not association.project.visibility == models.Visibility.INTERNAL + ] + projects_for_common = [ + association.project + for association in user_for_common_projects.projects + if not association.project.visibility == models.Visibility.INTERNAL + ] + + projects = [ + project + for project in current_users_projects + if project in projects_for_common + ] + log.info("Fetching the following projects: %s", projects) + return projects + + @router.patch( "/{project_slug}", response_model=models.Project, diff --git a/backend/tests/users/test_users.py b/backend/tests/users/test_users.py new file mode 100644 index 0000000000..1b8e577d2a --- /dev/null +++ b/backend/tests/users/test_users.py @@ -0,0 +1,43 @@ +# SPDX-FileCopyrightText: Copyright DB Netz AG and the capella-collab-manager contributors +# SPDX-License-Identifier: Apache-2.0 + +import pytest +from fastapi import testclient +from sqlalchemy import orm + +import capellacollab.projects.users.models as projects_users_models +from capellacollab.projects import models as projects_models +from capellacollab.projects.users import crud as projects_users_crud +from capellacollab.users import crud as users_crud +from capellacollab.users import models as users_models + + +@pytest.mark.usefixtures("user") +def test_get_no_common_projects( + client: testclient.TestClient, db: orm.Session +): + user2 = users_crud.create_user(db, "user2") + response = client.get(f"/api/v1/projects/common/{user2.id}") + assert response.status_code == 200 + assert len(response.json()) == 0 + + +@pytest.mark.usefixtures("project_user") +def test_get_common_projects( + client: testclient.TestClient, + db: orm.Session, + project: projects_models.DatabaseProject, +): + user2 = users_crud.create_user(db, "user2") + projects_users_crud.add_user_to_project( + db, + project, + user2, + role=projects_users_models.ProjectUserRole.USER, + permission=projects_users_models.ProjectUserPermission.WRITE, + ) + + response = client.get(f"/api/v1/projects/common/{user2.id}") + assert response.status_code == 200 + assert len(response.json()) == 1 + assert response.json()[0]["slug"] == project.slug diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 5dc705859d..fc3bbef665 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -14,6 +14,7 @@ import { EditProjectMetadataComponent } from 'src/app/projects/project-detail/ed import { SessionComponent } from 'src/app/sessions/session/session.component'; import { PipelinesOverviewComponent } from 'src/app/settings/core/pipelines-overview/pipelines-overview.component'; import { BasicAuthTokenComponent } from 'src/app/users/basic-auth-token/basic-auth-token.component'; +import { UsersProfileComponent } from 'src/app/users/users-profile/users-profile.component'; import { EventsComponent } from './events/events.component'; import { AuthComponent } from './general/auth/auth/auth.component'; import { AuthGuardService } from './general/auth/auth-guard/auth-guard.service'; @@ -442,6 +443,11 @@ const routes: Routes = [ data: { breadcrumb: 'Events' }, component: EventsComponent, }, + { + path: 'user', + data: { breadcrumb: (data: Data) => data?.user?.name || 'User' }, + component: UsersProfileComponent, + }, { path: 'tokens', data: { breadcrumb: 'Tokens' }, diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 8715ca6a66..bb194e57ee 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -136,6 +136,7 @@ import { T4CRepoDeletionDialogComponent } from './settings/modelsources/t4c-sett import { T4CSettingsWrapperComponent } from './settings/modelsources/t4c-settings/t4c-settings-wrapper/t4c-settings-wrapper.component'; import { T4CSettingsComponent } from './settings/modelsources/t4c-settings/t4c-settings.component'; import { SettingsComponent } from './settings/settings.component'; +import { UsersProfileComponent } from './users/users-profile/users-profile.component'; @NgModule({ declarations: [ @@ -223,6 +224,7 @@ import { SettingsComponent } from './settings/settings.component'; TriggerPipelineComponent, UserSessionsWrapperComponent, UserSettingsComponent, + UsersProfileComponent, VersionComponent, ViewLogsDialogComponent, ], diff --git a/frontend/src/app/general/header/header.component.html b/frontend/src/app/general/header/header.component.html index 9c18f0a11f..8aeca41840 100644 --- a/frontend/src/app/general/header/header.component.html +++ b/frontend/src/app/general/header/header.component.html @@ -48,6 +48,14 @@ + + Profile account_circle + - Profile account_circle + Menu menu diff --git a/frontend/src/app/projects/project-detail/project-users/project-user-settings.component.html b/frontend/src/app/projects/project-detail/project-users/project-user-settings.component.html index 2e6fc39a5f..0bf7e7b159 100644 --- a/frontend/src/app/projects/project-detail/project-users/project-user-settings.component.html +++ b/frontend/src/app/projects/project-detail/project-users/project-user-settings.component.html @@ -50,7 +50,11 @@

Project members

) " > -
- +