scouting: Deduplicate action definitions in entry.component.ts

I found it tedious to keep the definitions up-to-date between the .fbs
file and the entry.component.ts file. This patch fixes the issue by
using the generated flatbuffer types everywhere.

I added a helper library to deal with `actionTakenType` properly.
Otherwise the user would have to deal with it manually.

Since Angular templates don't seem to allow manual type casting, I
created a pipe to do it for me.

Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: I5f60e2d7b89978f40b5758bb8d04e800d6de230d
diff --git a/scouting/www/entry/action_helper.jinja2.ts b/scouting/www/entry/action_helper.jinja2.ts
new file mode 100644
index 0000000..bdce4d3
--- /dev/null
+++ b/scouting/www/entry/action_helper.jinja2.ts
@@ -0,0 +1,32 @@
+import {
+  ActionT,
+  ActionType,
+{% for action in ACTIONS %}
+  {{ action }}T,
+{% endfor %}
+} from '@org_frc971/scouting/webserver/requests/messages/submit_2024_actions_generated';
+
+export type ConcreteAction =
+{% for action in ACTIONS %}
+  {{ action }}T {% if not loop.last %} | {% endif %}
+{% endfor %};
+
+export class ActionHelper {
+  constructor(
+    private addAction: (actionType: ActionType, action: ConcreteAction) => void
+  ){}
+
+  {% for action in ACTIONS %}
+  // Calls `addAction` in entry.component.ts with the proper arguments. This
+  // also forces users to specify all the attributes in the `action` object.
+  public add{{ action}}(action: NonFunctionProperties<{{ action }}T>): void {
+    this.addAction(ActionType.{{ action }}, Object.assign(new {{ action }}T(), action));
+  }
+  {% endfor %}
+}
+
+type NonFunctionPropertyNames<T> = {
+  [K in keyof T]: T[K] extends Function ? never : K
+}[keyof T];
+
+type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;