From b40a6a952b7fceeeab84c6dadcaf2fb97c6294da Mon Sep 17 00:00:00 2001 From: Amal Shaji Date: Sun, 18 Aug 2024 17:57:24 +0530 Subject: [PATCH] fix remove user from team (#87) * update base style * small style updates * control delete modal manually * add spacing for password copy button * delete user if not part of any team --- admin/apis/v1/team.py | 22 +++++++-- admin/tests/api_tests/test_team.py | 3 +- admin/web/src/app.pcss | 49 ++++++++++++------- .../src/lib/components/ConnectionType.svelte | 4 +- .../src/lib/components/users/delete.svelte | 6 ++- .../lib/components/users/invite-user.svelte | 2 +- .../lib/components/users/user-email.svelte | 2 +- 7 files changed, 57 insertions(+), 31 deletions(-) diff --git a/admin/apis/v1/team.py b/admin/apis/v1/team.py index 3b98190e..165da5d8 100644 --- a/admin/apis/v1/team.py +++ b/admin/apis/v1/team.py @@ -10,7 +10,7 @@ from schemas.user import AddUserToTeamResponseSchema, TeamUserSchemaForTeam from services import team as team_service from utils.exception import PermissionDenied - +from tortoise.transactions import in_transaction api = APIRouter(prefix="/team", tags=["team"]) @@ -58,15 +58,15 @@ async def add_user( } -@api.delete("/users/{user_id}") +@api.delete("/users/{team_user_id}") async def remove_user( - user_id: int, + team_user_id: int, team_user: TeamUser = Depends(security.requires_admin), ): team_user_to_delete = ( await TeamUser.filter() .select_related("user") - .get_or_none(id=user_id, team=team_user.team) + .get_or_none(id=team_user_id, team=team_user.team) ) if team_user_to_delete is None: raise PermissionDenied("User not found in team") @@ -74,6 +74,18 @@ async def remove_user( if team_user_to_delete.user.is_superuser and not team_user.user.is_superuser: raise PermissionDenied("Only superuser can remove superuser from team") - await TeamUser.filter(id=user_id).delete() + async with in_transaction() as connection: + await TeamUser.filter(id=team_user_id).using_db(connection).delete() + + if ( + not await TeamUser.filter(user=team_user_to_delete.user) + .using_db(connection) + .exists() + ): + await ( + User.filter(id=team_user_to_delete.user.id) + .using_db(connection) + .delete() + ) return {"status": "ok"} diff --git a/admin/tests/api_tests/test_team.py b/admin/tests/api_tests/test_team.py index 67464957..e47ff783 100644 --- a/admin/tests/api_tests/test_team.py +++ b/admin/tests/api_tests/test_team.py @@ -1,4 +1,4 @@ -from models.user import TeamUser +from models.user import TeamUser, User from tests import TestClient from tortoise.contrib import test @@ -39,6 +39,7 @@ async def test_remove_team_user(self): ) assert resp.status_code == 200 assert await TeamUser.filter(id=team_user_to_delete.id).first() is None + assert await User.filter(id=team_user_to_delete.user.id).first() is None async def test_remove_superuserteam_user_by_admin_user(self): team_user_to_delete = await TeamUserFactory.create( diff --git a/admin/web/src/app.pcss b/admin/web/src/app.pcss index d717d324..30a56b30 100644 --- a/admin/web/src/app.pcss +++ b/admin/web/src/app.pcss @@ -5,26 +5,32 @@ @layer base { :root { --background: 0 0% 100%; - --foreground: 0 0% 3.9%; + --foreground: 222.2 84% 4.9%; --card: 0 0% 100%; - --card-foreground: 0 0% 3.9%; + --card-foreground: 222.2 84% 4.9%; --popover: 0 0% 100%; - --popover-foreground: 0 0% 3.9%; - --primary: 0 0% 9%; - --primary-foreground: 0 0% 98%; - --secondary: 0 0% 96.1%; - --secondary-foreground: 0 0% 9%; - --muted: 0 0% 96.1%; - --muted-foreground: 0 0% 45.1%; - --accent: 0 0% 96.1%; - --accent-foreground: 0 0% 9%; - --destructive: 0 72.22% 50.59%; - --destructive-foreground: 0 0% 98%; - --border: 0 0% 89.8%; - --input: 0 0% 89.8%; - --ring: 0 0% 3.9%; - --radius: 0.3rem; + --popover-foreground: 222.2 84% 4.9%; + --primary: 221.2 83.2% 53.3%; + --primary-foreground: 210 40% 98%; + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 221.2 83.2% 53.3%; + --radius: 0.75rem; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; } + .dark { --background: 222.2 84% 4.9%; --foreground: 210 40% 98%; @@ -32,7 +38,7 @@ --card-foreground: 210 40% 98%; --popover: 222.2 84% 4.9%; --popover-foreground: 210 40% 98%; - --primary: 210 40% 98%; + --primary: 217.2 91.2% 59.8%; --primary-foreground: 222.2 47.4% 11.2%; --secondary: 217.2 32.6% 17.5%; --secondary-foreground: 210 40% 98%; @@ -44,6 +50,11 @@ --destructive-foreground: 210 40% 98%; --border: 217.2 32.6% 17.5%; --input: 217.2 32.6% 17.5%; - --ring: 212.7 26.8% 83.9%; + --ring: 224.3 76.3% 48%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; } } diff --git a/admin/web/src/lib/components/ConnectionType.svelte b/admin/web/src/lib/components/ConnectionType.svelte index 3d604578..ed512975 100644 --- a/admin/web/src/lib/components/ConnectionType.svelte +++ b/admin/web/src/lib/components/ConnectionType.svelte @@ -6,7 +6,7 @@ {#if type === "http"} - HTTP + HTTP {:else} - TCP + TCP {/if} diff --git a/admin/web/src/lib/components/users/delete.svelte b/admin/web/src/lib/components/users/delete.svelte index e8a5bb42..d558b7af 100644 --- a/admin/web/src/lib/components/users/delete.svelte +++ b/admin/web/src/lib/components/users/delete.svelte @@ -8,6 +8,7 @@ import { toast } from "svelte-sonner"; export let user: TeamUser; + let deleteOpen = false; const team = getContext("team") as string; @@ -25,6 +26,7 @@ if (response.ok) { users.update((users) => users.filter((u) => u.id !== user.id)); isLoading = false; + deleteOpen = false; toast.success("User removed from team"); } } catch (err) { @@ -40,8 +42,8 @@ ); - - + +