Add Teams #45

Merged
Typhus merged 6 commits from feature/add-teams into main 2026-02-15 00:16:55 +00:00
5 changed files with 190 additions and 10 deletions
Showing only changes of commit b34269cdb5 - Show all commits

View File

@ -12,13 +12,14 @@ from src.ezgg_lan_manager.services.MailingService import MailingService
from src.ezgg_lan_manager.services.NewsService import NewsService
from src.ezgg_lan_manager.services.ReceiptPrintingService import ReceiptPrintingService
from src.ezgg_lan_manager.services.SeatingService import SeatingService
from src.ezgg_lan_manager.services.TeamService import TeamService
from src.ezgg_lan_manager.services.TicketingService import TicketingService
from src.ezgg_lan_manager.services.TournamentService import TournamentService
from src.ezgg_lan_manager.services.UserService import UserService
from src.ezgg_lan_manager.types import *
# Inits services in the correct order
def init_services() -> tuple[AccountingService, CateringService, ConfigurationService, DatabaseService, MailingService, NewsService, SeatingService, TicketingService, UserService, LocalDataService, ReceiptPrintingService, TournamentService]:
def init_services() -> tuple[AccountingService, CateringService, ConfigurationService, DatabaseService, MailingService, NewsService, SeatingService, TicketingService, UserService, LocalDataService, ReceiptPrintingService, TournamentService, TeamService]:
logging.basicConfig(level=logging.DEBUG)
configuration_service = ConfigurationService(from_root("config.toml"))
db_service = DatabaseService(configuration_service.get_database_configuration())
@ -32,6 +33,7 @@ def init_services() -> tuple[AccountingService, CateringService, ConfigurationSe
catering_service = CateringService(db_service, accounting_service, user_service, receipt_printing_service)
local_data_service = LocalDataService()
tournament_service = TournamentService(db_service, user_service)
team_service = TeamService(db_service)
return accounting_service, catering_service, configuration_service, db_service, mailing_service, news_service, seating_service, ticketing_service, user_service, local_data_service, receipt_printing_service, tournament_service
return accounting_service, catering_service, configuration_service, db_service, mailing_service, news_service, seating_service, ticketing_service, user_service, local_data_service, receipt_printing_service, tournament_service, team_service

View File

@ -0,0 +1,43 @@
from functools import partial
from typing import Callable, Optional
from rio import Component, Revealer, TextStyle, Column, Row, Tooltip, Icon, Spacer, Text, Button
from src.ezgg_lan_manager.types.Team import TeamStatus, Team
from src.ezgg_lan_manager.types.User import User
class TeamRevealer(Component):
user: Optional[User]
team: Team
on_join_button_pressed: Callable
def build(self) -> Component:
return Revealer(
header=self.team.name,
header_style=TextStyle(
fill=self.session.theme.background_color,
font_size=1
),
content=Column(
*[Row(
Tooltip(
anchor=Icon("material/star" if self.team.members[member] == TeamStatus.LEADER else "material/stat_1", fill=self.session.theme.hud_color),
tip="Leiter" if self.team.members[member] == TeamStatus.LEADER else "Mitglied", position="top"),
Text(member.user_name, style=TextStyle(fill=self.session.theme.background_color, font_size=1), margin_left=0.5),
Spacer(grow_y=False))
for member in self.team.members
],
Row(Button(
content=f"{self.team.name} beitreten",
shape="rectangle",
style="major",
color="hud",
on_press=partial(self.on_join_button_pressed, self.team),
) if self.user not in self.team.members.keys() and self.user is not None else Spacer(grow_x=False, grow_y=False), margin_top=1, margin_bottom=1),
margin_right=1,
margin_left=1
),
margin_left=1,
margin_right=1,
)

View File

@ -1,17 +1,133 @@
from rio import Column, Component, event, Text
from typing import Optional
from rio import Column, Component, event, Text, TextStyle, ProgressCircle, Spacer, Revealer, Row, Button, Icon, Tooltip, Rectangle, PointerEventListener, PointerEvent
from src.ezgg_lan_manager import ConfigurationService
from src.ezgg_lan_manager.components.MainViewContentBox import MainViewContentBox
from src.ezgg_lan_manager.types.News import News
from src.ezgg_lan_manager.components.TeamRevealer import TeamRevealer
from src.ezgg_lan_manager.services.TeamService import TeamService
from src.ezgg_lan_manager.services.UserService import UserService
from src.ezgg_lan_manager.types.SessionStorage import SessionStorage
from src.ezgg_lan_manager.types.Team import Team
from src.ezgg_lan_manager.types.User import User
class TeamsPage(Component):
all_teams: Optional[list[Team]] = None
user: Optional[User] = None
user_teams: list[Team] = []
@event.on_populate
async def on_populate(self) -> None:
self.all_teams = await self.session[TeamService].get_all_teams()
#self.user = await self.session[UserService].get_user(self.session[SessionStorage].user_id)
self.user = await self.session[UserService].get_user("Typhus") # FixMe: Only debug
if self.user is not None:
self.user_teams = await self.session[TeamService].get_teams_for_user_by_id(self.user.user_id)
await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Teams")
self.session[SessionStorage].subscribe_to_logged_in_or_out_event(str(self.__class__), self.on_populate)
async def on_join_button_pressed(self, team: Team) -> None:
# ToDo: handle joining by displaying password popup
print(f"Starting join process for team {team.abbreviation}")
async def on_leave_button_pressed(self, team: Team) -> None:
# ToDo: handle leaving
print(f"Starting leaving process for team {team.abbreviation}")
async def on_create_button_pressed(self, _: PointerEvent) -> None:
# ToDo: Add Popup creation dialog
print(f"Starting creation process for team")
def build(self) -> Component:
if self.all_teams is None:
return Column(
MainViewContentBox(
ProgressCircle(
color="secondary",
align_x=0.5,
margin_top=1,
margin_bottom=1
)
),
Spacer()
)
team_list = []
for team in self.all_teams:
team_list.append(TeamRevealer(user=self.user, team=team, on_join_button_pressed=self.on_join_button_pressed))
if team_list:
team_list[-1].margin_bottom = 1
own_teams_content = Spacer(grow_x=False, grow_y=False)
if self.user is not None:
user_team_list = []
for team in self.user_teams:
# ToDo: Remove from team instead of join
user_team_list.append(TeamRevealer(user=self.user, team=team, on_join_button_pressed=self.on_join_button_pressed))
if not user_team_list:
user_team_list.append(Text(
text="Du bist noch in keinem Team.",
style=TextStyle(
fill=self.session.theme.background_color,
font_size=1
),
margin_top=1,
margin_bottom=1,
align_x=0.5
))
else:
user_team_list[-1].margin_bottom = 1
own_teams_content = MainViewContentBox(
Column(
Row(
Text(
text="Deine Teams",
style=TextStyle(
fill=self.session.theme.background_color,
font_size=1.2
),
grow_x=True,
justify="right",
margin_right=3
),
Column(
PointerEventListener(Rectangle(
content=Text(text="Team erstellen", style=TextStyle(fill=self.session.theme.background_color, font_size=0.7), margin=0.1, selectable=False),
stroke_width=0.1,
stroke_color=self.session.theme.hud_color,
cursor="pointer",
hover_fill=self.session.theme.hud_color,
transition_time=0
), on_press=self.on_create_button_pressed),
Spacer(),
margin_right=2
),
margin_top=1,
margin_bottom=1
),
*user_team_list
)
)
return Column(
MainViewContentBox(Text("Teams")),
own_teams_content,
MainViewContentBox(
Column(
Text(
text="Alle Teams",
style=TextStyle(
fill=self.session.theme.background_color,
font_size=1.2
),
margin_top=1,
margin_bottom=1,
align_x=0.5
),
*team_list
)
),
align_y=0
)

View File

@ -971,13 +971,32 @@ class DatabaseService:
async def get_teams(self) -> list[Team]:
# ToDo: Implement
return []
return [
Team(
id=1,
name="MockTeamAlpha",
abbreviation="-=MTA=-",
members={User(0, "DemoUserA", "", "abuvbwer", None, None, None, True, False, False, datetime.now(), datetime.now()): TeamStatus.LEADER},
join_password="abc"
),
Team(
id=1,
name="MockTeamBeta",
abbreviation="[MTB]",
members={
User(1, "DemoUserB", "", "abuvbwer", None, None, None, True, False, False, datetime.now(), datetime.now()): TeamStatus.LEADER,
User(2, "DemoUserC", "", "abuvbwer", None, None, None, True, False, False, datetime.now(), datetime.now()): TeamStatus.OFFICER,
User(3, "DemoUserD", "", "abuvbwer", None, None, None, True, False, False, datetime.now(), datetime.now()): TeamStatus.MEMBER
},
join_password="abc"
)
]
async def get_team_by_id(self, team_id: int) -> Optional[Team]:
return
async def get_team_for_user_by_id(self, user_id: int) -> Optional[Team]:
return
async def get_teams_for_user_by_id(self, user_id: int) -> list[Team]:
return []
async def create_team(self, team_name: str, team_abbr: str, join_password: str) -> Team:
return # ToDo: Raise on existing team

View File

@ -36,8 +36,8 @@ class TeamService:
async def get_team_by_id(self, team_id: int) -> Optional[Team]:
return await self._db_service.get_team_by_id(team_id)
async def get_team_for_user_by_id(self, user_id: int) -> Optional[Team]:
return await self._db_service.get_team_for_user_by_id(user_id)
async def get_teams_for_user_by_id(self, user_id: int) -> list[Team]:
return await self._db_service.get_teams_for_user_by_id(user_id)
async def create_team(self, team_name: str, team_abbr: str, join_password: str) -> Team:
disallowed_char = self._check_for_disallowed_char(team_name)