Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add compete data to teaminfo #558

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions backend/siarnaq/api/compete/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
views.ScrimmageRequestViewSet,
basename="request",
)
router.register(
r"(?P<episode_id>[^\/.]+)/matchParticipant", views.MatchViewSet, basename="match"
)

urlpatterns = [
path("", include(router.urls)),
Expand Down
32 changes: 32 additions & 0 deletions backend/siarnaq/api/teams/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import structlog
from django.db import transaction
from django.db.models import F, OuterRef, Subquery
from django.shortcuts import get_object_or_404
from drf_spectacular.utils import extend_schema
from rest_framework import filters, mixins, status, viewsets
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from siarnaq.api.compete.models import Match, MatchParticipant
from siarnaq.api.episodes.permissions import IsEpisodeAvailable
from siarnaq.api.teams.exceptions import TeamMaxSizeExceeded
from siarnaq.api.teams.filters import TeamActiveSubmissionFilter, TeamOrderingFilter
Expand Down Expand Up @@ -173,3 +175,33 @@ def avatar(self, request, pk=None, *, episode_id):
titan.upload_image(avatar, profile.get_avatar_path())

return Response(None, status=status.HTTP_204_NO_CONTENT)

@action(
detail=False,
methods=["post"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be get, since it’s a non mutator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need detail = True to get pk

serializer_class=None,
permission_classes=(IsAuthenticated, IsEpisodeAvailable),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might suggest removing IsAuthenticated, to allow this to be viewable by the public

)
def record(self, request, pk=None, *, episode_id):
n8kim1 marked this conversation as resolved.
Show resolved Hide resolved
"""Retrieve the win/loss record of a team"""
team = request.data["id"]
matches = Match.objects.filter(participants__team=team, status="OK!")
n8kim1 marked this conversation as resolved.
Show resolved Hide resolved

matches = Match.objects.annotate(
my_score=Subquery(
MatchParticipant.objects.filter(match=OuterRef("pk"))
.filter(team=team)
.values("score")
),
opponent_score=Subquery(
MatchParticipant.objects.filter(match=OuterRef("pk"))
.exclude(team=team)
.values("score")[:1]
),
).filter(
my_score__isnull=False,
)
apollo1291 marked this conversation as resolved.
Show resolved Hide resolved
win_count = matches.filter(my_score__gt=F("opponent_score")).count()
loss_count = matches.filter(my_score__lt=F("opponent_score")).count()

return Response({"wins": win_count, "losses": loss_count})
39 changes: 13 additions & 26 deletions frontend/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,34 +99,21 @@ class Api {
// clean these calls, fix in #368

// data from scrimmaging
static getOwnTeamMuHistory(callback) {
return Api.getTeamMuHistory(Cookies.get("team_id"), callback);
}

static getTeamMuHistory(team, callback) {
$.get(`${URL}/api/${LEAGUE}/team/${team}/history/`).done((data, status) => {
callback(data);
});
}

static getTeamWinStats(callback) {
return Api.getOtherTeamWinStats(Cookies.get("team_id"), callback);
}

static getOtherTeamWinStats(team, callback) {
this.getTeamMuHistory(team, (data) => {
let wins = 0;
let losses = 0;
data.forEach((entry) => {
if (entry.won === true) {
wins++;
} else if (entry.won === false) {
losses++;
} // entry.won can be null when errors occur, doesn't contribute to win/loss
static getTeamWinStats(team, episode, callback) {
$.ajax({
url: `${URL}/api/team/${episode}/t/record/`,
data: JSON.stringify(team),
type: "POST",
contentType: "application/json",
dataType: "json",
})
.done((data) => {
callback(data);
})
.fail((xhr, status, error) => {
callback(xhr, false);
});

callback([wins, losses]);
});
}

//get data for team with team_id
Expand Down
79 changes: 36 additions & 43 deletions frontend/src/views/teamInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,14 @@ import TeamCard from "../components/teamCard";
import PerfCard from "../components/perfCard";

class RankCard extends Component {
constructor() {
super();
constructor(props) {
super(props);
this.state = {
ranking: null,
rating: this.props.team.profile.rating,
};
}

componentDidMount() {
Api.getTeamRanking(this.props.teamId, this.setRanking);
}

setRanking = (ranking_data) => {
this.setState({ ranking: ranking_data.ranking });
};
componentDidMount() {}

render() {
const { ranking } = this.state;
Expand All @@ -34,10 +28,10 @@ class RankCard extends Component {
</div>
<br></br>
<p style={{ textAlign: "center" }}>
Score:{" "}
{this.props.team.score === -1000000
Rating:{" "}
{this.state.rating === -1000000
? "N/A"
: Math.round(this.props.team.score)}
: Math.round(this.state.rating)}
n8kim1 marked this conversation as resolved.
Show resolved Hide resolved
</p>
</div>
</div>
Expand All @@ -52,17 +46,16 @@ class WinsCard extends Component {
}

render() {
const { wins, draws, losses } = this.state;
return (
<div className="card">
<div className="content">
<div className="col-2-row">
<div className="row-items-box items-box-center items-box-skinny">
<label>wins</label>
<label>Wins:</label>
<h1>{this.props.wins}</h1>
</div>
<div className="row-items-box items-box-center items-box-skinny">
<label>losses</label>
<label>Losses:</label>
n8kim1 marked this conversation as resolved.
Show resolved Hide resolved
<h1>{this.props.losses}</h1>
</div>
</div>
Expand All @@ -82,6 +75,7 @@ class TeamInfo extends Component {
// and the :team_id part makes props.match.params.team_id
// whatever that id is)
id: this.props.match.params.team_id,
episode: this.props.match.params.episode,
team: null,
wins: 0,
losses: 0,
Expand All @@ -98,13 +92,12 @@ class TeamInfo extends Component {
// Commented out since we don't have scrimmages, records, etc.
// Work on this once we are ready to.
// Track in #368.
// Api.getOtherTeamWinStats(teamId, (data) => {
// this.setState({ wins: data[0], losses: data[1] });
// });
}

setTeam = (team) => {
this.setState({ team });
Api.getTeamWinStats(team, this.state.episode, (data) => {
this.setState({ team: team, wins: data["wins"], losses: data["losses"] });
});
};

render() {
Expand All @@ -116,35 +109,35 @@ class TeamInfo extends Component {
<div className="row">
<TeamCard team={team} episode={this.props.match.params.episode} />
</div>
{/* Commented out since we don't have scrimmages, records, etc.
Work on this once we are ready to.
Do in #368 */}
{/* <div className="row">
<div className="col-md-3">
<div className="container-fluid">
<div className="row">
<RankCard teamId={team.id} team={team} />
{
<div className="row">
<div className="col-md-3">
<div className="container-fluid">
<div className="row">
<RankCard teamId={team.id} team={team} />
</div>
</div>
</div>
</div>
<div className="col-md-3">
<div className="container-fluid">
<div className="row">
<WinsCard
wins={this.state.wins}
losses={this.state.losses}
/>
<div className="col-md-3">
<div className="container-fluid">
<div className="row">
<WinsCard
wins={this.state.wins}
losses={this.state.losses}
/>
</div>
</div>
</div>
</div>
<div className="col-md-6">
<div className="container-fluid">
<div className="row">
<PerfCard team={team.id} />

{/*<div className="col-md-6">
<div className="container-fluid">
<div className="row">
<PerfCard team={team.id} />
</div>
</div>
</div>
</div>*/}
</div>
</div> */}
}
</div>
</div>
);
Expand Down