diff --git a/src/lib/components/cards/DriverCard.svelte b/src/lib/components/cards/DriverCard.svelte index 2dd71d6..7fa54c4 100644 --- a/src/lib/components/cards/DriverCard.svelte +++ b/src/lib/components/cards/DriverCard.svelte @@ -6,14 +6,18 @@ SlideToggle, type ModalStore, } from "@skeletonlabs/skeleton"; - import { Button, Input, Card, Dropdown, type DropdownOption } from "$lib/components"; - import type { Driver } from "$lib/schema"; + import { Button, Input, Card, Dropdown } from "$lib/components"; + import type { Driver, Team } from "$lib/schema"; import { DRIVER_HEADSHOT_HEIGHT, DRIVER_HEADSHOT_WIDTH } from "$lib/config"; + import { team_dropdown_options } from "$lib/dropdown"; interface DriverCardProps { /** The [Driver] object used to prefill values. */ driver?: Driver | undefined; + /** The teams (for the dropdown options) */ + teams: Team[]; + /** Disable all inputs if [true] */ disable_inputs?: boolean; @@ -28,20 +32,17 @@ // This also applies to the other card components... team_select_value: string; - /** The options this component's team select dropdown will display */ - team_select_options: DropdownOption[]; - /** The value this component's active switch will bind to */ active_value: boolean; } let { driver = undefined, + teams, disable_inputs = false, require_inputs = false, headshot_template = undefined, team_select_value, - team_select_options, active_value, }: DriverCardProps = $props(); @@ -51,8 +52,8 @@ // Stuff thats required for the "update" card driver = meta.driver; + teams = meta.teams; team_select_value = meta.team_select_value; - team_select_options = meta.team_select_options; active_value = meta.active_value; disable_inputs = meta.disable_inputs; @@ -116,7 +117,7 @@ - import { Card, Button, Dropdown, type DropdownOption } from "$lib/components"; + import { Card, Button, Dropdown } from "$lib/components"; import type { Driver, Race, RacePick, User } from "$lib/schema"; import { get_by_value } from "$lib/database"; import type { Action } from "svelte/action"; import { getModalStore, type ModalStore } from "@skeletonlabs/skeleton"; import { DRIVER_HEADSHOT_HEIGHT, DRIVER_HEADSHOT_WIDTH } from "$lib/config"; + import { driver_dropdown_options } from "$lib/dropdown"; interface RacePickCardProps { /** The [RacePick] object used to prefill values. */ @@ -30,9 +31,6 @@ /** The value this component's dnf select dropdown will bind to */ dnf_select_value: string; - - /** The options this component's driver select dropdowns will display */ - driver_select_options: DropdownOption[]; } let { @@ -44,7 +42,6 @@ headshot_template = "", pxx_select_value, dnf_select_value, - driver_select_options, }: RacePickCardProps = $props(); const modalStore: ModalStore = getModalStore(); @@ -60,7 +57,6 @@ headshot_template = meta.headshot_template; pxx_select_value = meta.pxx_select_value; dnf_select_value = meta.dnf_select_value; - driver_select_options = meta.driver_select_options; } // This action is used on the element. @@ -111,7 +107,7 @@ name="pxx" input_variable={pxx_select_value} action={register_pxx_preview_handler} - options={driver_select_options} + options={driver_dropdown_options(drivers)} labelwidth="60px" disabled={disable_inputs} > @@ -122,7 +118,7 @@ diff --git a/src/lib/components/cards/RaceResultCard.svelte b/src/lib/components/cards/RaceResultCard.svelte index 195f2e1..2bae192 100644 --- a/src/lib/components/cards/RaceResultCard.svelte +++ b/src/lib/components/cards/RaceResultCard.svelte @@ -6,10 +6,10 @@ type AutocompleteOption, type ModalStore, } from "@skeletonlabs/skeleton"; - import { Button, Card, Dropdown, type DropdownOption } from "$lib/components"; + import { Button, Card, Dropdown } from "$lib/components"; import type { Driver, Race, RaceResult } from "$lib/schema"; import { get_by_value } from "$lib/database"; - import { RACE_PICTOGRAM_HEIGHT, RACE_PICTOGRAM_WIDTH } from "$lib/config"; + import { race_dropdown_options } from "$lib/dropdown"; interface RaceResultCardProps { /** The [RaceResult] object used to prefill values. */ @@ -64,15 +64,6 @@ const require_inputs2 = require_inputs; let race_select_value: string = currentrace?.id ?? ""; - const race_select_options: DropdownOption[] = races2.map((race: Race) => { - return { - label: race.name, - value: race.id, - icon_url: race.pictogram_url, - icon_width: RACE_PICTOGRAM_WIDTH, - icon_height: RACE_PICTOGRAM_HEIGHT, - }; - }); let pxxs_input: string = $state(""); let pxxs_chips: string[] = $state( @@ -160,7 +151,7 @@ - import { Card, Button, Dropdown, type DropdownOption } from "$lib/components"; - import type { Driver, Substitution } from "$lib/schema"; + import { Card, Button, Dropdown } from "$lib/components"; + import type { Driver, Race, Substitution } from "$lib/schema"; import { get_by_value } from "$lib/database"; import type { Action } from "svelte/action"; import { getModalStore, type ModalStore } from "@skeletonlabs/skeleton"; import { DRIVER_HEADSHOT_HEIGHT, DRIVER_HEADSHOT_WIDTH } from "$lib/config"; + import { driver_dropdown_options, race_dropdown_options } from "$lib/dropdown"; interface SubstitutionCardProps { /** The [Substitution] object used to prefill values. */ @@ -13,6 +14,8 @@ /** The drivers (to display the headshot) */ drivers: Driver[]; + races: Race[]; + /** Disable all inputs if [true] */ disable_inputs?: boolean; @@ -30,25 +33,18 @@ /** The value this component's race select dropdown will bind to */ race_select_value: string; - - /** The options this component's substitute/driver select dropdowns will display */ - driver_select_options: DropdownOption[]; - - /** The options this component's race select dropdown will display */ - race_select_options: DropdownOption[]; } let { substitution = undefined, drivers, + races, disable_inputs = false, require_inputs = false, headshot_template = "", substitute_select_value, driver_select_value, race_select_value, - driver_select_options, - race_select_options, }: SubstitutionCardProps = $props(); const modalStore: ModalStore = getModalStore(); @@ -58,12 +54,11 @@ // Stuff thats required for the "update" card substitution = meta.substitution; drivers = meta.drivers; + races = meta.races; disable_inputs = meta.disable_inputs; substitute_select_value = meta.substitute_select_value; driver_select_value = meta.driver_select_value; race_select_value = meta.race_select_value; - driver_select_options = meta.driver_select_options; - race_select_options = meta.race_select_options; // Stuff thats additionally required for the "create" card require_inputs = meta.require_inputs; @@ -116,7 +111,7 @@ name="substitute" input_variable={substitute_select_value} action={register_substitute_preview_handler} - options={driver_select_options} + options={driver_dropdown_options(drivers)} labelwidth="120px" disabled={disable_inputs} required={require_inputs} @@ -128,7 +123,7 @@ component. + * Cached until page reload. + */ +export const team_dropdown_options = (teams: Team[]): DropdownOption[] => { + if (!team_dropdown_opts) { + console.log("team_dropdown_options"); + team_dropdown_opts = teams.map((team: Team) => { + return { + label: team.name, + value: team.id, + icon_url: team.banner_url, + icon_width: TEAM_BANNER_WIDTH, + icon_height: TEAM_BANNER_HEIGHT, + }; + }); + } + + return team_dropdown_opts; +}; + +let driver_dropdown_opts: DropdownOption[] | null = null; + +/** + * Generates a list of [DropdownOptions] for a component. + * Cached until page reload. + */ +export const driver_dropdown_options = (drivers: Driver[]): DropdownOption[] => { + if (!driver_dropdown_opts) { + console.log("driver_dropdown_options"); + driver_dropdown_opts = drivers.map((driver: Driver) => { + return { + label: driver.code, + value: driver.id, + icon_url: driver.headshot_url, + icon_width: DRIVER_HEADSHOT_WIDTH, + icon_height: DRIVER_HEADSHOT_HEIGHT, + }; + }); + } + + return driver_dropdown_opts; +}; + +let race_dropdown_opts: DropdownOption[] | null = null; + +/** + * Generates a list of [DropdownOptions] for a component. + * Cached until page reload. + */ +export const race_dropdown_options = (races: Race[]): DropdownOption[] => { + if (!race_dropdown_opts) { + console.log("race_dropdown_options"); + race_dropdown_opts = races.map((race: Race) => { + return { + label: race.name, + value: race.id, + icon_url: race.pictogram_url, + icon_width: RACE_PICTOGRAM_WIDTH, + icon_height: RACE_PICTOGRAM_HEIGHT, + }; + }); + } + + return race_dropdown_opts; +}; diff --git a/src/routes/data/season/drivers/+page.svelte b/src/routes/data/season/drivers/+page.svelte index bcc91c9..940cc41 100644 --- a/src/routes/data/season/drivers/+page.svelte +++ b/src/routes/data/season/drivers/+page.svelte @@ -1,6 +1,5 @@