blob: fae079a55051b9d7bd1a767c6827e03571e219d6 [file] [log] [blame]
Alex Perrybb901052022-03-23 19:46:15 -07001import {Component} from '@angular/core';
2import {Builder, ByteBuffer} from 'flatbuffers';
3import {ErrorResponse} from 'org_frc971/scouting/webserver/requests/messages/error_response_generated';
4import {RequestNotesForTeam} from 'org_frc971/scouting/webserver/requests/messages/request_notes_for_team_generated';
Philipp Schrader817cce32022-03-26 15:00:00 -07005import {
6 Note as NoteFb,
7 RequestNotesForTeamResponse,
8} from 'org_frc971/scouting/webserver/requests/messages/request_notes_for_team_response_generated';
Alex Perrybb901052022-03-23 19:46:15 -07009import {SubmitNotes} from 'org_frc971/scouting/webserver/requests/messages/submit_notes_generated';
10import {SubmitNotesResponse} from 'org_frc971/scouting/webserver/requests/messages/submit_notes_response_generated';
11
Filip Kujawaf947cb42022-11-21 10:00:30 -080012/*
13For new games, the keywords being used will likely need to be updated.
14To update the keywords complete the following:
15 1) Update the Keywords Interface and KEYWORD_CHECKBOX_LABELS in notes.component.ts
16 The keys of Keywords and KEYWORD_CHECKBOX_LABELS should match.
17 2) In notes.component.ts, update the setTeamNumber() method with the new keywords.
18 3) Add/Edit the new keywords in /scouting/webserver/requests/messages/submit_notes.fbs.
19 4) In notes.component.ts, update the submitData() method with the newKeywords
20 so that it matches the updated flatbuffer
21 5) In db.go, update the NotesData struct and the
22 AddNotes method with the new keywords
23 6) In db_test.go update the TestNotes method so the test uses the keywords
24 7) Update the submitNoteScoutingHandler in requests.go with the new keywords
25 8) Finally, update the corresponding test in requests_test.go (TestSubmitNotes)
26
27 Note: If you change the number of keywords you might need to
28 update how they are displayed in notes.ng.html
29*/
30
31// TeamSelection: Display form to add a team to the teams being scouted.
32// Data: Display the note textbox and keyword selection form
33// for all the teams being scouted.
Philipp Schrader817cce32022-03-26 15:00:00 -070034type Section = 'TeamSelection' | 'Data';
Alex Perrybb901052022-03-23 19:46:15 -070035
Filip Kujawaf947cb42022-11-21 10:00:30 -080036// Every keyword checkbox corresponds to a boolean.
37// If the boolean is True, the checkbox is selected
38// and the note scout saw that the robot being scouted
39// displayed said property (ex. Driving really well -> goodDriving)
40interface Keywords {
41 goodDriving: boolean;
42 badDriving: boolean;
43 sketchyClimb: boolean;
44 solidClimb: boolean;
45 goodDefense: boolean;
46 badDefense: boolean;
Alex Perrybb901052022-03-23 19:46:15 -070047}
48
Filip Kujawaf947cb42022-11-21 10:00:30 -080049interface Input {
50 teamNumber: number;
51 notesData: string;
52 keywordsData: Keywords;
53}
54
55const KEYWORD_CHECKBOX_LABELS = {
56 goodDriving: 'Good Driving',
57 badDriving: 'Bad Driving',
58 solidClimb: 'Solid Climb',
59 sketchyClimb: 'Sketchy Climb',
60 goodDefense: 'Good Defense',
61 badDefense: 'Bad Defense',
62} as const;
63
Alex Perrybb901052022-03-23 19:46:15 -070064@Component({
65 selector: 'frc971-notes',
66 templateUrl: './notes.ng.html',
Philipp Schrader817cce32022-03-26 15:00:00 -070067 styleUrls: ['../common.css', './notes.component.css'],
Alex Perrybb901052022-03-23 19:46:15 -070068})
69export class Notes {
Filip Kujawaf947cb42022-11-21 10:00:30 -080070 // Re-export KEYWORD_CHECKBOX_LABELS so that we can
71 // use it in the checkbox properties.
72 readonly KEYWORD_CHECKBOX_LABELS = KEYWORD_CHECKBOX_LABELS;
73
74 // Necessary in order to iterate the keys of KEYWORD_CHECKBOX_LABELS.
75 Object = Object;
76
Alex Perrybb901052022-03-23 19:46:15 -070077 section: Section = 'TeamSelection';
Alex Perrybb901052022-03-23 19:46:15 -070078
79 errorMessage = '';
Filip Kujawaf947cb42022-11-21 10:00:30 -080080 teamNumberSelection: number = 971;
Alex Perrybb901052022-03-23 19:46:15 -070081
Filip Kujawaf947cb42022-11-21 10:00:30 -080082 // Data inputted by user is stored in this array.
83 // Includes the team number, notes, and keyword selection.
84 newData: Input[] = [];
Alex Perrybb901052022-03-23 19:46:15 -070085
Filip Kujawaf947cb42022-11-21 10:00:30 -080086 setTeamNumber() {
87 let data: Input = {
88 teamNumber: this.teamNumberSelection,
Filip Kujawaba55bb32022-12-02 14:08:32 -080089 notesData: 'Auto: \nTeleop: \nEngame: ',
Filip Kujawaf947cb42022-11-21 10:00:30 -080090 keywordsData: {
91 goodDriving: false,
92 badDriving: false,
93 solidClimb: false,
94 sketchyClimb: false,
95 goodDefense: false,
96 badDefense: false,
97 },
98 };
Alex Perrybb901052022-03-23 19:46:15 -070099
Filip Kujawaf947cb42022-11-21 10:00:30 -0800100 this.newData.push(data);
101 this.section = 'Data';
102 }
Alex Perrybb901052022-03-23 19:46:15 -0700103
Filip Kujawaf947cb42022-11-21 10:00:30 -0800104 removeTeam(index: number) {
105 this.newData.splice(index, 1);
106 if (this.newData.length == 0) {
107 this.section = 'TeamSelection';
Alex Perrybb901052022-03-23 19:46:15 -0700108 } else {
Filip Kujawaf947cb42022-11-21 10:00:30 -0800109 this.section = 'Data';
Alex Perrybb901052022-03-23 19:46:15 -0700110 }
111 }
112
Filip Kujawaf947cb42022-11-21 10:00:30 -0800113 addTeam() {
Philipp Schrader817cce32022-03-26 15:00:00 -0700114 this.section = 'TeamSelection';
Alex Perrybb901052022-03-23 19:46:15 -0700115 }
Philipp Schrader817cce32022-03-26 15:00:00 -0700116
Alex Perrybb901052022-03-23 19:46:15 -0700117 async submitData() {
Filip Kujawaf947cb42022-11-21 10:00:30 -0800118 for (let i = 0; i < this.newData.length; i++) {
119 const builder = new Builder();
120 const dataFb = builder.createString(this.newData[i].notesData);
Filip Kujawaba55bb32022-12-02 14:08:32 -0800121
Filip Kujawaf947cb42022-11-21 10:00:30 -0800122 builder.finish(
123 SubmitNotes.createSubmitNotes(
124 builder,
125 this.newData[i].teamNumber,
126 dataFb,
127 this.newData[i].keywordsData.goodDriving,
128 this.newData[i].keywordsData.badDriving,
129 this.newData[i].keywordsData.sketchyClimb,
130 this.newData[i].keywordsData.solidClimb,
131 this.newData[i].keywordsData.goodDefense,
132 this.newData[i].keywordsData.badDefense
133 )
134 );
Alex Perrybb901052022-03-23 19:46:15 -0700135
Filip Kujawaf947cb42022-11-21 10:00:30 -0800136 const buffer = builder.asUint8Array();
137 const res = await fetch('/requests/submit/submit_notes', {
138 method: 'POST',
139 body: buffer,
140 });
Alex Perrybb901052022-03-23 19:46:15 -0700141
Filip Kujawaf947cb42022-11-21 10:00:30 -0800142 if (!res.ok) {
143 const resBuffer = await res.arrayBuffer();
144 const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
145 const parsedResponse = ErrorResponse.getRootAsErrorResponse(fbBuffer);
146 const errorMessage = parsedResponse.errorMessage();
147 this.errorMessage = `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
148 }
Alex Perrybb901052022-03-23 19:46:15 -0700149 }
Filip Kujawaf947cb42022-11-21 10:00:30 -0800150
151 this.newData = [];
152 this.errorMessage = '';
153 this.section = 'TeamSelection';
Alex Perrybb901052022-03-23 19:46:15 -0700154 }
155}