From d23d78de9c4adb35f6c155925ee2c1551f228437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aron=20Sch=C3=BCler?= Date: Sun, 17 Dec 2023 22:55:31 +0100 Subject: [PATCH] feat: remove empty data columns from results --- src/SessionPicker.tsx | 6 +-- src/types/GolfSwingData.ts | 79 ++++++++++++++++++++++---------------- src/types/Sessions.ts | 10 ++--- src/utils.ts | 31 +++++++++++++++ 4 files changed, 85 insertions(+), 41 deletions(-) diff --git a/src/SessionPicker.tsx b/src/SessionPicker.tsx index f8ec9c8..fc0fc46 100644 --- a/src/SessionPicker.tsx +++ b/src/SessionPicker.tsx @@ -6,7 +6,8 @@ import { Label } from "./Label"; import { SessionContext } from "./SessionContext"; import { UserContext } from "./UserProvider"; import { db } from "./firebaseConfig"; -import { Sessions } from "./types/Sessions"; +import { Session, Sessions } from "./types/Sessions"; +import { reduceSessionToDefinedValues } from "./utils"; export const SessionPicker = () => { const [selected, setSelected] = useState([]); @@ -21,8 +22,7 @@ export const SessionPicker = () => { collection(db, "r10data", uuid, "data"), ); const fetchedSessions = querySnapshot.docs.reduce((acc, curr) => { - const data = curr.data(); - // @ts-expect-error - The results property will always be set as we upload it this way + const data = reduceSessionToDefinedValues(curr.data() as Session); acc[curr.id] = { ...data, selected: true }; return acc; }, {} as Sessions); diff --git a/src/types/GolfSwingData.ts b/src/types/GolfSwingData.ts index 264b626..6acdf0c 100644 --- a/src/types/GolfSwingData.ts +++ b/src/types/GolfSwingData.ts @@ -1,36 +1,4 @@ -export type GolfSwingData = { - Schlagflächenstellung: null | number | undefined; - Luftdruck: number | null | undefined; - Schlagfläche: null | number; - Datum: string | null; - Temperatur: number | null; - Markierung: null | string; - Luftdichte: number | null; - Schwungbahn: null | number; - Drehrate: number | null; - "Smash Factor": number | null; - Drehratentyp: string | null; - Ballgeschwindigkeit: number | null; - Gesamtabweichungswinkel: number | null; - "Höhe des Scheitelpunkts": number | null; - Gesamtabweichungsdistanz: number | null; - Drehachse: number | null; - "Carry-Abweichungsdistanz": number | null; - Abflugrichtung: number | null; - Backspin: number | null; - Schlägername: null | string; - "Carry-Abweichungswinkel": number | null; - Sidespin: number | null; - Gesamtstrecke: number | null; - Spieler: string | null; - Abflugwinkel: number | null; - "Relative Luftfeuchtigkeit": number | null; - "Schl.gsch.": number | null; - Notiz: null | string; - Schlägerart: string | null; - Anstellwinkel: null | number; - "Carry-Distanz": number | null; -} & { +type GolfSwingDataEN = { "Club Speed": number; "Launch Direction": number; "Carry Distance": number; @@ -64,17 +32,62 @@ export type GolfSwingData = { Backspin: number; }; +type GolfSwingDataDE = { + Schlagflächenstellung: null | number | undefined; + Luftdruck: number | null | undefined; + Schlagfläche: null | number; + Datum: string | null; + Temperatur: number | null; + Markierung: null | string; + Luftdichte: number | null; + Schwungbahn: null | number; + Drehrate: number | null; + "Smash Factor": number | null; + Drehratentyp: string | null; + Ballgeschwindigkeit: number | null; + Gesamtabweichungswinkel: number | null; + "Höhe des Scheitelpunkts": number | null; + Gesamtabweichungsdistanz: number | null; + Drehachse: number | null; + "Carry-Abweichungsdistanz": number | null; + Abflugrichtung: number | null; + Backspin: number | null; + Schlägername: null | string; + "Carry-Abweichungswinkel": number | null; + Sidespin: number | null; + Gesamtstrecke: number | null; + Spieler: string | null; + Abflugwinkel: number | null; + "Relative Luftfeuchtigkeit": number | null; + "Schl.gsch.": number | null; + Notiz: null | string; + Schlägerart: string | null; + Anstellwinkel: null | number; + "Carry-Distanz": number | null; +}; + +export type GolfSwingData = GolfSwingDataEN | GolfSwingDataDE; + export const golfSwingDataKeysInMeters: Array = [ + "Carry Distance", "Carry-Distanz", + "Carry Deviation Distance", "Carry-Abweichungsdistanz", + "Total Distance", "Gesamtstrecke", + "Total Deviation Distance", "Gesamtabweichungsdistanz", + "Apex Height", "Höhe des Scheitelpunkts", ]; export const golfSwingDataKeysInDegrees: Array = [ + "Carry Deviation Angle", "Carry-Abweichungswinkel", + "Total Deviation Angle", "Gesamtabweichungswinkel", + "Launch Direction", "Abflugrichtung", + "Club Face", "Abflugwinkel", ]; diff --git a/src/types/Sessions.ts b/src/types/Sessions.ts index 4bf5550..db1256a 100644 --- a/src/types/Sessions.ts +++ b/src/types/Sessions.ts @@ -1,8 +1,8 @@ import { GolfSwingData } from "./GolfSwingData"; - +export type Session = { + results: GolfSwingData[]; + selected: boolean; +}; export type Sessions = { - [key: string]: { - results: GolfSwingData[]; - selected: boolean; - }; + [key: string]: Session; }; diff --git a/src/utils.ts b/src/utils.ts index 02701cf..3a09c9d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,6 @@ +import { GolfSwingData } from "./types/GolfSwingData"; +import { Session } from "./types/Sessions"; + export const sortGolfSwingKeysForHeader = (a: string, b: string) => { // We want to prioritize Carry Distance, Total Distance, Club Name, Ball Spped, and Date // over all other keys. This is because these keys are the most important ones to @@ -62,3 +65,31 @@ export const sortGolfSwingKeysForHeader = (a: string, b: string) => { // If both keys are not in the list of prioritized keys, sort them alphabetically return a.localeCompare(b); }; + +export const reduceSessionToDefinedValues: (session: Session) => Session = ( + session, +) => { + const fieldValueCount = session.results.reduce((accumulator, curr) => { + // @ts-expect-error - We know that the type will be correct + Object.keys(curr).forEach((key: keyof GolfSwingData) => { + if (accumulator[key] === undefined) accumulator[key] = 0; + if (curr[key] !== undefined && curr[key] !== null) + accumulator[key] = (accumulator[key] ?? 0) + 1; + }); + return accumulator; + }, {} as GolfSwingData); + + const fieldsWithoutValues = Object.keys(fieldValueCount).filter( + (key) => fieldValueCount[key as keyof GolfSwingData] === 0, + ); + + const reducedResults = session.results.map((result) => { + const newResult = { ...result }; + fieldsWithoutValues.forEach((key) => { + delete newResult[key as keyof GolfSwingData]; + }); + return newResult; + }); + + return { ...session, results: reducedResults }; +};