diff --git a/backend/app/seed.py b/backend/app/seed.py index fdd3c07..9a18e66 100644 --- a/backend/app/seed.py +++ b/backend/app/seed.py @@ -7,6 +7,7 @@ from sqlalchemy.orm import Session from .models import Project, Package, Artifact, Tag, Upload, PackageVersion, ArtifactDependency, Team, TeamMembership, User from .storage import get_storage +from .auth import hash_password logger = logging.getLogger(__name__) @@ -176,6 +177,53 @@ def seed_database(db: Session) -> None: logger.info(f"Created team: {demo_team.name} ({demo_team.slug})") + # Create test users with various roles + test_users = [ + {"username": "alice", "email": "alice@example.com", "role": "admin"}, + {"username": "bob", "email": "bob@example.com", "role": "admin"}, + {"username": "charlie", "email": "charlie@example.com", "role": "member"}, + {"username": "diana", "email": "diana@example.com", "role": "member"}, + {"username": "eve", "email": "eve@example.com", "role": "member"}, + {"username": "frank", "email": None, "role": "member"}, + ] + + for user_data in test_users: + # Check if user already exists + existing_user = db.query(User).filter(User.username == user_data["username"]).first() + if existing_user: + test_user = existing_user + else: + # Create the user with password same as username + test_user = User( + username=user_data["username"], + email=user_data["email"], + password_hash=hash_password(user_data["username"]), + is_admin=False, + is_active=True, + must_change_password=False, + ) + db.add(test_user) + db.flush() + logger.info(f"Created test user: {user_data['username']}") + + # Add to demo team with specified role + existing_membership = db.query(TeamMembership).filter( + TeamMembership.team_id == demo_team.id, + TeamMembership.user_id == test_user.id, + ).first() + + if not existing_membership: + membership = TeamMembership( + team_id=demo_team.id, + user_id=test_user.id, + role=user_data["role"], + invited_by=team_owner_username, + ) + db.add(membership) + logger.info(f"Added {user_data['username']} to {demo_team.slug} as {user_data['role']}") + + db.flush() + # Create projects and packages project_map = {} package_map = {} diff --git a/frontend/src/pages/TeamMembersPage.css b/frontend/src/pages/TeamMembersPage.css index 47987db..7d545b1 100644 --- a/frontend/src/pages/TeamMembersPage.css +++ b/frontend/src/pages/TeamMembersPage.css @@ -16,34 +16,11 @@ font-size: 1.75rem; } -/* Members list */ -.members-list { - display: flex; - flex-direction: column; - gap: 0.5rem; -} - -.member-card { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem; - background: var(--color-bg-secondary); - border: 1px solid var(--color-border); - border-radius: var(--radius-md); - gap: 1rem; -} - -.member-card.current-user { - background: var(--color-primary-bg); - border-color: var(--color-primary-border, var(--color-border)); -} - -.member-info { +/* Member cell in table */ +.member-cell { display: flex; align-items: center; gap: 0.75rem; - min-width: 0; } .member-avatar { @@ -87,11 +64,8 @@ white-space: nowrap; } -.member-actions { - display: flex; - align-items: center; - gap: 0.5rem; - flex-shrink: 0; +.text-muted { + color: var(--color-text-muted); } .role-select { diff --git a/frontend/src/pages/TeamMembersPage.tsx b/frontend/src/pages/TeamMembersPage.tsx index e92cd42..a03e880 100644 --- a/frontend/src/pages/TeamMembersPage.tsx +++ b/frontend/src/pages/TeamMembersPage.tsx @@ -11,6 +11,7 @@ import { import { useAuth } from '../contexts/AuthContext'; import { Badge } from '../components/Badge'; import { Breadcrumb } from '../components/Breadcrumb'; +import { DataTable } from '../components/DataTable'; import { UserAutocomplete } from '../components/UserAutocomplete'; import './TeamMembersPage.css'; @@ -201,34 +202,49 @@ function TeamMembersPage() { )} -