blob: 357d6b741699d219d4c5425467d227b036769f84 [file] [log] [blame]
Ravago Jones2813c032022-03-16 23:44:11 -07001import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
2import {FormsModule} from '@angular/forms';
James Kuszmauldac091f2022-03-22 09:35:06 -07003import {Builder, ByteBuffer} from 'flatbuffers';
4import {ErrorResponse} from 'org_frc971/scouting/webserver/requests/messages/error_response_generated';
Philipp Schrader36df73a2022-03-17 23:27:24 -07005import {ClimbLevel, SubmitDataScouting} from 'org_frc971/scouting/webserver/requests/messages/submit_data_scouting_generated';
Alex Perrybb901052022-03-23 19:46:15 -07006import {SubmitDataScoutingResponse} from 'org_frc971/scouting/webserver/requests/messages/submit_data_scouting_response_generated';
Philipp Schrader8b8ed672022-03-05 18:08:50 -08007
Ravago Jones2813c032022-03-16 23:44:11 -07008type Section = 'Team Selection'|'Auto'|'TeleOp'|'Climb'|'Other'|
Philipp Schrader23993e82022-03-18 18:54:00 -07009 'Review and Submit'|'Success';
Philipp Schrader80587432022-03-05 15:41:22 -080010
Philipp Schrader23993e82022-03-18 18:54:00 -070011@Component({
12 selector: 'app-entry',
13 templateUrl: './entry.ng.html',
14 styleUrls: ['../common.css', './entry.component.css']
15})
16export class EntryComponent {
Philipp Schrader36df73a2022-03-17 23:27:24 -070017 // Re-export the type here so that we can use it in the `[value]` attribute
18 // of radio buttons.
19 readonly ClimbLevel = ClimbLevel;
20
Ravago Jones2813c032022-03-16 23:44:11 -070021 section: Section = 'Team Selection';
22 @Output() switchTabsEvent = new EventEmitter<string>();
23 @Input() matchNumber: number = 1;
24 @Input() teamNumber: number = 1;
25 autoUpperShotsMade: number = 0;
26 autoLowerShotsMade: number = 0;
27 autoShotsMissed: number = 0;
28 teleUpperShotsMade: number = 0;
29 teleLowerShotsMade: number = 0;
30 teleShotsMissed: number = 0;
31 defensePlayedOnScore: number = 0;
32 defensePlayedScore: number = 0;
Philipp Schrader36df73a2022-03-17 23:27:24 -070033 level: ClimbLevel = ClimbLevel.NoAttempt;
Ravago Jones2813c032022-03-16 23:44:11 -070034 ball1: boolean = false;
35 ball2: boolean = false;
36 ball3: boolean = false;
37 ball4: boolean = false;
38 ball5: boolean = false;
39 quadrant: number = 1;
40 errorMessage: string = '';
41 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
Ravago Jones2813c032022-03-16 23:44:11 -070047 @ViewChild('header') header: ElementRef;
Philipp Schrader6b2e9502022-03-15 23:42:56 -070048
Ravago Jones2813c032022-03-16 23:44:11 -070049 nextSection() {
50 if (this.section === 'Team Selection') {
51 this.section = 'Auto';
52 } else if (this.section === 'Auto') {
53 this.section = 'TeleOp';
54 } else if (this.section === 'TeleOp') {
55 this.section = 'Climb';
56 } else if (this.section === 'Climb') {
57 this.section = 'Other';
58 } else if (this.section === 'Other') {
59 this.section = 'Review and Submit';
60 } else if (this.section === 'Review and Submit') {
Philipp Schrader36df73a2022-03-17 23:27:24 -070061
Ravago Jones2813c032022-03-16 23:44:11 -070062 this.submitDataScouting();
63 return;
64 } else if (this.section === 'Success') {
Philipp Schrader23993e82022-03-18 18:54:00 -070065 this.switchTabsEvent.emit('MatchList');
66 return;
Philipp Schrader80587432022-03-05 15:41:22 -080067 }
Ravago Jones2813c032022-03-16 23:44:11 -070068 // Scroll back to the top so that we can be sure the user sees the
69 // entire next screen. Otherwise it's easy to overlook input fields.
70 this.scrollToTop();
71 }
Philipp Schrader80587432022-03-05 15:41:22 -080072
Ravago Jones2813c032022-03-16 23:44:11 -070073 prevSection() {
74 if (this.section === 'Auto') {
75 this.section = 'Team Selection';
76 } else if (this.section === 'TeleOp') {
77 this.section = 'Auto';
78 } else if (this.section === 'Climb') {
79 this.section = 'TeleOp';
80 } else if (this.section === 'Other') {
81 this.section = 'Climb';
82 } else if (this.section === 'Review and Submit') {
83 this.section = 'Other';
Philipp Schrader6b2e9502022-03-15 23:42:56 -070084 }
Ravago Jones2813c032022-03-16 23:44:11 -070085 // Scroll back to the top so that we can be sure the user sees the
86 // entire previous screen. Otherwise it's easy to overlook input
87 // fields.
88 this.scrollToTop();
89 }
Philipp Schrader6b2e9502022-03-15 23:42:56 -070090
Ravago Jones2813c032022-03-16 23:44:11 -070091 private scrollToTop() {
92 this.header.nativeElement.scrollIntoView();
93 }
94
95 async submitDataScouting() {
96 this.errorMessage = '';
97
James Kuszmauldac091f2022-03-22 09:35:06 -070098 const builder = new Builder();
Ravago Jones2813c032022-03-16 23:44:11 -070099 SubmitDataScouting.startSubmitDataScouting(builder);
100 SubmitDataScouting.addTeam(builder, this.teamNumber);
101 SubmitDataScouting.addMatch(builder, this.matchNumber);
102 SubmitDataScouting.addMissedShotsAuto(builder, this.autoShotsMissed);
103 SubmitDataScouting.addUpperGoalAuto(builder, this.autoUpperShotsMade);
104 SubmitDataScouting.addLowerGoalAuto(builder, this.autoLowerShotsMade);
105 SubmitDataScouting.addMissedShotsTele(builder, this.teleShotsMissed);
106 SubmitDataScouting.addUpperGoalTele(builder, this.teleUpperShotsMade);
107 SubmitDataScouting.addLowerGoalTele(builder, this.teleLowerShotsMade);
108 SubmitDataScouting.addDefenseRating(builder, this.defensePlayedScore);
109 SubmitDataScouting.addAutoBall1(builder, this.ball1);
110 SubmitDataScouting.addAutoBall2(builder, this.ball2);
111 SubmitDataScouting.addAutoBall3(builder, this.ball3);
112 SubmitDataScouting.addAutoBall4(builder, this.ball4);
113 SubmitDataScouting.addAutoBall5(builder, this.ball5);
114 SubmitDataScouting.addStartingQuadrant(builder, this.quadrant);
Ravago Jones2813c032022-03-16 23:44:11 -0700115 // TODO(phil): Add support for defensePlayedOnScore.
Philipp Schrader36df73a2022-03-17 23:27:24 -0700116 SubmitDataScouting.addClimbLevel(builder, this.level);
Ravago Jones2813c032022-03-16 23:44:11 -0700117 builder.finish(SubmitDataScouting.endSubmitDataScouting(builder));
118
119 const buffer = builder.asUint8Array();
120 const res = await fetch(
121 '/requests/submit/data_scouting', {method: 'POST', body: buffer});
122
123 if (res.ok) {
124 // We successfully submitted the data. Report success.
125 this.section = 'Success';
126 } else {
127 const resBuffer = await res.arrayBuffer();
128 const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
James Kuszmauldac091f2022-03-22 09:35:06 -0700129 const parsedResponse = ErrorResponse.getRootAsErrorResponse(fbBuffer);
Ravago Jones2813c032022-03-16 23:44:11 -0700130
131 const errorMessage = parsedResponse.errorMessage();
132 this.errorMessage =
133 `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
Alex Perrybb3d2062022-03-05 18:14:33 -0800134 }
Ravago Jones2813c032022-03-16 23:44:11 -0700135 }
Philipp Schrader80587432022-03-05 15:41:22 -0800136}