From 6f49053dacdfa2d858d0ac851d02f96f7770b88f Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Fri, 29 Nov 2024 00:06:34 -0800 Subject: [PATCH] feat: Add event details in roster builder --- availabili.tf/src/client/index.ts | 3 +- .../src/client/models/EventSchemaList.ts | 6 -- .../client/models/EventWithPlayerSchema.ts | 11 +++ .../models/EventWithPlayerSchemaList.ts | 6 ++ .../src/client/services/DefaultService.ts | 93 +++++++++---------- .../src/components/EventSchedulerForm.vue | 54 +++++++++++ availabili.tf/src/composables/event-form.ts | 14 +++ availabili.tf/src/stores/roster.ts | 15 +-- availabili.tf/src/stores/teams/events.ts | 59 +++++++----- availabili.tf/src/views/RosterBuilderView.vue | 40 ++++---- backend-flask/events.py | 72 ++++++++------ backend-flask/models/event.py | 14 ++- backend-flask/models/player_event.py | 20 +++- 13 files changed, 269 insertions(+), 138 deletions(-) delete mode 100644 availabili.tf/src/client/models/EventSchemaList.ts create mode 100644 availabili.tf/src/client/models/EventWithPlayerSchema.ts create mode 100644 availabili.tf/src/client/models/EventWithPlayerSchemaList.ts create mode 100644 availabili.tf/src/components/EventSchedulerForm.vue create mode 100644 availabili.tf/src/composables/event-form.ts diff --git a/availabili.tf/src/client/index.ts b/availabili.tf/src/client/index.ts index b76aa83..dd3a4ca 100644 --- a/availabili.tf/src/client/index.ts +++ b/availabili.tf/src/client/index.ts @@ -16,7 +16,8 @@ export type { CreateEventJson } from './models/CreateEventJson'; export type { CreateTeamJson } from './models/CreateTeamJson'; export type { EditMemberRolesJson } from './models/EditMemberRolesJson'; export type { EventSchema } from './models/EventSchema'; -export type { EventSchemaList } from './models/EventSchemaList'; +export type { EventWithPlayerSchema } from './models/EventWithPlayerSchema'; +export type { EventWithPlayerSchemaList } from './models/EventWithPlayerSchemaList'; export type { GetEventPlayersResponse } from './models/GetEventPlayersResponse'; export type { PlayerEventRolesSchema } from './models/PlayerEventRolesSchema'; export type { PlayerRoleSchema } from './models/PlayerRoleSchema'; diff --git a/availabili.tf/src/client/models/EventSchemaList.ts b/availabili.tf/src/client/models/EventSchemaList.ts deleted file mode 100644 index b425d11..0000000 --- a/availabili.tf/src/client/models/EventSchemaList.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* generated using openapi-typescript-codegen -- do not edit */ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { EventSchema } from './EventSchema'; -export type EventSchemaList = Array; diff --git a/availabili.tf/src/client/models/EventWithPlayerSchema.ts b/availabili.tf/src/client/models/EventWithPlayerSchema.ts new file mode 100644 index 0000000..58814e2 --- /dev/null +++ b/availabili.tf/src/client/models/EventWithPlayerSchema.ts @@ -0,0 +1,11 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { EventSchema } from './EventSchema'; +import type { PlayerEventRolesSchema } from './PlayerEventRolesSchema'; +export type EventWithPlayerSchema = { + event: EventSchema; + playerEvent: (PlayerEventRolesSchema | null); +}; + diff --git a/availabili.tf/src/client/models/EventWithPlayerSchemaList.ts b/availabili.tf/src/client/models/EventWithPlayerSchemaList.ts new file mode 100644 index 0000000..84edd12 --- /dev/null +++ b/availabili.tf/src/client/models/EventWithPlayerSchemaList.ts @@ -0,0 +1,6 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { EventWithPlayerSchema } from './EventWithPlayerSchema'; +export type EventWithPlayerSchemaList = Array; diff --git a/availabili.tf/src/client/services/DefaultService.ts b/availabili.tf/src/client/services/DefaultService.ts index 595d244..f8f06c5 100644 --- a/availabili.tf/src/client/services/DefaultService.ts +++ b/availabili.tf/src/client/services/DefaultService.ts @@ -7,7 +7,8 @@ import type { CreateEventJson } from '../models/CreateEventJson'; import type { CreateTeamJson } from '../models/CreateTeamJson'; import type { EditMemberRolesJson } from '../models/EditMemberRolesJson'; import type { EventSchema } from '../models/EventSchema'; -import type { EventSchemaList } from '../models/EventSchemaList'; +import type { EventWithPlayerSchema } from '../models/EventWithPlayerSchema'; +import type { EventWithPlayerSchemaList } from '../models/EventWithPlayerSchemaList'; import type { GetEventPlayersResponse } from '../models/GetEventPlayersResponse'; import type { PlayerSchema } from '../models/PlayerSchema'; import type { PutScheduleForm } from '../models/PutScheduleForm'; @@ -50,12 +51,12 @@ export class DefaultService { /** * get_team_events * @param teamId - * @returns EventSchemaList OK + * @returns EventWithPlayerSchemaList OK * @throws ApiError */ public getTeamEvents( teamId: number, - ): CancelablePromise { + ): CancelablePromise { return this.httpRequest.request({ method: 'GET', url: '/api/events/team/id/{team_id}', @@ -128,6 +129,46 @@ export class DefaultService { }, }); } + /** + * unattend_event + * @param eventId + * @returns EventWithPlayerSchema OK + * @throws ApiError + */ + public unattendEvent( + eventId: number, + ): CancelablePromise { + return this.httpRequest.request({ + method: 'DELETE', + url: '/api/events/{event_id}/attendance', + path: { + 'event_id': eventId, + }, + errors: { + 422: `Unprocessable Content`, + }, + }); + } + /** + * attend_event + * @param eventId + * @returns EventWithPlayerSchema OK + * @throws ApiError + */ + public attendEvent( + eventId: number, + ): CancelablePromise { + return this.httpRequest.request({ + method: 'PUT', + url: '/api/events/{event_id}/attendance', + path: { + 'event_id': eventId, + }, + errors: { + 422: `Unprocessable Content`, + }, + }); + } /** * get_event_players * @param eventId @@ -165,52 +206,6 @@ export class DefaultService { }, }); } - /** - * unattend_event - * @param eventId - * @param teamId - * @returns void - * @throws ApiError - */ - public deleteApiEventsEventIdTeamIdTeamIdAttendance( - eventId: number, - teamId: number, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'DELETE', - url: '/api/events/{event_id}/team/id/{team_id}/attendance', - path: { - 'event_id': eventId, - 'team_id': teamId, - }, - errors: { - 422: `Unprocessable Content`, - }, - }); - } - /** - * attend_event - * @param eventId - * @param teamId - * @returns void - * @throws ApiError - */ - public putApiEventsEventIdTeamIdTeamIdAttendance( - eventId: number, - teamId: number, - ): CancelablePromise { - return this.httpRequest.request({ - method: 'PUT', - url: '/api/events/{event_id}/team/id/{team_id}/attendance', - path: { - 'event_id': eventId, - 'team_id': teamId, - }, - errors: { - 422: `Unprocessable Content`, - }, - }); - } /** * logout * @returns void diff --git a/availabili.tf/src/components/EventSchedulerForm.vue b/availabili.tf/src/components/EventSchedulerForm.vue new file mode 100644 index 0000000..5a9456f --- /dev/null +++ b/availabili.tf/src/components/EventSchedulerForm.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/availabili.tf/src/composables/event-form.ts b/availabili.tf/src/composables/event-form.ts new file mode 100644 index 0000000..2fe13f0 --- /dev/null +++ b/availabili.tf/src/composables/event-form.ts @@ -0,0 +1,14 @@ +import type { PlayerRoleSchema } from "@/client"; +import { ref } from "vue"; + +export function useEventForm() { + const title = ref(""); + const description = ref(""); + const players = ref([]); + + return { + title, + description, + players, + } +} diff --git a/availabili.tf/src/stores/roster.ts b/availabili.tf/src/stores/roster.ts index e0b5f67..1f3f433 100644 --- a/availabili.tf/src/stores/roster.ts +++ b/availabili.tf/src/stores/roster.ts @@ -6,6 +6,7 @@ import { type EventSchema, type CreateEventJson, type PlayerRoleSchema } from "@ import { useTeamDetails } from "@/composables/team-details"; import moment from "moment"; import { useRoute, useRouter } from "vue-router"; +import { useEventForm } from "@/composables/event-form"; export const useRosterStore = defineStore("roster", () => { const clientStore = useClientStore(); @@ -169,6 +170,8 @@ export const useRosterStore = defineStore("roster", () => { const startTime = ref(); + const { title, description } = useEventForm(); + function saveRoster(teamId: number) { if (startTime.value == undefined) { throw new Error("No start time set"); @@ -176,8 +179,8 @@ export const useRosterStore = defineStore("roster", () => { if (!currentEvent.value) { const body: CreateEventJson = { - name: "Test", - description: "test description", + name: title.value, + description: description.value, startTime: startTime.value.toString(), playerRoles: Object.values(selectedPlayers).map((player) => ({ player: { @@ -191,12 +194,10 @@ export const useRosterStore = defineStore("roster", () => { })), }; - clientStore.client.default.createEvent(teamId, body) - .then(() => { - - }); + return clientStore.client.default.createEvent(teamId, body); } else { // TODO: update event + throw "Not implemented"; } } @@ -217,5 +218,7 @@ export const useRosterStore = defineStore("roster", () => { fetchPlayersFromEvent, startTime, saveRoster, + title, + description, } }); diff --git a/availabili.tf/src/stores/teams/events.ts b/availabili.tf/src/stores/teams/events.ts index ea8a614..01706d6 100644 --- a/availabili.tf/src/stores/teams/events.ts +++ b/availabili.tf/src/stores/teams/events.ts @@ -1,45 +1,62 @@ import { defineStore } from "pinia"; import { useClientStore } from "../client"; -import type { EventSchema, EventSchemaList } from "@/client"; +import type { EventWithPlayerSchema } from "@/client"; import { useEventsStore } from "../events"; -import { computed } from "vue"; +import { computed, reactive } from "vue"; export const useTeamsEventsStore = defineStore("teamsEvents", () => { const clientStore = useClientStore(); const client = clientStore.client; - const eventsStore = useEventsStore(); + //const eventsStore = useEventsStore(); - const teamEvents = computed(() => { - console.log("Recomputing teamEvents"); + const teamEvents = reactive<{ [teamId: number]: EventWithPlayerSchema[] }>({ }); + //const teamEvents = computed(() => { + // console.log("Recomputing teamEvents"); - // map events to objects with teamId as key, and array of events as value - return eventsStore.events - .reduce((acc, event) => { - if (!acc[event.teamId]) { - acc[event.teamId] = []; - } - acc[event.teamId].push(event); - return acc; - }, { } as { [teamId: number]: EventSchema[] }); - }); + // // map events to objects with teamId as key, and array of events as value + // return eventsStore.events + // .reduce((acc, event) => { + // if (!acc[event.teamId]) { + // acc[event.teamId] = []; + // } + // acc[event.teamId].push(event); + // return acc; + // }, { } as { [teamId: number]: EventSchema[] }); + //}); function fetchTeamEvents(teamId: number) { return clientStore.call( fetchTeamEvents.name, () => client.default.getTeamEvents(teamId), - (result: EventSchemaList) => { - result.forEach((event) => { - // insert into event store - //eventsStore.events[event.id] = event; - eventsStore.events.push(event); - }); + (result: EventWithPlayerSchema[]) => { + teamEvents[teamId] = result; return result; } ); } + function attendEvent(eventId: number) { + client.default.attendEvent(eventId) + .then((response) => { + let index = teamEvents[response.event.teamId] + .findIndex((event) => event.event.id == response.event.id); + teamEvents[response.event.teamId][index] = response; + }); + } + + function unattendEvent(eventId: number) { + client.default.unattendEvent(eventId) + .then((response) => { + let index = teamEvents[response.event.teamId] + .findIndex((event) => event.event.id == response.event.id); + teamEvents[response.event.teamId][index].playerEvent = null; + }); + } + return { teamEvents, fetchTeamEvents, + attendEvent, + unattendEvent, } }); diff --git a/availabili.tf/src/views/RosterBuilderView.vue b/availabili.tf/src/views/RosterBuilderView.vue index dab0e78..35af9ff 100644 --- a/availabili.tf/src/views/RosterBuilderView.vue +++ b/availabili.tf/src/views/RosterBuilderView.vue @@ -1,12 +1,11 @@