mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 21:56:50 -04:00
Enabled editing of match results before committing.
This commit is contained in:
@@ -460,7 +460,7 @@ func TestSubstituteTeam(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 107, mainArena.currentMatch.Red1)
|
||||
assert.Equal(t, 107, mainArena.AllianceStations["R1"].team.Id)
|
||||
CommitMatchScore(mainArena.currentMatch, &MatchResult{MatchId: mainArena.currentMatch.Id})
|
||||
CommitMatchScore(mainArena.currentMatch, &MatchResult{MatchId: mainArena.currentMatch.Id}, false)
|
||||
match2, _ := db.GetMatchById(match.Id)
|
||||
assert.Equal(t, 107, match2.Red1)
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ func MatchPlayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Saves the given match and result to the database, supplanting any previous result for the match.
|
||||
func CommitMatchScore(match *Match, matchResult *MatchResult) error {
|
||||
func CommitMatchScore(match *Match, matchResult *MatchResult, loadToShowBuffer bool) error {
|
||||
if matchResult.RedScore.CoopertitionSet != matchResult.BlueScore.CoopertitionSet ||
|
||||
matchResult.RedScore.CoopertitionStack != matchResult.BlueScore.CoopertitionStack {
|
||||
// Don't accept the score if the red and blue co-opertition points don't match up.
|
||||
@@ -423,10 +423,12 @@ func CommitMatchScore(match *Match, matchResult *MatchResult) error {
|
||||
matchResult.CorrectEliminationScore()
|
||||
}
|
||||
|
||||
// Store the result in the buffer to be shown in the audience display.
|
||||
mainArena.savedMatch = match
|
||||
mainArena.savedMatchResult = matchResult
|
||||
mainArena.scorePostedNotifier.Notify(nil)
|
||||
if loadToShowBuffer {
|
||||
// Store the result in the buffer to be shown in the audience display.
|
||||
mainArena.savedMatch = match
|
||||
mainArena.savedMatchResult = matchResult
|
||||
mainArena.scorePostedNotifier.Notify(nil)
|
||||
}
|
||||
|
||||
if match.Type == "test" {
|
||||
// Do nothing since this is a test match and doesn't exist in the database.
|
||||
@@ -520,12 +522,15 @@ func CommitMatchScore(match *Match, matchResult *MatchResult) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Saves the realtime result as the final score for the match currently loaded into the arena.
|
||||
func CommitCurrentMatchScore() error {
|
||||
matchResult := MatchResult{MatchId: mainArena.currentMatch.Id,
|
||||
func GetCurrentMatchResult() *MatchResult {
|
||||
return &MatchResult{MatchId: mainArena.currentMatch.Id,
|
||||
RedScore: mainArena.redRealtimeScore.CurrentScore, BlueScore: mainArena.blueRealtimeScore.CurrentScore,
|
||||
RedCards: mainArena.redRealtimeScore.Cards, BlueCards: mainArena.blueRealtimeScore.Cards}
|
||||
return CommitMatchScore(mainArena.currentMatch, &matchResult)
|
||||
}
|
||||
|
||||
// Saves the realtime result as the final score for the match currently loaded into the arena.
|
||||
func CommitCurrentMatchScore() error {
|
||||
return CommitMatchScore(mainArena.currentMatch, GetCurrentMatchResult(), true)
|
||||
}
|
||||
|
||||
// Helper function to implement the required interface for Sort.
|
||||
|
||||
@@ -149,7 +149,7 @@ func TestCommitMatch(t *testing.T) {
|
||||
|
||||
// Committing test match should do nothing.
|
||||
match := &Match{Id: 0, Type: "test", Red1: 101, Red2: 102, Red3: 103, Blue1: 104, Blue2: 105, Blue3: 106}
|
||||
err = CommitMatchScore(match, &MatchResult{MatchId: match.Id})
|
||||
err = CommitMatchScore(match, &MatchResult{MatchId: match.Id}, false)
|
||||
assert.Nil(t, err)
|
||||
matchResult, err := db.GetMatchResultForMatch(match.Id)
|
||||
assert.Nil(t, err)
|
||||
@@ -160,19 +160,19 @@ func TestCommitMatch(t *testing.T) {
|
||||
match.Type = "qualification"
|
||||
db.CreateMatch(match)
|
||||
matchResult = &MatchResult{MatchId: match.Id, BlueScore: Score{AutoRobotSet: true}}
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, matchResult.PlayNumber)
|
||||
match, _ = db.GetMatchById(1)
|
||||
assert.Equal(t, "B", match.Winner)
|
||||
matchResult = &MatchResult{MatchId: match.Id, RedScore: Score{AutoRobotSet: true}}
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, matchResult.PlayNumber)
|
||||
match, _ = db.GetMatchById(1)
|
||||
assert.Equal(t, "R", match.Winner)
|
||||
matchResult = &MatchResult{MatchId: match.Id}
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, matchResult.PlayNumber)
|
||||
match, _ = db.GetMatchById(1)
|
||||
@@ -183,7 +183,7 @@ func TestCommitMatch(t *testing.T) {
|
||||
eventSettings.TbaPublishingEnabled = true
|
||||
var writer bytes.Buffer
|
||||
log.SetOutput(&writer)
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
assert.Nil(t, err)
|
||||
time.Sleep(time.Millisecond * 10) // Allow some time for the asynchronous publishing to happen.
|
||||
assert.Contains(t, writer.String(), "Failed to publish matches")
|
||||
@@ -203,13 +203,13 @@ func TestCommitEliminationTie(t *testing.T) {
|
||||
match := &Match{Id: 0, Type: "qualification", Red1: 1, Red2: 2, Red3: 3, Blue1: 4, Blue2: 5, Blue3: 6}
|
||||
db.CreateMatch(match)
|
||||
matchResult := &MatchResult{MatchId: match.Id, RedScore: Score{AutoToteSet: true, Fouls: []Foul{Foul{}}}}
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
assert.Nil(t, err)
|
||||
match, _ = db.GetMatchById(1)
|
||||
assert.Equal(t, "T", match.Winner)
|
||||
match.Type = "elimination"
|
||||
db.SaveMatch(match)
|
||||
CommitMatchScore(match, matchResult)
|
||||
CommitMatchScore(match, matchResult, false)
|
||||
match, _ = db.GetMatchById(1)
|
||||
assert.Equal(t, "T", match.Winner) // No elimination tiebreakers in 2015.
|
||||
}
|
||||
@@ -230,21 +230,21 @@ func TestCommitCards(t *testing.T) {
|
||||
match := &Match{Id: 0, Type: "qualification", Red1: 1, Red2: 2, Red3: 3, Blue1: 4, Blue2: 5, Blue3: 6}
|
||||
db.CreateMatch(match)
|
||||
matchResult := &MatchResult{MatchId: match.Id, BlueCards: map[string]string{"5": "yellow"}}
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
assert.Nil(t, err)
|
||||
team, _ = db.GetTeamById(5)
|
||||
assert.True(t, team.YellowCard)
|
||||
|
||||
// Check that editing a match result removes a yellow card from a team.
|
||||
matchResult = &MatchResult{MatchId: match.Id}
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
assert.Nil(t, err)
|
||||
team, _ = db.GetTeamById(5)
|
||||
assert.False(t, team.YellowCard)
|
||||
|
||||
// Check that a red card causes a yellow card to stick with a team.
|
||||
matchResult = &MatchResult{MatchId: match.Id, BlueCards: map[string]string{"5": "red"}}
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
assert.Nil(t, err)
|
||||
team, _ = db.GetTeamById(5)
|
||||
assert.True(t, team.YellowCard)
|
||||
@@ -255,7 +255,7 @@ func TestCommitCards(t *testing.T) {
|
||||
db.SaveMatch(match)
|
||||
*matchResult = buildTestMatchResult(match.Id, 10)
|
||||
matchResult.RedCards = map[string]string{"1": "red"}
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, matchResult.RedScoreSummary().Score)
|
||||
assert.Equal(t, 104, matchResult.BlueScoreSummary().Score)
|
||||
|
||||
@@ -66,7 +66,7 @@ func MatchReviewHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Shows the page to edit the results for a match.
|
||||
func MatchReviewEditGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
match, matchResult, err := getMatchResultFromRequest(r)
|
||||
match, matchResult, _, err := getMatchResultFromRequest(r)
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
@@ -96,7 +96,7 @@ func MatchReviewEditGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Updates the results for a match.
|
||||
func MatchReviewEditPostHandler(w http.ResponseWriter, r *http.Request) {
|
||||
match, matchResult, err := getMatchResultFromRequest(r)
|
||||
match, matchResult, isCurrent, err := getMatchResultFromRequest(r)
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
@@ -114,36 +114,52 @@ func MatchReviewEditPostHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = CommitMatchScore(match, matchResult)
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
if isCurrent {
|
||||
// If editing the current match, just save it back to memory.
|
||||
mainArena.redRealtimeScore.CurrentScore = matchResult.RedScore
|
||||
mainArena.blueRealtimeScore.CurrentScore = matchResult.BlueScore
|
||||
mainArena.redRealtimeScore.Cards = matchResult.RedCards
|
||||
mainArena.blueRealtimeScore.Cards = matchResult.BlueCards
|
||||
|
||||
http.Redirect(w, r, "/match_review", 302)
|
||||
http.Redirect(w, r, "/match_play", 302)
|
||||
} else {
|
||||
err = CommitMatchScore(match, matchResult, false)
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/match_review", 302)
|
||||
}
|
||||
}
|
||||
|
||||
// Load the match result for the match referenced in the HTTP query string.
|
||||
func getMatchResultFromRequest(r *http.Request) (*Match, *MatchResult, error) {
|
||||
func getMatchResultFromRequest(r *http.Request) (*Match, *MatchResult, bool, error) {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
// If editing the current match, get it from memory instead of the DB.
|
||||
if vars["matchId"] == "current" {
|
||||
return mainArena.currentMatch, GetCurrentMatchResult(), true, nil
|
||||
}
|
||||
|
||||
matchId, _ := strconv.Atoi(vars["matchId"])
|
||||
match, err := db.GetMatchById(matchId)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, false, err
|
||||
}
|
||||
if match == nil {
|
||||
return nil, nil, fmt.Errorf("Error: No such match: %d", matchId)
|
||||
return nil, nil, false, fmt.Errorf("Error: No such match: %d", matchId)
|
||||
}
|
||||
matchResult, err := db.GetMatchResultForMatch(matchId)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, false, err
|
||||
}
|
||||
if matchResult == nil {
|
||||
// We're scoring a match that hasn't been played yet, but that's okay.
|
||||
matchResult = NewMatchResult()
|
||||
}
|
||||
|
||||
return match, matchResult, nil
|
||||
return match, matchResult, false, nil
|
||||
}
|
||||
|
||||
// Constructs the list of matches to display in the match review interface.
|
||||
|
||||
@@ -74,7 +74,8 @@
|
||||
background-color: #fc0;
|
||||
}
|
||||
.btn-match-play {
|
||||
width: 165px;
|
||||
width: 150px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.label-scoring {
|
||||
background-color: #e66;
|
||||
|
||||
@@ -106,6 +106,7 @@ var handleStatus = function(data) {
|
||||
$("#abortMatch").prop("disabled", true);
|
||||
$("#commitResults").prop("disabled", true);
|
||||
$("#discardResults").prop("disabled", true);
|
||||
$("#editResults").prop("disabled", true);
|
||||
break;
|
||||
case "START_MATCH":
|
||||
case "AUTO_PERIOD":
|
||||
@@ -116,12 +117,14 @@ var handleStatus = function(data) {
|
||||
$("#abortMatch").prop("disabled", false);
|
||||
$("#commitResults").prop("disabled", true);
|
||||
$("#discardResults").prop("disabled", true);
|
||||
$("#editResults").prop("disabled", true);
|
||||
break;
|
||||
case "POST_MATCH":
|
||||
$("#startMatch").prop("disabled", true);
|
||||
$("#abortMatch").prop("disabled", true);
|
||||
$("#commitResults").prop("disabled", false);
|
||||
$("#discardResults").prop("disabled", false);
|
||||
$("#editResults").prop("disabled", false);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -83,7 +83,7 @@ var updateResults = function(alliance) {
|
||||
var prefix = alliance + "Stack" + i;
|
||||
var stack = {Totes: parseInt(formData[prefix + "Totes"]),
|
||||
Container: formData[prefix + "Container"] == "on",
|
||||
Noodle: formData[prefix + "Litter"] == "on"}
|
||||
Litter: formData[prefix + "Litter"] == "on"}
|
||||
result.score.Stacks.push(stack);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
{{define "body"}}
|
||||
<div class="row">
|
||||
<div class="well">
|
||||
<form class="form-horizontal" action="/match_review/{{.Match.Id}}/edit" method="POST">
|
||||
<form class="form-horizontal" method="POST">
|
||||
<fieldset>
|
||||
<legend>Edit Match {{.Match.DisplayName}} Results</legend>
|
||||
<div class="col-lg-6" id="redScore"></div>
|
||||
|
||||
@@ -102,6 +102,11 @@
|
||||
onclick="$('#confirmDiscardResults').modal('show');" disabled>
|
||||
Discard Results
|
||||
</button>
|
||||
<a href="/match_review/current/edit">
|
||||
<button type="button" id="editResults" class="btn btn-default btn-lg btn-match-play" disabled>
|
||||
Edit Results
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row">
|
||||
|
||||
Reference in New Issue
Block a user