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