Co-authored-by: David Rodenkirchen <drodenkirchen@linetco.com> Reviewed-on: #45
223 lines
8.3 KiB
Python
223 lines
8.3 KiB
Python
import logging
|
|
from typing import Optional, Callable
|
|
|
|
from rio import Component, Text, Spacer, Rectangle, Column, TextStyle, Row, Button, TextInput, ThemeContextSwitcher
|
|
|
|
from src.ezgg_lan_manager.services.TeamService import TeamService, NotMemberError, TeamLeadRemovalError, AlreadyMemberError, NameNotAllowedError, TeamNameTooLongError, \
|
|
TeamAbbrInvalidError, TeamNameAlreadyTaken
|
|
from src.ezgg_lan_manager.types.Team import Team
|
|
from src.ezgg_lan_manager.types.User import User
|
|
|
|
logger = logging.getLogger(__name__.split(".")[-1])
|
|
|
|
|
|
class ErrorBox(Component):
|
|
error_message: str
|
|
cancel: Callable
|
|
|
|
def build(self) -> Component:
|
|
return Rectangle(
|
|
content=Column(
|
|
Text(self.error_message, style=TextStyle(fill=self.session.theme.background_color), margin_bottom=1.5),
|
|
Row(
|
|
Button(
|
|
content="Ok",
|
|
shape="rectangle",
|
|
style="major",
|
|
color="hud",
|
|
on_press=self.cancel,
|
|
)
|
|
),
|
|
margin=1
|
|
),
|
|
fill=self.session.theme.primary_color
|
|
)
|
|
|
|
|
|
class TeamsDialogJoinHandler(Component):
|
|
is_active: bool
|
|
cancel: Callable
|
|
user: Optional[User] = None
|
|
team: Optional[Team] = None
|
|
error_message: Optional[str] = None
|
|
password: str = ""
|
|
|
|
async def join(self) -> None:
|
|
if self.user is None or self.team is None:
|
|
return
|
|
|
|
if self.password != self.team.join_password:
|
|
self.error_message = "Falsches Passwort!"
|
|
return
|
|
|
|
try:
|
|
await self.session[TeamService].add_member_to_team(self.team, self.user)
|
|
except AlreadyMemberError:
|
|
self.error_message = "Du bist bereits Mitglied dieses Teams"
|
|
else:
|
|
await self.cancel_with_reset()
|
|
|
|
async def cancel_with_reset(self) -> None:
|
|
await self.cancel()
|
|
self.error_message = None
|
|
self.password = ""
|
|
|
|
def build(self) -> Component:
|
|
if not self.is_active or self.user is None or self.team is None:
|
|
return Spacer()
|
|
|
|
if self.error_message is not None:
|
|
return ErrorBox(error_message=self.error_message, cancel=self.cancel_with_reset)
|
|
|
|
return Rectangle(
|
|
content=Column(
|
|
Text(f"Team {self.team.name} beitreten", style=TextStyle(fill=self.session.theme.background_color), margin_bottom=1, justify="center"),
|
|
ThemeContextSwitcher(content=TextInput(text=self.bind().password, label="Beitrittspasswort", margin_bottom=1), color="secondary"),
|
|
Row(
|
|
Button(
|
|
content="Abbrechen",
|
|
shape="rectangle",
|
|
style="major",
|
|
color=self.session.theme.danger_color,
|
|
on_press=self.cancel_with_reset,
|
|
),
|
|
Button(
|
|
content="Beitreten",
|
|
shape="rectangle",
|
|
style="major",
|
|
color=self.session.theme.success_color,
|
|
on_press=self.join,
|
|
),
|
|
spacing=1
|
|
),
|
|
margin=1
|
|
),
|
|
fill=self.session.theme.primary_color
|
|
)
|
|
|
|
|
|
class TeamsDialogLeaveHandler(Component):
|
|
is_active: bool
|
|
cancel: Callable
|
|
user: Optional[User] = None
|
|
team: Optional[Team] = None
|
|
error_message: Optional[str] = None
|
|
|
|
async def leave(self) -> None:
|
|
if self.user is not None and self.team is not None:
|
|
try:
|
|
await self.session[TeamService].remove_member_from_team(self.team, self.user)
|
|
except NotMemberError:
|
|
self.error_message = "Du bist kein Mitglied in diesem Team"
|
|
except TeamLeadRemovalError:
|
|
self.error_message = "Als Teamleiter kannst du das Team nicht verlassen"
|
|
else:
|
|
await self.cancel_with_reset()
|
|
|
|
async def cancel_with_reset(self) -> None:
|
|
await self.cancel()
|
|
self.error_message = None
|
|
|
|
def build(self) -> Component:
|
|
if not self.is_active or self.user is None or self.team is None:
|
|
return Spacer()
|
|
|
|
if self.error_message is not None:
|
|
return ErrorBox(error_message=self.error_message, cancel=self.cancel_with_reset)
|
|
|
|
return Rectangle(
|
|
content=Column(
|
|
Text(f"Team {self.team.name} wirklich verlassen?", style=TextStyle(fill=self.session.theme.background_color), margin_bottom=1.5, justify="center"),
|
|
Row(
|
|
Button(
|
|
content="Nein",
|
|
shape="rectangle",
|
|
style="major",
|
|
color=self.session.theme.danger_color,
|
|
on_press=self.cancel_with_reset,
|
|
),
|
|
Button(
|
|
content="Ja",
|
|
shape="rectangle",
|
|
style="major",
|
|
color=self.session.theme.success_color,
|
|
on_press=self.leave,
|
|
),
|
|
spacing=1
|
|
),
|
|
margin=1
|
|
),
|
|
fill=self.session.theme.primary_color
|
|
)
|
|
|
|
|
|
class TeamsDialogCreateHandler(Component):
|
|
is_active: bool
|
|
cancel: Callable
|
|
user: Optional[User] = None
|
|
error_message: Optional[str] = None
|
|
team_name: str = ""
|
|
team_abbr: str = ""
|
|
team_join_password: str = ""
|
|
|
|
async def cancel_with_reset(self) -> None:
|
|
await self.cancel()
|
|
self.error_message = None
|
|
self.team_name, self.team_abbr, self.team_join_password = "", "", ""
|
|
|
|
async def create(self) -> None:
|
|
if self.user is None:
|
|
return
|
|
|
|
if not self.team_name or not self.team_abbr or not self.team_join_password:
|
|
self.error_message = "Angaben unvollständig"
|
|
return
|
|
|
|
try:
|
|
await self.session[TeamService].create_team(self.team_name, self.team_abbr, self.team_join_password, self.user)
|
|
except NameNotAllowedError as e:
|
|
self.error_message = f"Angaben ungültig. Darf kein '{e.disallowed_char}' enthalten."
|
|
except TeamNameTooLongError:
|
|
self.error_message = f"Name zu lang. Maximal {TeamService.MAX_TEAM_NAME_LENGTH} Zeichen."
|
|
except TeamAbbrInvalidError:
|
|
self.error_message = f"Name zu lang. Maximal {TeamService.MAX_TEAM_ABBR_LENGTH} Zeichen."
|
|
except TeamNameAlreadyTaken:
|
|
self.error_message = "Ein Team mit diesem Namen existiert bereits."
|
|
else:
|
|
await self.cancel_with_reset()
|
|
|
|
def build(self) -> Component:
|
|
if not self.is_active or self.user is None:
|
|
return Spacer()
|
|
|
|
if self.error_message is not None:
|
|
return ErrorBox(error_message=self.error_message, cancel=self.cancel_with_reset)
|
|
|
|
return Rectangle(
|
|
content=Column(
|
|
Text(f"Team gründen", style=TextStyle(fill=self.session.theme.background_color), margin_bottom=1.5, justify="center"),
|
|
ThemeContextSwitcher(content=TextInput(text=self.bind().team_name, label="Team Name", margin_bottom=1), color="secondary"),
|
|
ThemeContextSwitcher(content=TextInput(text=self.bind().team_abbr, label="Team Abkürzung", margin_bottom=1), color="secondary"),
|
|
ThemeContextSwitcher(content=TextInput(text=self.bind().team_join_password, label="Beitrittspasswort", margin_bottom=1), color="secondary"),
|
|
Row(
|
|
Button(
|
|
content="Abbrechen",
|
|
shape="rectangle",
|
|
style="major",
|
|
color=self.session.theme.danger_color,
|
|
on_press=self.cancel_with_reset,
|
|
),
|
|
Button(
|
|
content="Gründen",
|
|
shape="rectangle",
|
|
style="major",
|
|
color=self.session.theme.success_color,
|
|
on_press=self.create,
|
|
),
|
|
spacing=1
|
|
),
|
|
margin=1
|
|
),
|
|
fill=self.session.theme.primary_color
|
|
)
|