Add functionality for viewing available teammates
							parent
							
								
									60f96f43f7
								
							
						
					
					
						commit
						325b3529fe
					
				| 
						 | 
					@ -14,6 +14,7 @@ export type { AddPlayerJson } from './models/AddPlayerJson';
 | 
				
			||||||
export type { CreateTeamJson } from './models/CreateTeamJson';
 | 
					export type { CreateTeamJson } from './models/CreateTeamJson';
 | 
				
			||||||
export type { EditMemberRolesJson } from './models/EditMemberRolesJson';
 | 
					export type { EditMemberRolesJson } from './models/EditMemberRolesJson';
 | 
				
			||||||
export type { PlayerSchema } from './models/PlayerSchema';
 | 
					export type { PlayerSchema } from './models/PlayerSchema';
 | 
				
			||||||
 | 
					export type { PlayerTeamAvailabilityRoleSchema } from './models/PlayerTeamAvailabilityRoleSchema';
 | 
				
			||||||
export type { PutScheduleForm } from './models/PutScheduleForm';
 | 
					export type { PutScheduleForm } from './models/PutScheduleForm';
 | 
				
			||||||
export type { RoleSchema } from './models/RoleSchema';
 | 
					export type { RoleSchema } from './models/RoleSchema';
 | 
				
			||||||
export type { TeamInviteSchema } from './models/TeamInviteSchema';
 | 
					export type { TeamInviteSchema } from './models/TeamInviteSchema';
 | 
				
			||||||
| 
						 | 
					@ -22,7 +23,8 @@ export { TeamRole } from './models/TeamRole';
 | 
				
			||||||
export type { TeamSchema } from './models/TeamSchema';
 | 
					export type { TeamSchema } from './models/TeamSchema';
 | 
				
			||||||
export type { ValidationError } from './models/ValidationError';
 | 
					export type { ValidationError } from './models/ValidationError';
 | 
				
			||||||
export type { ValidationErrorElement } from './models/ValidationErrorElement';
 | 
					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 { ViewScheduleForm } from './models/ViewScheduleForm';
 | 
				
			||||||
export type { ViewScheduleResponse } from './models/ViewScheduleResponse';
 | 
					export type { ViewScheduleResponse } from './models/ViewScheduleResponse';
 | 
				
			||||||
export type { ViewTeamMembersResponse } from './models/ViewTeamMembersResponse';
 | 
					export type { ViewTeamMembersResponse } from './models/ViewTeamMembersResponse';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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<RoleSchema>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
/* istanbul ignore file */
 | 
					/* istanbul ignore file */
 | 
				
			||||||
/* tslint:disable */
 | 
					/* tslint:disable */
 | 
				
			||||||
/* eslint-disable */
 | 
					/* eslint-disable */
 | 
				
			||||||
export type ViewAvailablePlayersForm = {
 | 
					export type ViewAvailablePlayersQuery = {
 | 
				
			||||||
    startTime: string;
 | 
					    startTime: string;
 | 
				
			||||||
    teamId: number;
 | 
					    teamId: number;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -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<PlayerTeamAvailabilityRoleSchema>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ import type { PlayerSchema } from '../models/PlayerSchema';
 | 
				
			||||||
import type { PutScheduleForm } from '../models/PutScheduleForm';
 | 
					import type { PutScheduleForm } from '../models/PutScheduleForm';
 | 
				
			||||||
import type { TeamInviteSchema } from '../models/TeamInviteSchema';
 | 
					import type { TeamInviteSchema } from '../models/TeamInviteSchema';
 | 
				
			||||||
import type { TeamInviteSchemaList } from '../models/TeamInviteSchemaList';
 | 
					import type { TeamInviteSchemaList } from '../models/TeamInviteSchemaList';
 | 
				
			||||||
 | 
					import type { ViewAvailablePlayersResponse } from '../models/ViewAvailablePlayersResponse';
 | 
				
			||||||
import type { ViewScheduleResponse } from '../models/ViewScheduleResponse';
 | 
					import type { ViewScheduleResponse } from '../models/ViewScheduleResponse';
 | 
				
			||||||
import type { ViewTeamMembersResponseList } from '../models/ViewTeamMembersResponseList';
 | 
					import type { ViewTeamMembersResponseList } from '../models/ViewTeamMembersResponseList';
 | 
				
			||||||
import type { ViewTeamResponse } from '../models/ViewTeamResponse';
 | 
					import type { ViewTeamResponse } from '../models/ViewTeamResponse';
 | 
				
			||||||
| 
						 | 
					@ -130,16 +131,16 @@ export class DefaultService {
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * view_available <GET>
 | 
					     * view_available_at_time <GET>
 | 
				
			||||||
     * @param startTime
 | 
					     * @param startTime
 | 
				
			||||||
     * @param teamId
 | 
					     * @param teamId
 | 
				
			||||||
     * @returns void
 | 
					     * @returns ViewAvailablePlayersResponse OK
 | 
				
			||||||
     * @throws ApiError
 | 
					     * @throws ApiError
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public getApiScheduleViewAvailable(
 | 
					    public viewAvailableAtTime(
 | 
				
			||||||
        startTime: string,
 | 
					        startTime: string,
 | 
				
			||||||
        teamId: number,
 | 
					        teamId: number,
 | 
				
			||||||
    ): CancelablePromise<void> {
 | 
					    ): CancelablePromise<ViewAvailablePlayersResponse> {
 | 
				
			||||||
        return this.httpRequest.request({
 | 
					        return this.httpRequest.request({
 | 
				
			||||||
            method: 'GET',
 | 
					            method: 'GET',
 | 
				
			||||||
            url: '/api/schedule/view-available',
 | 
					            url: '/api/schedule/view-available',
 | 
				
			||||||
| 
						 | 
					@ -147,6 +148,9 @@ export class DefaultService {
 | 
				
			||||||
                'startTime': startTime,
 | 
					                'startTime': startTime,
 | 
				
			||||||
                'teamId': teamId,
 | 
					                'teamId': teamId,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            errors: {
 | 
				
			||||||
 | 
					                422: `Unprocessable Entity`,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,11 +3,11 @@ export interface Player {
 | 
				
			||||||
  name: string;
 | 
					  name: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface PlayerTeamRole {
 | 
					export interface PlayerTeamRoleFlat {
 | 
				
			||||||
  steamId: number;
 | 
					  steamId: string;
 | 
				
			||||||
  name: string;
 | 
					  name: string;
 | 
				
			||||||
  role: string;
 | 
					  role: string;
 | 
				
			||||||
  main: boolean;
 | 
					  isMain: boolean;
 | 
				
			||||||
  availability: number;
 | 
					  availability: number;
 | 
				
			||||||
  playtime: number;
 | 
					  playtime: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ const router = createRouter({
 | 
				
			||||||
      component: ScheduleView
 | 
					      component: ScheduleView
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/schedule/roster",
 | 
					      path: "/schedule/roster/:teamId/:startTime",
 | 
				
			||||||
      name: "roster-builder",
 | 
					      name: "roster-builder",
 | 
				
			||||||
      component: RosterBuilderView
 | 
					      component: RosterBuilderView
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,12 @@
 | 
				
			||||||
import { type Player, type PlayerTeamRole } from "@/player";
 | 
					import { type Player, type PlayerTeamRoleFlat } from "@/player";
 | 
				
			||||||
import { defineStore } from "pinia";
 | 
					import { defineStore } from "pinia";
 | 
				
			||||||
import { computed, reactive, ref, type Reactive, type Ref } from "vue";
 | 
					import { computed, reactive, ref, type Reactive, type Ref } from "vue";
 | 
				
			||||||
 | 
					import { useClientStore } from "./client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const useRosterStore = defineStore("roster", () => {
 | 
					export const useRosterStore = defineStore("roster", () => {
 | 
				
			||||||
 | 
					  const clientStore = useClientStore();
 | 
				
			||||||
 | 
					  const client = clientStore.client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const neededRoles: Reactive<Array<String>> = reactive([
 | 
					  const neededRoles: Reactive<Array<String>> = reactive([
 | 
				
			||||||
    "PocketScout",
 | 
					    "PocketScout",
 | 
				
			||||||
    "FlankScout",
 | 
					    "FlankScout",
 | 
				
			||||||
| 
						 | 
					@ -12,134 +16,31 @@ export const useRosterStore = defineStore("roster", () => {
 | 
				
			||||||
    "Medic",
 | 
					    "Medic",
 | 
				
			||||||
  ]);
 | 
					  ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const selectedPlayers: Reactive<{ [key: string]: PlayerTeamRole }> = reactive({});
 | 
					  const selectedPlayers: Reactive<{ [key: string]: PlayerTeamRoleFlat }> = reactive({});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const selectedRole: Ref<String | undefined> = ref(undefined);
 | 
					  const selectedRole: Ref<String | undefined> = ref(undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const availablePlayers: Reactive<Array<PlayerTeamRole>> = reactive([
 | 
					  const availablePlayers: Ref<Array<PlayerTeamRoleFlat>> = ref([
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      steamId: 2840,
 | 
					      steamId: "342534598",
 | 
				
			||||||
      name: "Wesker U",
 | 
					      name: "Wesker U",
 | 
				
			||||||
      role: "Flank Scout",
 | 
					      role: "Flank Scout",
 | 
				
			||||||
      main: true,
 | 
					      isMain: true,
 | 
				
			||||||
      availability: 1,
 | 
					      availability: 1,
 | 
				
			||||||
      playtime: 35031,
 | 
					      playtime: 35031,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      steamId: 2839,
 | 
					      steamId: "342534298",
 | 
				
			||||||
      name: "JustGetAHouse",
 | 
					      name: "JustGetAHouse",
 | 
				
			||||||
      role: "Flank Scout",
 | 
					      role: "Flank Scout",
 | 
				
			||||||
      main: false,
 | 
					      isMain: false,
 | 
				
			||||||
      availability: 1,
 | 
					      availability: 1,
 | 
				
			||||||
      playtime: 28811,
 | 
					      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(() => {
 | 
					  const availablePlayerRoles = computed(() => {
 | 
				
			||||||
    return availablePlayers.filter((player) => player.role == selectedRole.value);
 | 
					    return availablePlayers.value.filter((player) => player.role == selectedRole.value);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const definitelyAvailable = computed(() => {
 | 
					  const definitelyAvailable = computed(() => {
 | 
				
			||||||
| 
						 | 
					@ -150,7 +51,7 @@ export const useRosterStore = defineStore("roster", () => {
 | 
				
			||||||
    return availablePlayerRoles.value.filter((player) => player.availability == 1);
 | 
					    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
 | 
					    // definitely available > can be available
 | 
				
			||||||
    let availabilityDiff = p1.availability - p2.availability;
 | 
					    let availabilityDiff = p1.availability - p2.availability;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,12 +62,12 @@ export const useRosterStore = defineStore("roster", () => {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const mainRoles = computed(() => {
 | 
					  const mainRoles = computed(() => {
 | 
				
			||||||
    return availablePlayerRoles.value.filter((player) => player.main)
 | 
					    return availablePlayerRoles.value.filter((player) => player.isMain)
 | 
				
			||||||
      .sort(comparator);
 | 
					      .sort(comparator);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const alternateRoles = computed(() => {
 | 
					  const alternateRoles = computed(() => {
 | 
				
			||||||
    return availablePlayerRoles.value.filter((player) => !player.main)
 | 
					    return availablePlayerRoles.value.filter((player) => !player.isMain)
 | 
				
			||||||
      .sort(comparator);
 | 
					      .sort(comparator);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -188,8 +89,8 @@ export const useRosterStore = defineStore("roster", () => {
 | 
				
			||||||
    "Medic": "Medic",
 | 
					    "Medic": "Medic",
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function selectPlayerForRole(player: PlayerTeamRole, role: string) {
 | 
					  function selectPlayerForRole(player: PlayerTeamRoleFlat, role: string) {
 | 
				
			||||||
    if (player && player.steamId > 0) {
 | 
					    if (player && player.steamId) {
 | 
				
			||||||
      const existingRole = Object.keys(selectedPlayers).find((selectedRole) => {
 | 
					      const existingRole = Object.keys(selectedPlayers).find((selectedRole) => {
 | 
				
			||||||
        return selectedPlayers[selectedRole]?.steamId == player.steamId &&
 | 
					        return selectedPlayers[selectedRole]?.steamId == player.steamId &&
 | 
				
			||||||
          role != selectedRole;
 | 
					          role != selectedRole;
 | 
				
			||||||
| 
						 | 
					@ -203,6 +104,27 @@ export const useRosterStore = defineStore("roster", () => {
 | 
				
			||||||
    selectedPlayers[role] = player;
 | 
					    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 {
 | 
					  return {
 | 
				
			||||||
    neededRoles,
 | 
					    neededRoles,
 | 
				
			||||||
    selectedPlayers,
 | 
					    selectedPlayers,
 | 
				
			||||||
| 
						 | 
					@ -216,5 +138,6 @@ export const useRosterStore = defineStore("roster", () => {
 | 
				
			||||||
    roleNames,
 | 
					    roleNames,
 | 
				
			||||||
    mainRoles,
 | 
					    mainRoles,
 | 
				
			||||||
    alternateRoles,
 | 
					    alternateRoles,
 | 
				
			||||||
 | 
					    fetchAvailablePlayers,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,11 +2,15 @@
 | 
				
			||||||
import PlayerCard from "../components/PlayerCard.vue";
 | 
					import PlayerCard from "../components/PlayerCard.vue";
 | 
				
			||||||
import RoleSlot from "../components/RoleSlot.vue";
 | 
					import RoleSlot from "../components/RoleSlot.vue";
 | 
				
			||||||
import PlayerTeamRole from "../player.ts";
 | 
					import PlayerTeamRole from "../player.ts";
 | 
				
			||||||
import { computed, reactive } from "vue";
 | 
					import { computed, reactive, onMounted } from "vue";
 | 
				
			||||||
import { useRosterStore } from "../stores/roster";
 | 
					import { useRosterStore } from "../stores/roster";
 | 
				
			||||||
 | 
					import { useRoute } from "vue-router";
 | 
				
			||||||
 | 
					import moment from "moment";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const rosterStore = useRosterStore();
 | 
					const rosterStore = useRosterStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const route = useRoute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const hasAvailablePlayers = computed(() => {
 | 
					const hasAvailablePlayers = computed(() => {
 | 
				
			||||||
  return rosterStore.availablePlayerRoles.length > 0;
 | 
					  return rosterStore.availablePlayerRoles.length > 0;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -14,6 +18,10 @@ const hasAvailablePlayers = computed(() => {
 | 
				
			||||||
const hasAlternates = computed(() => {
 | 
					const hasAlternates = computed(() => {
 | 
				
			||||||
  return rosterStore.alternateRoles.length > 0;
 | 
					  return rosterStore.alternateRoles.length > 0;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					  rosterStore.fetchAvailablePlayers(route.params.startTime, route.params.teamId);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
| 
						 | 
					@ -21,7 +29,10 @@ const hasAlternates = computed(() => {
 | 
				
			||||||
    <div class="top">
 | 
					    <div class="top">
 | 
				
			||||||
      <h1 class="roster-title">
 | 
					      <h1 class="roster-title">
 | 
				
			||||||
        Roster for Snus Brotherhood
 | 
					        Roster for Snus Brotherhood
 | 
				
			||||||
        <em class="aside date">Aug. 13, 2036 @ 11:30 PM EST</em>
 | 
					        <em class="aside date">
 | 
				
			||||||
 | 
					          @
 | 
				
			||||||
 | 
					          {{ moment(startTime).format("L LT") }}
 | 
				
			||||||
 | 
					        </em>
 | 
				
			||||||
      </h1>
 | 
					      </h1>
 | 
				
			||||||
      <div class="button-group">
 | 
					      <div class="button-group">
 | 
				
			||||||
        <button>Cancel</button>
 | 
					        <button>Cancel</button>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,6 @@ def index():
 | 
				
			||||||
    return "test"
 | 
					    return "test"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@api_login.get("/get-user")
 | 
					@api_login.get("/get-user")
 | 
				
			||||||
@requires_authentication
 | 
					 | 
				
			||||||
@spec.validate(
 | 
					@spec.validate(
 | 
				
			||||||
    resp=Response(
 | 
					    resp=Response(
 | 
				
			||||||
        HTTP_200=PlayerSchema,
 | 
					        HTTP_200=PlayerSchema,
 | 
				
			||||||
| 
						 | 
					@ -29,11 +28,9 @@ def index():
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    operation_id="get_user"
 | 
					    operation_id="get_user"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					@requires_authentication
 | 
				
			||||||
def get_user(player: Player, auth_session: AuthSession):
 | 
					def get_user(player: Player, auth_session: AuthSession):
 | 
				
			||||||
    return PlayerSchema(
 | 
					    return PlayerSchema.from_model(player).dict(by_alias=True)
 | 
				
			||||||
        steam_id=str(player.steam_id),
 | 
					 | 
				
			||||||
        username=player.username,
 | 
					 | 
				
			||||||
    ).dict(by_alias=True), 200
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@api_login.post("/authenticate")
 | 
					@api_login.post("/authenticate")
 | 
				
			||||||
def steam_authenticate():
 | 
					def steam_authenticate():
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,10 @@ class PlayerSchema(spec.BaseModel):
 | 
				
			||||||
    steam_id: str
 | 
					    steam_id: str
 | 
				
			||||||
    username: str
 | 
					    username: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def from_model(cls, player: Player):
 | 
				
			||||||
 | 
					        return cls(steam_id=str(player.steam_id), username=player.username)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from models.auth_session import AuthSession
 | 
					from models.auth_session import AuthSession
 | 
				
			||||||
from models.player_team import PlayerTeam
 | 
					from models.player_team import PlayerTeam
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
from datetime import datetime
 | 
					from datetime import datetime, timedelta
 | 
				
			||||||
 | 
					import spec
 | 
				
			||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
 | 
					from sqlalchemy.orm import Mapped, mapped_column, relationship
 | 
				
			||||||
from sqlalchemy.schema import ForeignKeyConstraint
 | 
					from sqlalchemy.schema import ForeignKeyConstraint
 | 
				
			||||||
from sqlalchemy.types import Integer
 | 
					from sqlalchemy.types import Integer
 | 
				
			||||||
| 
						 | 
					@ -28,3 +29,12 @@ class PlayerTeamAvailability(app_db.BaseModel):
 | 
				
			||||||
            [PlayerTeam.player_id, PlayerTeam.team_id]
 | 
					            [PlayerTeam.player_id, PlayerTeam.team_id]
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PlayerTeamAvailabilityRoleSchema(spec.BaseModel):
 | 
				
			||||||
 | 
					    from models.player import PlayerSchema
 | 
				
			||||||
 | 
					    from models.player_team_role import RoleSchema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    player: PlayerSchema
 | 
				
			||||||
 | 
					    playtime: int
 | 
				
			||||||
 | 
					    availability: int
 | 
				
			||||||
 | 
					    roles: list[RoleSchema]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
import enum
 | 
					import enum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import spec
 | 
				
			||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
 | 
					from sqlalchemy.orm import Mapped, mapped_column, relationship
 | 
				
			||||||
from sqlalchemy.schema import ForeignKeyConstraint
 | 
					from sqlalchemy.schema import ForeignKeyConstraint
 | 
				
			||||||
from sqlalchemy.types import Boolean, Enum
 | 
					from sqlalchemy.types import Boolean, Enum
 | 
				
			||||||
| 
						 | 
					@ -46,3 +47,11 @@ class PlayerTeamRole(app_db.BaseModel):
 | 
				
			||||||
            [PlayerTeam.player_id, PlayerTeam.team_id]
 | 
					            [PlayerTeam.player_id, PlayerTeam.team_id]
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RoleSchema(spec.BaseModel):
 | 
				
			||||||
 | 
					    role: str
 | 
				
			||||||
 | 
					    is_main: bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def from_model(cls, role: PlayerTeamRole):
 | 
				
			||||||
 | 
					        return cls(role=role.role.name, is_main=role.is_main)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,11 +2,12 @@ import datetime
 | 
				
			||||||
from typing import cast
 | 
					from typing import cast
 | 
				
			||||||
from flask import Blueprint, abort, jsonify, make_response, request
 | 
					from flask import Blueprint, abort, jsonify, make_response, request
 | 
				
			||||||
from spectree import Response
 | 
					from spectree import Response
 | 
				
			||||||
 | 
					from sqlalchemy.orm import joinedload
 | 
				
			||||||
from app_db import db
 | 
					from app_db import db
 | 
				
			||||||
from models.player import Player
 | 
					from models.player import Player, PlayerSchema
 | 
				
			||||||
from models.player_team import PlayerTeam
 | 
					from models.player_team import PlayerTeam
 | 
				
			||||||
from models.player_team_availability import PlayerTeamAvailability
 | 
					from models.player_team_availability import PlayerTeamAvailability, PlayerTeamAvailabilityRoleSchema
 | 
				
			||||||
from models.player_team_role import PlayerTeamRole
 | 
					from models.player_team_role import PlayerTeamRole, RoleSchema
 | 
				
			||||||
from middleware import requires_authentication
 | 
					from middleware import requires_authentication
 | 
				
			||||||
from spec import spec, BaseModel
 | 
					from spec import spec, BaseModel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -184,20 +185,32 @@ def put(json: PutScheduleForm, player: Player, **kwargs):
 | 
				
			||||||
    db.session.commit()
 | 
					    db.session.commit()
 | 
				
			||||||
    return make_response({ }, 200)
 | 
					    return make_response({ }, 200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ViewAvailablePlayersForm(BaseModel):
 | 
					class ViewAvailablePlayersQuery(BaseModel):
 | 
				
			||||||
    start_time: datetime.datetime
 | 
					    start_time: datetime.datetime
 | 
				
			||||||
    team_id: int
 | 
					    team_id: int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ViewAvailablePlayersResponse(BaseModel):
 | 
				
			||||||
 | 
					    players: list[PlayerTeamAvailabilityRoleSchema]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@api_schedule.get("/view-available")
 | 
					@api_schedule.get("/view-available")
 | 
				
			||||||
@spec.validate()
 | 
					@spec.validate(
 | 
				
			||||||
 | 
					    resp=Response(
 | 
				
			||||||
 | 
					        HTTP_200=ViewAvailablePlayersResponse,
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    operation_id="view_available_at_time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@requires_authentication
 | 
					@requires_authentication
 | 
				
			||||||
def view_available(query: ViewAvailablePlayersForm, player: Player, **kwargs):
 | 
					def view_available_at_time(query: ViewAvailablePlayersQuery, player: Player, **kwargs):
 | 
				
			||||||
    start_time = query.start_time
 | 
					    start_time = query.start_time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    availability = db.session.query(
 | 
					    records = db.session.query(
 | 
				
			||||||
        PlayerTeamAvailability
 | 
					        PlayerTeamAvailability
 | 
				
			||||||
    ).where(
 | 
					    ).join(
 | 
				
			||||||
        PlayerTeamAvailability.player_id == player.steam_id
 | 
					        PlayerTeam
 | 
				
			||||||
 | 
					    ).join(
 | 
				
			||||||
 | 
					        Player
 | 
				
			||||||
 | 
					    ).join(
 | 
				
			||||||
 | 
					        PlayerTeamRole
 | 
				
			||||||
    ).where(
 | 
					    ).where(
 | 
				
			||||||
        PlayerTeamAvailability.team_id == query.team_id
 | 
					        PlayerTeamAvailability.team_id == query.team_id
 | 
				
			||||||
    ).where(
 | 
					    ).where(
 | 
				
			||||||
| 
						 | 
					@ -205,22 +218,18 @@ def view_available(query: ViewAvailablePlayersForm, player: Player, **kwargs):
 | 
				
			||||||
            (PlayerTeamAvailability.end_time > start_time)
 | 
					            (PlayerTeamAvailability.end_time > start_time)
 | 
				
			||||||
    ).all()
 | 
					    ).all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def map_roles_to_json(roles: list[PlayerTeamRole],
 | 
					    def map_to_response(player_avail: PlayerTeamAvailability):
 | 
				
			||||||
                          player_team: PlayerTeam,
 | 
					        player_team = player_avail.player_team
 | 
				
			||||||
                          entry: PlayerTeamAvailability):
 | 
					        player = player_team.player
 | 
				
			||||||
        for role in roles:
 | 
					 | 
				
			||||||
            yield {
 | 
					 | 
				
			||||||
                "steamId": entry.player_id,
 | 
					 | 
				
			||||||
                "username": entry.player_team.player.username,
 | 
					 | 
				
			||||||
                "role": role.role.name,
 | 
					 | 
				
			||||||
                "isMain": role.is_main,
 | 
					 | 
				
			||||||
                "availability": entry.availability,
 | 
					 | 
				
			||||||
                "playtime": int(player_team.playtime.total_seconds()),
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def map_availability_to_json(entry: PlayerTeamAvailability):
 | 
					 | 
				
			||||||
        player_team = entry.player_team
 | 
					 | 
				
			||||||
        player_roles = player_team.player_roles
 | 
					        player_roles = player_team.player_roles
 | 
				
			||||||
        return list(map_roles_to_json(player_roles, player_team, entry))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return jsonify(list(map(map_availability_to_json, availability)))
 | 
					        return PlayerTeamAvailabilityRoleSchema(
 | 
				
			||||||
 | 
					            player=PlayerSchema.from_model(player),
 | 
				
			||||||
 | 
					            playtime=int(player_team.playtime.total_seconds()),
 | 
				
			||||||
 | 
					            availability=player_avail.availability,
 | 
				
			||||||
 | 
					            roles=list(map(RoleSchema.from_model, player_roles)),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ViewAvailablePlayersResponse(
 | 
				
			||||||
 | 
					        players=list(map(map_to_response, records))
 | 
				
			||||||
 | 
					    ).dict(by_alias=True), 200
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ from app_db import db
 | 
				
			||||||
from models.player import Player, PlayerSchema
 | 
					from models.player import Player, PlayerSchema
 | 
				
			||||||
from models.player_team import PlayerTeam
 | 
					from models.player_team import PlayerTeam
 | 
				
			||||||
from models.player_team_availability import PlayerTeamAvailability
 | 
					from models.player_team_availability import PlayerTeamAvailability
 | 
				
			||||||
from models.player_team_role import PlayerTeamRole
 | 
					from models.player_team_role import PlayerTeamRole, RoleSchema
 | 
				
			||||||
from models.team import Team, TeamSchema
 | 
					from models.team import Team, TeamSchema
 | 
				
			||||||
from models.team_invite import TeamInvite, TeamInviteSchema
 | 
					from models.team_invite import TeamInvite, TeamInviteSchema
 | 
				
			||||||
from middleware import requires_authentication
 | 
					from middleware import requires_authentication
 | 
				
			||||||
| 
						 | 
					@ -302,10 +302,6 @@ def fetch_teams_for_player(player: Player, team_id: int | None):
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ViewTeamMembersResponse(PlayerSchema):
 | 
					class ViewTeamMembersResponse(PlayerSchema):
 | 
				
			||||||
    class RoleSchema(BaseModel):
 | 
					 | 
				
			||||||
        role: str
 | 
					 | 
				
			||||||
        is_main: bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    roles: list[RoleSchema]
 | 
					    roles: list[RoleSchema]
 | 
				
			||||||
    availability: list[int]
 | 
					    availability: list[int]
 | 
				
			||||||
    playtime: float
 | 
					    playtime: float
 | 
				
			||||||
| 
						 | 
					@ -346,7 +342,7 @@ def view_team_members(player: Player, team_id: int, **kwargs):
 | 
				
			||||||
        abort(404)
 | 
					        abort(404)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def map_role_to_schema(player_team_role: PlayerTeamRole):
 | 
					    def map_role_to_schema(player_team_role: PlayerTeamRole):
 | 
				
			||||||
        return ViewTeamMembersResponse.RoleSchema(
 | 
					        return RoleSchema(
 | 
				
			||||||
            role=player_team_role.role.name,
 | 
					            role=player_team_role.role.name,
 | 
				
			||||||
            is_main=player_team_role.is_main,
 | 
					            is_main=player_team_role.is_main,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -376,7 +372,7 @@ def view_team_members(player: Player, team_id: int, **kwargs):
 | 
				
			||||||
    return list(map(map_to_response, player_teams))
 | 
					    return list(map(map_to_response, player_teams))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EditMemberRolesJson(BaseModel):
 | 
					class EditMemberRolesJson(BaseModel):
 | 
				
			||||||
    roles: list[ViewTeamMembersResponse.RoleSchema]
 | 
					    roles: list[RoleSchema]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@api_team.patch("/id/<team_id>/edit-player/<target_player_id>")
 | 
					@api_team.patch("/id/<team_id>/edit-player/<target_player_id>")
 | 
				
			||||||
@spec.validate(
 | 
					@spec.validate(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue