Hide scouted matches from the match list

This patch adds a checkbox to the top of the match list selection
screen for data entry. The checkbox (default checked) will hide
matches that have already been scouted. When matches have been
partially scouted, the teams for which data has already been collected
are greyed out.

Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: I5150029dcf7cac4437fff6108e0ef8af6cea37c2
diff --git a/scouting/www/match_list/match_list.component.css b/scouting/www/match_list/match_list.component.css
index e7c071c..f77be5e 100644
--- a/scouting/www/match_list/match_list.component.css
+++ b/scouting/www/match_list/match_list.component.css
@@ -6,6 +6,10 @@
   background-color: #dc3545;
 }
 
+button:disabled {
+  background-color: #524143;
+}
+
 .blue {
   background-color: #0d6efd;
 }
@@ -22,3 +26,7 @@
   /* minimum touch target size */
   height: 44px;
 }
+
+div.hidden_row {
+  display: none;
+}
diff --git a/scouting/www/match_list/match_list.component.ts b/scouting/www/match_list/match_list.component.ts
index eb5284f..a656a1f 100644
--- a/scouting/www/match_list/match_list.component.ts
+++ b/scouting/www/match_list/match_list.component.ts
@@ -26,21 +26,67 @@
   progressMessage: string = '';
   errorMessage: string = '';
   matchList: Match[] = [];
+  hideCompletedMatches: boolean = true;
 
   constructor(private readonly matchListRequestor: MatchListRequestor) {}
 
+  // Returns a class for the row to hide it if all teams in this match have
+  // already been scouted.
+  getRowClass(match: Match): string {
+    const scouted = match.dataScouted();
+    if (
+      this.hideCompletedMatches &&
+      scouted.r1() &&
+      scouted.r2() &&
+      scouted.r3() &&
+      scouted.b1() &&
+      scouted.b2() &&
+      scouted.b3()
+    ) {
+      return 'hidden_row';
+    }
+    return '';
+  }
+
   setTeamInMatch(teamInMatch: TeamInMatch) {
     this.selectedTeamEvent.emit(teamInMatch);
   }
 
-  teamsInMatch(match: Match): {teamNumber: number; color: 'red' | 'blue'}[] {
+  teamsInMatch(
+    match: Match
+  ): {teamNumber: number; color: 'red' | 'blue'; disabled: boolean}[] {
+    const scouted = match.dataScouted();
     return [
-      {teamNumber: match.r1(), color: 'red'},
-      {teamNumber: match.r2(), color: 'red'},
-      {teamNumber: match.r3(), color: 'red'},
-      {teamNumber: match.b1(), color: 'blue'},
-      {teamNumber: match.b2(), color: 'blue'},
-      {teamNumber: match.b3(), color: 'blue'},
+      {
+        teamNumber: match.r1(),
+        color: 'red',
+        disabled: this.hideCompletedMatches && scouted.r1(),
+      },
+      {
+        teamNumber: match.r2(),
+        color: 'red',
+        disabled: this.hideCompletedMatches && scouted.r2(),
+      },
+      {
+        teamNumber: match.r3(),
+        color: 'red',
+        disabled: this.hideCompletedMatches && scouted.r3(),
+      },
+      {
+        teamNumber: match.b1(),
+        color: 'blue',
+        disabled: this.hideCompletedMatches && scouted.b1(),
+      },
+      {
+        teamNumber: match.b2(),
+        color: 'blue',
+        disabled: this.hideCompletedMatches && scouted.b2(),
+      },
+      {
+        teamNumber: match.b3(),
+        color: 'blue',
+        disabled: this.hideCompletedMatches && scouted.b3(),
+      },
     ];
   }
 
diff --git a/scouting/www/match_list/match_list.ng.html b/scouting/www/match_list/match_list.ng.html
index e890faf..0ebbe4c 100644
--- a/scouting/www/match_list/match_list.ng.html
+++ b/scouting/www/match_list/match_list.ng.html
@@ -2,8 +2,16 @@
   <h2>Matches</h2>
 </div>
 
+<label>
+  <input type="checkbox" [(ngModel)]="hideCompletedMatches" />
+  Hide completed matches
+</label>
+
 <div class="container-fluid">
-  <div class="row" *ngFor="let match of matchList; index as i">
+  <div
+    *ngFor="let match of matchList; index as i"
+    [ngClass]="'row ' + getRowClass(match)"
+  >
     <span class="badge bg-secondary rounded-left">
       {{ displayMatchNumber(match) }}
     </span>
@@ -18,6 +26,7 @@
             })"
         class="match-item"
         [ngClass]="team.color"
+        [disabled]="team.disabled"
       >
         {{ team.teamNumber }}
       </button>