blob: 7461aada85e1f37e546f9916b787570a61048a0b [file] [log] [blame]
Philipp Schrader6b2e9502022-03-15 23:42:56 -07001import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
Philipp Schradere279e1a2022-03-15 22:20:10 -07002import { FormsModule } from '@angular/forms';
Philipp Schrader80587432022-03-05 15:41:22 -08003
Philipp Schrader8b8ed672022-03-05 18:08:50 -08004import * as flatbuffer_builder from 'org_frc971/external/com_github_google_flatbuffers/ts/builder';
5import {ByteBuffer} from 'org_frc971/external/com_github_google_flatbuffers/ts/byte-buffer';
6import * as error_response from 'org_frc971/scouting/webserver/requests/messages/error_response_generated';
7import * as submit_data_scouting_response from 'org_frc971/scouting/webserver/requests/messages/submit_data_scouting_response_generated';
8import * as submit_data_scouting from 'org_frc971/scouting/webserver/requests/messages/submit_data_scouting_generated';
9import SubmitDataScouting = submit_data_scouting.scouting.webserver.requests.SubmitDataScouting;
10import SubmitDataScoutingResponse = submit_data_scouting_response.scouting.webserver.requests.SubmitDataScoutingResponse;
11import ErrorResponse = error_response.scouting.webserver.requests.ErrorResponse;
12
Philipp Schradera3c4e262022-03-17 09:04:12 -070013type Section = 'Team Selection'|'Auto'|'TeleOp'|'Climb'|'Other'|'Review and Submit'|'Success'
Philipp Schrader5990fd32022-03-15 21:49:58 -070014type Level = 'NoAttempt'|'Failed'|'FailedWithPlentyOfTime'|'Low'|'Medium'|'High'|'Transversal'
Philipp Schrader80587432022-03-05 15:41:22 -080015
16@Component({
17 selector: 'app-entry',
18 templateUrl: './entry.ng.html',
Philipp Schrader72beced2022-03-07 05:29:52 -080019 styleUrls: ['../common.css', './entry.component.css']
Philipp Schrader80587432022-03-05 15:41:22 -080020})
21export class EntryComponent {
Philipp Schrader93ade042022-03-05 17:16:10 -080022 section: Section = 'Team Selection';
23 matchNumber: number = 1
24 teamNumber: number = 1
Philipp Schrader80587432022-03-05 15:41:22 -080025 autoUpperShotsMade: number = 0;
26 autoLowerShotsMade: number = 0;
27 autoShotsMissed: number = 0;
28 teleUpperShotsMade: number = 0;
29 teleLowerShotsMade: number = 0;
30 teleShotsMissed: number = 0;
Yash Chainani43a81022022-03-12 16:46:47 -080031 defensePlayedOnScore: number = 0;
32 defensePlayedScore: number = 0;
Philipp Schrader5990fd32022-03-15 21:49:58 -070033 level: Level = 'NoAttempt';
Milo Lin905e78a2022-03-12 15:55:35 -080034 ball1: boolean = false;
35 ball2: boolean = false;
36 ball3: boolean = false;
37 ball4: boolean = false;
38 ball5: boolean = false;
Philipp Schradere7c252d2022-03-17 21:13:47 -070039 quadrant: number = 1;
Philipp Schrader8b8ed672022-03-05 18:08:50 -080040 errorMessage: string = '';
Philipp Schradere279e1a2022-03-15 22:20:10 -070041 noShow: boolean = false;
42 neverMoved: boolean = false;
43 batteryDied: boolean = false;
44 mechanicallyBroke: boolean = false;
45 lostComs: boolean = false;
Philipp Schrader80587432022-03-05 15:41:22 -080046
Philipp Schrader6b2e9502022-03-15 23:42:56 -070047 @ViewChild("header") header: ElementRef;
48
Philipp Schrader80587432022-03-05 15:41:22 -080049 nextSection() {
Philipp Schrader93ade042022-03-05 17:16:10 -080050 if (this.section === 'Team Selection') {
51 this.section = 'Auto';
52 } else if (this.section === 'Auto') {
Philipp Schrader80587432022-03-05 15:41:22 -080053 this.section = 'TeleOp';
54 } else if (this.section === 'TeleOp') {
55 this.section = 'Climb';
56 } else if (this.section === 'Climb') {
Philipp Schradere279e1a2022-03-15 22:20:10 -070057 this.section = 'Other';
58 } else if (this.section === 'Other') {
Philipp Schrader80587432022-03-05 15:41:22 -080059 this.section = 'Review and Submit';
60 } else if (this.section === 'Review and Submit') {
Philipp Schrader8b8ed672022-03-05 18:08:50 -080061 this.submitDataScouting();
Philipp Schrader6b2e9502022-03-15 23:42:56 -070062 return;
Philipp Schrader80587432022-03-05 15:41:22 -080063 }
Philipp Schrader6b2e9502022-03-15 23:42:56 -070064 // Scroll back to the top so that we can be sure the user sees the
65 // entire next screen. Otherwise it's easy to overlook input fields.
66 this.scrollToTop();
Philipp Schrader80587432022-03-05 15:41:22 -080067 }
68
Alex Perrybb3d2062022-03-05 18:14:33 -080069 prevSection() {
Philipp Schrader93ade042022-03-05 17:16:10 -080070 if (this.section === 'Auto') {
71 this.section = 'Team Selection';
72 } else if (this.section === 'TeleOp') {
Alex Perrybb3d2062022-03-05 18:14:33 -080073 this.section = 'Auto';
74 } else if (this.section === 'Climb') {
75 this.section = 'TeleOp';
Philipp Schradere279e1a2022-03-15 22:20:10 -070076 } else if (this.section === 'Other') {
Alex Perrybb3d2062022-03-05 18:14:33 -080077 this.section = 'Climb';
78 } else if (this.section === 'Review and Submit') {
Philipp Schradere279e1a2022-03-15 22:20:10 -070079 this.section = 'Other';
Alex Perrybb3d2062022-03-05 18:14:33 -080080 }
Philipp Schrader6b2e9502022-03-15 23:42:56 -070081 // Scroll back to the top so that we can be sure the user sees the
82 // entire previous screen. Otherwise it's easy to overlook input
83 // fields.
84 this.scrollToTop();
85 }
86
87 private scrollToTop() {
88 this.header.nativeElement.scrollIntoView();
Alex Perrybb3d2062022-03-05 18:14:33 -080089 }
90
Philipp Schrader8b8ed672022-03-05 18:08:50 -080091 async submitDataScouting() {
Philipp Schrader5f190012022-03-15 23:29:09 -070092 this.errorMessage = '';
93
Philipp Schrader8b8ed672022-03-05 18:08:50 -080094 const builder = new flatbuffer_builder.Builder() as unknown as flatbuffers.Builder;
95 SubmitDataScouting.startSubmitDataScouting(builder);
96 SubmitDataScouting.addTeam(builder, this.teamNumber);
97 SubmitDataScouting.addMatch(builder, this.matchNumber);
98 SubmitDataScouting.addMissedShotsAuto(builder, this.autoShotsMissed);
99 SubmitDataScouting.addUpperGoalAuto(builder, this.autoUpperShotsMade);
100 SubmitDataScouting.addLowerGoalAuto(builder, this.autoLowerShotsMade);
101 SubmitDataScouting.addMissedShotsTele(builder, this.teleShotsMissed);
102 SubmitDataScouting.addUpperGoalTele(builder, this.teleUpperShotsMade);
103 SubmitDataScouting.addLowerGoalTele(builder, this.teleLowerShotsMade);
104 SubmitDataScouting.addDefenseRating(builder, this.defensePlayedScore);
Milo Lin905e78a2022-03-12 15:55:35 -0800105 SubmitDataScouting.addAutoBall1(builder, this.ball1);
106 SubmitDataScouting.addAutoBall2(builder, this.ball2);
107 SubmitDataScouting.addAutoBall3(builder, this.ball3);
108 SubmitDataScouting.addAutoBall4(builder, this.ball4);
109 SubmitDataScouting.addAutoBall5(builder, this.ball5);
Philipp Schradere7c252d2022-03-17 21:13:47 -0700110 SubmitDataScouting.addStartingQuadrant(builder, this.quadrant);
Milo Lin905e78a2022-03-12 15:55:35 -0800111
Philipp Schrader8b8ed672022-03-05 18:08:50 -0800112 // TODO(phil): Add support for defensePlayedOnScore.
113 // TODO(phil): Fix the Climbing score.
114 SubmitDataScouting.addClimbing(builder, 1);
115 builder.finish(SubmitDataScouting.endSubmitDataScouting(builder));
116
117 const buffer = builder.asUint8Array();
118 const res = await fetch(
119 '/requests/submit/data_scouting', {method: 'POST', body: buffer});
120
121 if (res.ok) {
Philipp Schradera3c4e262022-03-17 09:04:12 -0700122 // We successfully submitted the data. Report success.
123 this.section = 'Success';
Philipp Schrader8b8ed672022-03-05 18:08:50 -0800124 } else {
125 const resBuffer = await res.arrayBuffer();
126 const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
127 const parsedResponse = ErrorResponse.getRootAsErrorResponse(
128 fbBuffer as unknown as flatbuffers.ByteBuffer);
129
130 const errorMessage = parsedResponse.errorMessage();
131 this.errorMessage = `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
132 }
133 }
Philipp Schrader80587432022-03-05 15:41:22 -0800134}