From 325b3529fe9b965c96a6e7024aab64d846fa5d98 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Mon, 11 Nov 2024 18:05:27 -0800 Subject: [PATCH] Add functionality for viewing available teammates --- availabili.tf/src/client/index.ts | 4 +- .../PlayerTeamAvailabilityRoleSchema.ts | 13 ++ ...rsForm.ts => ViewAvailablePlayersQuery.ts} | 2 +- .../models/ViewAvailablePlayersResponse.ts | 9 + .../src/client/services/DefaultService.ts | 12 +- availabili.tf/src/player.ts | 6 +- availabili.tf/src/router/index.ts | 2 +- availabili.tf/src/stores/roster.ts | 155 +++++------------- availabili.tf/src/views/RosterBuilderView.vue | 15 +- backend-flask/login.py | 7 +- backend-flask/models/player.py | 4 + .../models/player_team_availability.py | 12 +- backend-flask/models/player_team_role.py | 9 + backend-flask/schedule.py | 61 ++++--- backend-flask/team.py | 10 +- 15 files changed, 154 insertions(+), 167 deletions(-) create mode 100644 availabili.tf/src/client/models/PlayerTeamAvailabilityRoleSchema.ts rename availabili.tf/src/client/models/{ViewAvailablePlayersForm.ts => ViewAvailablePlayersQuery.ts} (81%) create mode 100644 availabili.tf/src/client/models/ViewAvailablePlayersResponse.ts diff --git a/availabili.tf/src/client/index.ts b/availabili.tf/src/client/index.ts index f006045..1c4dac2 100644 --- a/availabili.tf/src/client/index.ts +++ b/availabili.tf/src/client/index.ts @@ -14,6 +14,7 @@ export type { AddPlayerJson } from './models/AddPlayerJson'; export type { CreateTeamJson } from './models/CreateTeamJson'; export type { EditMemberRolesJson } from './models/EditMemberRolesJson'; export type { PlayerSchema } from './models/PlayerSchema'; +export type { PlayerTeamAvailabilityRoleSchema } from './models/PlayerTeamAvailabilityRoleSchema'; export type { PutScheduleForm } from './models/PutScheduleForm'; export type { RoleSchema } from './models/RoleSchema'; export type { TeamInviteSchema } from './models/TeamInviteSchema'; @@ -22,7 +23,8 @@ export { TeamRole } from './models/TeamRole'; export type { TeamSchema } from './models/TeamSchema'; export type { ValidationError } from './models/ValidationError'; export type { ValidationErrorElement } from './models/ValidationErrorElement'; -export type { ViewAvailablePlayersForm } from './models/ViewAvailablePlayersForm'; +export type { ViewAvailablePlayersQuery } from './models/ViewAvailablePlayersQuery'; +export type { ViewAvailablePlayersResponse } from './models/ViewAvailablePlayersResponse'; export type { ViewScheduleForm } from './models/ViewScheduleForm'; export type { ViewScheduleResponse } from './models/ViewScheduleResponse'; export type { ViewTeamMembersResponse } from './models/ViewTeamMembersResponse'; diff --git a/availabili.tf/src/client/models/PlayerTeamAvailabilityRoleSchema.ts b/availabili.tf/src/client/models/PlayerTeamAvailabilityRoleSchema.ts new file mode 100644 index 0000000..1763eb4 --- /dev/null +++ b/availabili.tf/src/client/models/PlayerTeamAvailabilityRoleSchema.ts @@ -0,0 +1,13 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { PlayerSchema } from './PlayerSchema'; +import type { RoleSchema } from './RoleSchema'; +export type PlayerTeamAvailabilityRoleSchema = { + availability: number; + player: PlayerSchema; + playtime: number; + roles: Array; +}; + diff --git a/availabili.tf/src/client/models/ViewAvailablePlayersForm.ts b/availabili.tf/src/client/models/ViewAvailablePlayersQuery.ts similarity index 81% rename from availabili.tf/src/client/models/ViewAvailablePlayersForm.ts rename to availabili.tf/src/client/models/ViewAvailablePlayersQuery.ts index d46cd46..4ec6283 100644 --- a/availabili.tf/src/client/models/ViewAvailablePlayersForm.ts +++ b/availabili.tf/src/client/models/ViewAvailablePlayersQuery.ts @@ -2,7 +2,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -export type ViewAvailablePlayersForm = { +export type ViewAvailablePlayersQuery = { startTime: string; teamId: number; }; diff --git a/availabili.tf/src/client/models/ViewAvailablePlayersResponse.ts b/availabili.tf/src/client/models/ViewAvailablePlayersResponse.ts new file mode 100644 index 0000000..20590cc --- /dev/null +++ b/availabili.tf/src/client/models/ViewAvailablePlayersResponse.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { PlayerTeamAvailabilityRoleSchema } from './PlayerTeamAvailabilityRoleSchema'; +export type ViewAvailablePlayersResponse = { + players: Array; +}; + diff --git a/availabili.tf/src/client/services/DefaultService.ts b/availabili.tf/src/client/services/DefaultService.ts index 54016b4..fa5c8d3 100644 --- a/availabili.tf/src/client/services/DefaultService.ts +++ b/availabili.tf/src/client/services/DefaultService.ts @@ -9,6 +9,7 @@ import type { PlayerSchema } from '../models/PlayerSchema'; import type { PutScheduleForm } from '../models/PutScheduleForm'; import type { TeamInviteSchema } from '../models/TeamInviteSchema'; import type { TeamInviteSchemaList } from '../models/TeamInviteSchemaList'; +import type { ViewAvailablePlayersResponse } from '../models/ViewAvailablePlayersResponse'; import type { ViewScheduleResponse } from '../models/ViewScheduleResponse'; import type { ViewTeamMembersResponseList } from '../models/ViewTeamMembersResponseList'; import type { ViewTeamResponse } from '../models/ViewTeamResponse'; @@ -130,16 +131,16 @@ export class DefaultService { }); } /** - * view_available + * view_available_at_time * @param startTime * @param teamId - * @returns void + * @returns ViewAvailablePlayersResponse OK * @throws ApiError */ - public getApiScheduleViewAvailable( + public viewAvailableAtTime( startTime: string, teamId: number, - ): CancelablePromise { + ): CancelablePromise { return this.httpRequest.request({ method: 'GET', url: '/api/schedule/view-available', @@ -147,6 +148,9 @@ export class DefaultService { 'startTime': startTime, 'teamId': teamId, }, + errors: { + 422: `Unprocessable Entity`, + }, }); } /** diff --git a/availabili.tf/src/player.ts b/availabili.tf/src/player.ts index 38ba1b3..d2fae42 100644 --- a/availabili.tf/src/player.ts +++ b/availabili.tf/src/player.ts @@ -3,11 +3,11 @@ export interface Player { name: string; } -export interface PlayerTeamRole { - steamId: number; +export interface PlayerTeamRoleFlat { + steamId: string; name: string; role: string; - main: boolean; + isMain: boolean; availability: number; playtime: number; } diff --git a/availabili.tf/src/router/index.ts b/availabili.tf/src/router/index.ts index 1b0f3c8..51e004d 100644 --- a/availabili.tf/src/router/index.ts +++ b/availabili.tf/src/router/index.ts @@ -26,7 +26,7 @@ const router = createRouter({ component: ScheduleView }, { - path: "/schedule/roster", + path: "/schedule/roster/:teamId/:startTime", name: "roster-builder", component: RosterBuilderView }, diff --git a/availabili.tf/src/stores/roster.ts b/availabili.tf/src/stores/roster.ts index 3e7ed0e..ca42885 100644 --- a/availabili.tf/src/stores/roster.ts +++ b/availabili.tf/src/stores/roster.ts @@ -1,8 +1,12 @@ -import { type Player, type PlayerTeamRole } from "@/player"; +import { type Player, type PlayerTeamRoleFlat } from "@/player"; import { defineStore } from "pinia"; import { computed, reactive, ref, type Reactive, type Ref } from "vue"; +import { useClientStore } from "./client"; export const useRosterStore = defineStore("roster", () => { + const clientStore = useClientStore(); + const client = clientStore.client; + const neededRoles: Reactive> = reactive([ "PocketScout", "FlankScout", @@ -12,134 +16,31 @@ export const useRosterStore = defineStore("roster", () => { "Medic", ]); - const selectedPlayers: Reactive<{ [key: string]: PlayerTeamRole }> = reactive({}); + const selectedPlayers: Reactive<{ [key: string]: PlayerTeamRoleFlat }> = reactive({}); const selectedRole: Ref = ref(undefined); - const availablePlayers: Reactive> = reactive([ + const availablePlayers: Ref> = ref([ { - steamId: 2840, + steamId: "342534598", name: "Wesker U", role: "Flank Scout", - main: true, + isMain: true, availability: 1, playtime: 35031, }, { - steamId: 2839, + steamId: "342534298", name: "JustGetAHouse", role: "Flank Scout", - main: false, + isMain: false, availability: 1, playtime: 28811, }, - { - steamId: 2839, - name: "JustGetAHouse", - role: "Pocket Scout", - main: true, - availability: 1, - playtime: 28811, - }, - { - steamId: 2841, - name: "VADIKUS007", - role: "Pocket Soldier", - main: true, - availability: 2, - playtime: 98372, - }, - { - steamId: 2841, - name: "VADIKUS007", - role: "Roamer", - main: false, - availability: 2, - playtime: 98372, - }, - { - steamId: 2282, - name: "Bergman777", - role: "Demoman", - main: true, - availability: 2, - playtime: 47324, - }, - { - steamId: 2083, - name: "IF_YOU_READ_THIS_", - role: "Demoman", - main: true, - availability: 1, - playtime: 32812, - }, - { - steamId: 2842, - name: "BossOfThisGym", - role: "Roamer", - main: false, - availability: 2, - playtime: 12028, - }, - { - steamId: 2842, - name: "BossOfThisGym", - role: "Demoman", - main: false, - availability: 2, - playtime: 12028, - }, - { - steamId: 2842, - name: "BossOfThisGym", - role: "Pocket Scout", - main: false, - availability: 2, - playtime: 12028, - }, - //{ - // steamId: 2843, - // name: "samme1g", - // role: "Medic", - // main: true, - // availability: 2, - //}, - { - steamId: 2843, - name: "samme1g", - role: "Pocket Soldier", - main: false, - availability: 2, - playtime: 50201, - }, - { - steamId: 2843, - name: "samme1g", - role: "Demoman", - main: true, - availability: 2, - playtime: 50201, - }, - { - steamId: 2844, - name: "FarbrorBarbro", - role: "Roamer", - main: true, - availability: 1, - playtime: 4732, - }, - { - steamId: 2844, - name: "FarbrorBarbro", - role: "Pocket Soldier", - main: false, - availability: 1, - playtime: 4732, - }, ]); const availablePlayerRoles = computed(() => { - return availablePlayers.filter((player) => player.role == selectedRole.value); + return availablePlayers.value.filter((player) => player.role == selectedRole.value); }); const definitelyAvailable = computed(() => { @@ -150,7 +51,7 @@ export const useRosterStore = defineStore("roster", () => { return availablePlayerRoles.value.filter((player) => player.availability == 1); }); - function comparator(p1: PlayerTeamRole, p2: PlayerTeamRole) { + function comparator(p1: PlayerTeamRoleFlat, p2: PlayerTeamRoleFlat) { // definitely available > can be available let availabilityDiff = p1.availability - p2.availability; @@ -161,12 +62,12 @@ export const useRosterStore = defineStore("roster", () => { } const mainRoles = computed(() => { - return availablePlayerRoles.value.filter((player) => player.main) + return availablePlayerRoles.value.filter((player) => player.isMain) .sort(comparator); }); const alternateRoles = computed(() => { - return availablePlayerRoles.value.filter((player) => !player.main) + return availablePlayerRoles.value.filter((player) => !player.isMain) .sort(comparator); }); @@ -188,8 +89,8 @@ export const useRosterStore = defineStore("roster", () => { "Medic": "Medic", }); - function selectPlayerForRole(player: PlayerTeamRole, role: string) { - if (player && player.steamId > 0) { + function selectPlayerForRole(player: PlayerTeamRoleFlat, role: string) { + if (player && player.steamId) { const existingRole = Object.keys(selectedPlayers).find((selectedRole) => { return selectedPlayers[selectedRole]?.steamId == player.steamId && role != selectedRole; @@ -203,6 +104,27 @@ export const useRosterStore = defineStore("roster", () => { selectedPlayers[role] = player; } + function fetchAvailablePlayers(startTime: number, teamId: number) { + clientStore.call( + fetchAvailablePlayers.name, + () => client.default.viewAvailableAtTime(startTime.toString(), teamId), + (response) => { + availablePlayers.value = response.players.flatMap((schema) => { + return schema.roles.map((role) => ({ + steamId: schema.player.steamId, + name: schema.player.username, + role: role.role, + isMain: role.isMain, + availability: schema.availability, + playtime: schema.playtime, + })); + }); + + return response; + } + ) + } + return { neededRoles, selectedPlayers, @@ -216,5 +138,6 @@ export const useRosterStore = defineStore("roster", () => { roleNames, mainRoles, alternateRoles, + fetchAvailablePlayers, } }); diff --git a/availabili.tf/src/views/RosterBuilderView.vue b/availabili.tf/src/views/RosterBuilderView.vue index 036fe6b..a49ddad 100644 --- a/availabili.tf/src/views/RosterBuilderView.vue +++ b/availabili.tf/src/views/RosterBuilderView.vue @@ -2,11 +2,15 @@ import PlayerCard from "../components/PlayerCard.vue"; import RoleSlot from "../components/RoleSlot.vue"; import PlayerTeamRole from "../player.ts"; -import { computed, reactive } from "vue"; +import { computed, reactive, onMounted } from "vue"; import { useRosterStore } from "../stores/roster"; +import { useRoute } from "vue-router"; +import moment from "moment"; const rosterStore = useRosterStore(); +const route = useRoute(); + const hasAvailablePlayers = computed(() => { return rosterStore.availablePlayerRoles.length > 0; }); @@ -14,6 +18,10 @@ const hasAvailablePlayers = computed(() => { const hasAlternates = computed(() => { return rosterStore.alternateRoles.length > 0; }); + +onMounted(() => { + rosterStore.fetchAvailablePlayers(route.params.startTime, route.params.teamId); +});