62 lines
1.6 KiB
Svelte
62 lines
1.6 KiB
Svelte
<script lang="ts">
|
|
import { type ActionReturnType, actions } from 'astro:actions';
|
|
import Search from '@components/admin/search/Search.svelte';
|
|
import { actionErrorPopup } from '@util/action.ts';
|
|
|
|
// types
|
|
type Teams = Exclude<ActionReturnType<typeof actions.team.teams>['data'], undefined>['teams'];
|
|
type Team = Teams[0];
|
|
interface Props {
|
|
id?: string;
|
|
value?: string | null;
|
|
label?: string;
|
|
readonly?: boolean;
|
|
required?: boolean;
|
|
mustMatch?: boolean;
|
|
|
|
onSubmit?: (team: Team | null) => void;
|
|
}
|
|
|
|
// inputs
|
|
let { id, value = $bindable(), label, readonly, required, mustMatch, onSubmit }: Props = $props();
|
|
|
|
// states
|
|
let teamSuggestionCache = $state<Teams>([]);
|
|
|
|
// functions
|
|
async function getSuggestions(query: string, limit: number) {
|
|
const { data, error } = await actions.team.teams({
|
|
name: query,
|
|
limit: limit
|
|
});
|
|
|
|
if (error) {
|
|
actionErrorPopup(error);
|
|
return [];
|
|
}
|
|
|
|
teamSuggestionCache = data.teams;
|
|
return teamSuggestionCache.map((team) => team.name);
|
|
}
|
|
|
|
async function getTeamByTeamName(teamName: string) {
|
|
let team = teamSuggestionCache.find((team) => team.name === teamName);
|
|
if (!team) {
|
|
await getSuggestions(teamName, 5);
|
|
return await getTeamByTeamName(teamName);
|
|
}
|
|
return team;
|
|
}
|
|
</script>
|
|
|
|
<Search
|
|
{id}
|
|
bind:value
|
|
{label}
|
|
{readonly}
|
|
{required}
|
|
{mustMatch}
|
|
requestSuggestions={async (teamName) => getSuggestions(teamName, 5)}
|
|
onSubmit={async (teamName) => onSubmit?.(teamName != null ? await getTeamByTeamName(teamName) : null)}
|
|
/>
|