From 7043877a9f2622eb583f7a6c638d20662fe5e341 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Sat, 30 Nov 2024 13:08:42 -0800 Subject: [PATCH] Add updating events --- availabili.tf/src/client/index.ts | 1 + .../src/client/models/CreateEventJson.ts | 2 +- .../src/client/models/UpdateEventJson.ts | 11 +++ .../src/client/services/DefaultService.ts | 42 ++++++----- availabili.tf/src/components/EventCard.vue | 10 +++ .../src/components/EventSchedulerForm.vue | 23 ++++-- availabili.tf/src/composables/event-form.ts | 10 ++- availabili.tf/src/stores/roster.ts | 73 ++++++++++++------- availabili.tf/src/views/RosterBuilderView.vue | 12 ++- backend-flask/events.py | 44 ++++++++--- backend-flask/models/player_event.py | 6 +- 11 files changed, 164 insertions(+), 70 deletions(-) create mode 100644 availabili.tf/src/client/models/UpdateEventJson.ts diff --git a/availabili.tf/src/client/index.ts b/availabili.tf/src/client/index.ts index dd3a4ca..45058cf 100644 --- a/availabili.tf/src/client/index.ts +++ b/availabili.tf/src/client/index.ts @@ -33,6 +33,7 @@ export type { TeamInviteSchemaList } from './models/TeamInviteSchemaList'; export type { TeamLogsTfIntegrationSchema } from './models/TeamLogsTfIntegrationSchema'; export { TeamRole } from './models/TeamRole'; export type { TeamSchema } from './models/TeamSchema'; +export type { UpdateEventJson } from './models/UpdateEventJson'; export type { ValidationError } from './models/ValidationError'; export type { ValidationErrorElement } from './models/ValidationErrorElement'; export type { ViewAvailablePlayersQuery } from './models/ViewAvailablePlayersQuery'; diff --git a/availabili.tf/src/client/models/CreateEventJson.ts b/availabili.tf/src/client/models/CreateEventJson.ts index 2530f85..e770eed 100644 --- a/availabili.tf/src/client/models/CreateEventJson.ts +++ b/availabili.tf/src/client/models/CreateEventJson.ts @@ -4,7 +4,7 @@ /* eslint-disable */ import type { PlayerRoleSchema } from './PlayerRoleSchema'; export type CreateEventJson = { - description: string; + description: (string | null); name: string; playerRoles: Array; startTime: string; diff --git a/availabili.tf/src/client/models/UpdateEventJson.ts b/availabili.tf/src/client/models/UpdateEventJson.ts new file mode 100644 index 0000000..c076e45 --- /dev/null +++ b/availabili.tf/src/client/models/UpdateEventJson.ts @@ -0,0 +1,11 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { PlayerRoleSchema } from './PlayerRoleSchema'; +export type UpdateEventJson = { + description: (string | null); + name: string; + playerRoles: Array; +}; + diff --git a/availabili.tf/src/client/services/DefaultService.ts b/availabili.tf/src/client/services/DefaultService.ts index f8f06c5..2963ff8 100644 --- a/availabili.tf/src/client/services/DefaultService.ts +++ b/availabili.tf/src/client/services/DefaultService.ts @@ -16,6 +16,7 @@ import type { SetUsernameJson } from '../models/SetUsernameJson'; import type { TeamIntegrationSchema } from '../models/TeamIntegrationSchema'; import type { TeamInviteSchema } from '../models/TeamInviteSchema'; import type { TeamInviteSchemaList } from '../models/TeamInviteSchemaList'; +import type { UpdateEventJson } from '../models/UpdateEventJson'; import type { ViewAvailablePlayersResponse } from '../models/ViewAvailablePlayersResponse'; import type { ViewScheduleResponse } from '../models/ViewScheduleResponse'; import type { ViewTeamMembersResponseList } from '../models/ViewTeamMembersResponseList'; @@ -129,6 +130,30 @@ export class DefaultService { }, }); } + /** + * update_event + * @param eventId + * @param requestBody + * @returns EventSchema OK + * @throws ApiError + */ + public updateEvent( + eventId: number, + requestBody?: UpdateEventJson, + ): CancelablePromise { + return this.httpRequest.request({ + method: 'PATCH', + url: '/api/events/{event_id}', + path: { + 'event_id': eventId, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Unprocessable Content`, + }, + }); + } /** * unattend_event * @param eventId @@ -189,23 +214,6 @@ export class DefaultService { }, }); } - /** - * set_event_players - * @param eventId - * @returns void - * @throws ApiError - */ - public patchApiEventsEventIdPlayers( - eventId: number, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'PATCH', - url: '/api/events/{event_id}/players', - path: { - 'event_id': eventId, - }, - }); - } /** * logout * @returns void diff --git a/availabili.tf/src/components/EventCard.vue b/availabili.tf/src/components/EventCard.vue index ab9f747..0870a31 100644 --- a/availabili.tf/src/components/EventCard.vue +++ b/availabili.tf/src/components/EventCard.vue @@ -5,6 +5,7 @@ import { useTeamsStore } from "@/stores/teams"; import { useTeamsEventsStore } from "@/stores/teams/events"; import moment from "moment"; import { computed } from "vue"; +import { RouterLink } from "vue-router"; const teamsStore = useTeamsStore(); const rosterStore = useRosterStore(); @@ -72,6 +73,15 @@ function attendOrUnattend() { No description provided.
+ + + diff --git a/backend-flask/events.py b/backend-flask/events.py index 0988c28..ce53ec9 100644 --- a/backend-flask/events.py +++ b/backend-flask/events.py @@ -76,10 +76,15 @@ def get_user_events(user_id: int): class CreateEventJson(BaseModel): name: str - description: str + description: Optional[str] start_time: datetime player_roles: list[PlayerRoleSchema] +class UpdateEventJson(BaseModel): + name: str + description: Optional[str] + player_roles: list[PlayerRoleSchema] + @api_events.post("/team/id/") @spec.validate( resp=Response( @@ -93,7 +98,8 @@ def create_event(player_team: PlayerTeam, team_id: int, json: CreateEventJson, * event = Event() event.team_id = player_team.team_id event.name = json.name - event.description = json.description + if json.description: + event.description = json.description event.start_time = json.start_time db.session.add(event) @@ -252,13 +258,33 @@ def get_event_players(player: Player, event_id: int, **_): players=player_event_roles ).dict(by_alias=True), 200 -@api_events.patch("//players") +@api_events.patch("/") +@spec.validate( + resp=Response( + HTTP_200=EventSchema, + ), + operation_id="update_event", +) @requires_authentication -@requires_team_membership() -def set_event_players(player_team: PlayerTeam, event_id: int, **_): - assert_team_authority(player_team, None) +def update_event(player: Player, event_id: int, json: UpdateEventJson, **_): + event = db.session.query(Event).where(Event.id == event_id).one_or_none() + if not event: + abort(404) + assert_team_membership(player, event.team) - # merge players into event - db.session.query(Event).filter(Event.id == event_id).update({"players": []}) + for player_event in event.players: + player_team = player_event.player_team + roles = player_team.player_roles + # assign new roles if in json, set to None if not + new_role = next((x.role for x in json.player_roles if x.player.steam_id == str(player_event.player_id)), None) + #import sys + #print(player_event.player_id, file=sys.stderr) + # if valid role (new_role exists in roles), update player_event.role + if new_role and (role_entity := next((x for x in roles if x.role.name == new_role.role), None)): + player_event.player_team_role_id = role_entity.id + else: + player_event.role = None - raise NotImplementedError() + event.update_discord_message() + + return EventSchema.from_model(event).dict(by_alias=True), 200 diff --git a/backend-flask/models/player_event.py b/backend-flask/models/player_event.py index dc31dc3..e9456dd 100644 --- a/backend-flask/models/player_event.py +++ b/backend-flask/models/player_event.py @@ -12,7 +12,7 @@ class PlayerEvent(app_db.BaseModel): event_id: Mapped[int] = mapped_column(ForeignKey("events.id"), primary_key=True) player_id: Mapped[int] = mapped_column(ForeignKey("players.steam_id"), primary_key=True) - player_team_role_id: Mapped[int] = mapped_column(ForeignKey("players_teams_roles.id"), nullable=True) + player_team_role_id: Mapped[int | None] = mapped_column(ForeignKey("players_teams_roles.id"), nullable=True) has_confirmed: Mapped[bool] = mapped_column(Boolean, default=False) event: Mapped["Event"] = relationship("Event", back_populates="players") @@ -21,10 +21,10 @@ class PlayerEvent(app_db.BaseModel): "PlayerTeam", secondary="players", primaryjoin="PlayerEvent.player_id == Player.steam_id", - secondaryjoin="PlayerTeam.player_id == Player.steam_id", + secondaryjoin="(PlayerTeam.player_id == Player.steam_id) & (PlayerTeam.team_id == Event.team_id)", viewonly=True, ) - role: Mapped["PlayerTeamRole"] = relationship("PlayerTeamRole") + role: Mapped["PlayerTeamRole | None"] = relationship("PlayerTeamRole") class EventWithPlayerSchema(spec.BaseModel): event: "EventSchema"