Add delete functionality to the scouting app
This patch adds the ability to delete data scouting entries
from the database through the view tab.
Signed-off-by: Filip Kujawa <filip.j.kujawa@gmail.com>
Change-Id: I294fd3ebfa3721dace00582ba7f22e3da5f0f419
diff --git a/scouting/www/view/BUILD b/scouting/www/view/BUILD
index d787e8f..67c7e3b 100644
--- a/scouting/www/view/BUILD
+++ b/scouting/www/view/BUILD
@@ -10,6 +10,8 @@
],
deps = [
":node_modules/@angular/forms",
+ "//scouting/webserver/requests/messages:delete_2023_data_scouting_response_ts_fbs",
+ "//scouting/webserver/requests/messages:delete_2023_data_scouting_ts_fbs",
"//scouting/webserver/requests/messages:error_response_ts_fbs",
"//scouting/webserver/requests/messages:request_2023_data_scouting_response_ts_fbs",
"//scouting/webserver/requests/messages:request_2023_data_scouting_ts_fbs",
diff --git a/scouting/www/view/view.component.ts b/scouting/www/view/view.component.ts
index 561ae08..c75f83b 100644
--- a/scouting/www/view/view.component.ts
+++ b/scouting/www/view/view.component.ts
@@ -1,4 +1,6 @@
import {Component, OnInit} from '@angular/core';
+import {Builder, ByteBuffer} from 'flatbuffers';
+import {ErrorResponse} from '../../webserver/requests/messages/error_response_generated';
import {
Ranking,
RequestAllDriverRankingsResponse,
@@ -11,6 +13,8 @@
Note,
RequestAllNotesResponse,
} from '../../webserver/requests/messages/request_all_notes_response_generated';
+import {Delete2023DataScouting} from '../../webserver/requests/messages/delete_2023_data_scouting_generated';
+import {Delete2023DataScoutingResponse} from '../../webserver/requests/messages/delete_2023_data_scouting_response_generated';
import {ViewDataRequestor} from '../rpc';
@@ -104,16 +108,83 @@
}
// TODO(Filip): Add delete functionality.
- // Gets called when a user clicks the delete icon.
- async deleteData() {
+ // Gets called when a user clicks the delete icon (note scouting).
+ async deleteNoteData() {
const block_alerts = document.getElementById(
'block_alerts'
) as HTMLInputElement;
- if (!block_alerts.checked) {
- if (!window.confirm('Actually delete data?')) {
- this.errorMessage = 'Deleting data has not been implemented yet.';
- return;
- }
+ if (block_alerts.checked || window.confirm('Actually delete data?')) {
+ this.errorMessage = 'Deleting data has not been implemented yet.';
+ return;
+ }
+ }
+
+ // TODO(Filip): Add delete functionality.
+ // Gets called when a user clicks the delete icon (driver ranking).
+ async deleteDriverRankingData() {
+ const block_alerts = document.getElementById(
+ 'block_alerts'
+ ) as HTMLInputElement;
+ if (block_alerts.checked || window.confirm('Actually delete data?')) {
+ this.errorMessage = 'Deleting data has not been implemented yet.';
+ return;
+ }
+ }
+
+ // Gets called when a user clicks the delete icon.
+ async deleteDataScouting(
+ compLevel: string,
+ matchNumber: number,
+ setNumber: number,
+ teamNumber: string
+ ) {
+ const block_alerts = document.getElementById(
+ 'block_alerts'
+ ) as HTMLInputElement;
+ if (block_alerts.checked || window.confirm('Actually delete data?')) {
+ await this.requestDeleteDataScouting(
+ compLevel,
+ matchNumber,
+ setNumber,
+ teamNumber
+ );
+ await this.fetchStats2023();
+ }
+ }
+
+ async requestDeleteDataScouting(
+ compLevel: string,
+ matchNumber: number,
+ setNumber: number,
+ teamNumber: string
+ ) {
+ this.progressMessage = 'Deleting data. Please be patient.';
+ const builder = new Builder();
+ const compLevelData = builder.createString(compLevel);
+ const teamNumberData = builder.createString(teamNumber);
+
+ builder.finish(
+ Delete2023DataScouting.createDelete2023DataScouting(
+ builder,
+ compLevelData,
+ matchNumber,
+ setNumber,
+ teamNumberData
+ )
+ );
+
+ const buffer = builder.asUint8Array();
+ const res = await fetch('/requests/delete/delete_2023_data_scouting', {
+ method: 'POST',
+ body: buffer,
+ });
+
+ if (!res.ok) {
+ const resBuffer = await res.arrayBuffer();
+ const fbBuffer = new ByteBuffer(new Uint8Array(resBuffer));
+ const parsedResponse = ErrorResponse.getRootAsErrorResponse(fbBuffer);
+ const errorMessage = parsedResponse.errorMessage();
+ this.errorMessage = `Received ${res.status} ${res.statusText}: "${errorMessage}"`;
}
}
diff --git a/scouting/www/view/view.ng.html b/scouting/www/view/view.ng.html
index 667765f..2273217 100644
--- a/scouting/www/view/view.ng.html
+++ b/scouting/www/view/view.ng.html
@@ -11,12 +11,22 @@
</button>
<ul class="dropdown-menu">
<li>
- <a class="dropdown-item" href="#" (click)="switchDataSource('Notes')">
+ <a
+ class="dropdown-item"
+ href="#"
+ (click)="switchDataSource('Notes')"
+ id="notes_source_dropdown"
+ >
Notes
</a>
</li>
<li>
- <a class="dropdown-item" href="#" (click)="switchDataSource('Stats2023')">
+ <a
+ class="dropdown-item"
+ href="#"
+ (click)="switchDataSource('Stats2023')"
+ id="stats_source_dropdown"
+ >
Stats
</a>
</li>
@@ -25,6 +35,7 @@
class="dropdown-item"
href="#"
(click)="switchDataSource('DriverRanking')"
+ id="driver_ranking_source_dropdown"
>
Driver Ranking
</a>
@@ -64,7 +75,7 @@
<td>{{parseKeywords(note)}}</td>
<!-- Delete Icon. -->
<td>
- <button class="btn btn-danger" (click)="deleteData()">
+ <button class="btn btn-danger" (click)="deleteNoteData()">
<i class="bi bi-trash"></i>
</button>
</td>
@@ -94,13 +105,17 @@
</thead>
<tbody>
<tr *ngFor="let stat2023 of statList; index as i;">
- <th scope="row">{{stat2023.match()}}</th>
- <td>{{stat2023.team()}}</td>
+ <th scope="row">{{stat2023.matchNumber()}}</th>
+ <td>{{stat2023.teamNumber()}}</td>
<td>{{stat2023.setNumber()}}</td>
<td>{{COMP_LEVEL_LABELS[stat2023.compLevel()]}}</td>
<!-- Delete Icon. -->
<td>
- <button class="btn btn-danger" (click)="deleteData()">
+ <button
+ class="btn btn-danger"
+ id="delete_button_{{i}}"
+ (click)="deleteDataScouting(stat2023.compLevel(), stat2023.matchNumber(), stat2023.setNumber(), stat2023.teamNumber())"
+ >
<i class="bi bi-trash"></i>
</button>
</td>
@@ -136,7 +151,7 @@
<td>{{ranking.rank3()}}</td>
<!-- Delete Icon. -->
<td>
- <button class="btn btn-danger" (click)="deleteData()">
+ <button class="btn btn-danger" (click)="deleteDriverRankingData()">
<i class="bi bi-trash"></i>
</button>
</td>