Add pit image submission test
Add submission test and add pit images to view tab.
Signed-off-by: Emily Markova <emily.markova@gmail.com>
Change-Id: I01e227f19c0622fcca09186662ab25ab34599045
diff --git a/scouting/www/view/view.component.css b/scouting/www/view/view.component.css
index e220645..7811d2d 100644
--- a/scouting/www/view/view.component.css
+++ b/scouting/www/view/view.component.css
@@ -1,3 +1,23 @@
* {
padding: 10px;
}
+
+.collapse-border {
+ border-collapse: collapse;
+ border-color: transparent;
+ border-width: 0;
+ overflow: auto;
+}
+
+.align-images {
+ word-wrap: break-word;
+ display: flex;
+ margin: 5px;
+ justify-content: center;
+ align-items: center;
+}
+
+.align-text {
+ text-align: center;
+ vertical-align: middle;
+}
diff --git a/scouting/www/view/view.component.ts b/scouting/www/view/view.component.ts
index 26e816b..64b0680 100644
--- a/scouting/www/view/view.component.ts
+++ b/scouting/www/view/view.component.ts
@@ -9,6 +9,12 @@
Stats2023,
Request2023DataScoutingResponse,
} from '../../webserver/requests/messages/request_2023_data_scouting_response_generated';
+
+import {
+ PitImage,
+ RequestAllPitImagesResponse,
+} from '../../webserver/requests/messages/request_all_pit_images_response_generated';
+
import {
Note,
RequestAllNotesResponse,
@@ -18,7 +24,7 @@
import {ViewDataRequestor} from '../rpc';
-type Source = 'Notes' | 'Stats2023' | 'DriverRanking';
+type Source = 'Notes' | 'Stats2023' | 'PitImages' | 'DriverRanking';
//TODO(Filip): Deduplicate
const COMP_LEVEL_LABELS = {
@@ -56,6 +62,7 @@
// Stores the corresponding data.
noteList: Note[] = [];
driverRankingList: Ranking[] = [];
+ pitImageList: PitImage[][] = [];
statList: Stats2023[] = [];
// Fetch notes on initialization.
@@ -74,13 +81,23 @@
.team()
.localeCompare(a[0].team(), undefined, {numeric: true});
});
+ this.pitImageList.sort(function (a, b) {
+ return b[0]
+ .teamNumber()
+ .localeCompare(a[0].teamNumber(), undefined, {numeric: true});
+ });
this.statList.sort((a, b) => b.matchNumber() - a.matchNumber());
} else {
this.driverRankingList.sort((a, b) => a.matchNumber() - b.matchNumber());
this.noteList.sort(function (a, b) {
- return a[0]
+ return b[0]
.team()
- .localeCompare(b[0].team(), undefined, {numeric: true});
+ .localeCompare(a[0].team(), undefined, {numeric: true});
+ });
+ this.pitImageList.sort(function (a, b) {
+ return a[0]
+ .teamNumber()
+ .localeCompare(b[0].teamNumber(), undefined, {numeric: true});
});
this.statList.sort((a, b) => a.matchNumber() - b.matchNumber());
}
@@ -95,6 +112,7 @@
this.noteList = [];
this.driverRankingList = [];
this.statList = [];
+ this.pitImageList = [];
this.fetchCurrentSource();
}
@@ -109,6 +127,10 @@
this.fetchStats2023();
}
+ case 'PitImages': {
+ this.fetchPitImages();
+ }
+
case 'DriverRanking': {
this.fetchDriverRanking();
}
@@ -211,6 +233,42 @@
}
}
+ // Fetch all pit image data and store in pitImageList.
+ async fetchPitImages() {
+ this.progressMessage = 'Fetching pit image list. Please be patient.';
+ this.errorMessage = '';
+
+ try {
+ const initialPitImageList =
+ await this.viewDataRequestor.fetchPitImagesList();
+ let officialPitImageList = [];
+ // Use iteration to make an array of arrays containing pit image data for individual teams.
+ // Ex. [ [ {971PitImageData} , {971PitImage2Data} ], [ {432PitImageData} ] , [ {213PitImageData} ] ]
+ for (let pitImage of initialPitImageList) {
+ let found = false;
+ for (let arr of officialPitImageList) {
+ if (arr[0].teamNumber() == pitImage.teamNumber()) {
+ arr.push(pitImage);
+ found = true;
+ }
+ }
+ if (!found) {
+ officialPitImageList.push([pitImage]);
+ }
+ }
+ // Sort the arrays based on image file names so their order is predictable.
+ for (let arr of officialPitImageList) {
+ arr.sort((a, b) => (a.imagePath() > b.imagePath() ? 1 : -1));
+ }
+ this.pitImageList = officialPitImageList;
+ this.sortData();
+ this.progressMessage = 'Successfully fetched pit image list.';
+ } catch (e) {
+ this.errorMessage = e;
+ this.progressMessage = '';
+ }
+ }
+
// Fetch all data scouting (stats) data and store in statList.
async fetchStats2023() {
this.progressMessage = 'Fetching stats list. Please be patient.';
diff --git a/scouting/www/view/view.ng.html b/scouting/www/view/view.ng.html
index ee2c62f..239548c 100644
--- a/scouting/www/view/view.ng.html
+++ b/scouting/www/view/view.ng.html
@@ -34,6 +34,16 @@
<a
class="dropdown-item"
href="#"
+ (click)="switchDataSource('PitImages')"
+ id="pit_images_source_dropdown"
+ >
+ PitImages
+ </a>
+ </li>
+ <li>
+ <a
+ class="dropdown-item"
+ href="#"
(click)="switchDataSource('DriverRanking')"
id="driver_ranking_source_dropdown"
>
@@ -123,6 +133,42 @@
</tbody>
</table>
</div>
+ <!-- Pit Images Data Display. -->
+ <div *ngSwitchCase="'PitImages'">
+ <table class="table collapse-border">
+ <thead>
+ <tr>
+ <th scope="col" class="d-flex flex-row">
+ <div class="align-self-center">Team</div>
+ <div class="align-self-center" *ngIf="ascendingSort">
+ <i (click)="sortData()" class="bi bi-caret-up"></i>
+ </div>
+ <div class="align-self-center" *ngIf="!ascendingSort">
+ <i (click)="sortData()" class="bi bi-caret-down"></i>
+ </div>
+ </th>
+ <th scope="col" style="max-width: 200px; max-height: 200px">
+ Image(s)
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let pitImageArr of pitImageList">
+ <th scope="row" class="align-text">
+ {{pitImageArr[0].teamNumber()}}
+ </th>
+ <td style="display: flex">
+ <div *ngFor="let pitImage of pitImageArr" class="align-images">
+ <img
+ src="/sha256/{{ pitImage.checkSum() }}/{{ pitImage.imagePath() }}"
+ style="max-width: 50px; max-height: 50px; padding: 0; margin: 0"
+ />
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
<!-- Driver Ranking Data Display. -->
<div *ngSwitchCase="'DriverRanking'">
<table class="table">