Refactor code for consistency: standardize formatting and improve readability across multiple Svelte components
Some checks failed
SteamWarCI Build failed

This commit is contained in:
2025-12-02 22:24:09 +01:00
parent 5f5988e270
commit 3bde299ea5
4 changed files with 177 additions and 172 deletions

View File

@@ -18,83 +18,103 @@
--> -->
<script lang="ts"> <script lang="ts">
import {Input, Label, Select} from "flowbite-svelte"; import { Input, Label, Select } from "flowbite-svelte";
import TypeAheadSearch from "./TypeAheadSearch.svelte"; import TypeAheadSearch from "./TypeAheadSearch.svelte";
import {gamemodes, groups, maps} from "@stores/stores.ts"; import { gamemodes, groups, maps } from "@stores/stores.ts";
import type {Team} from "@type/team.ts"; import type { Team } from "@type/team.ts";
interface Props { interface Props {
teams?: Team[]; teams?: Team[];
blueTeam: string; blueTeam: string;
redTeam: string; redTeam: string;
start?: string; start?: string;
gamemode?: string; gamemode?: string;
map?: string; map?: string;
spectatePort?: string | null; spectatePort?: string | null;
group?: string | null; group?: string | null;
groupSearch?: string; groupSearch?: string;
} }
let { let {
teams = [], teams = [],
blueTeam = $bindable(), blueTeam = $bindable(),
redTeam = $bindable(), redTeam = $bindable(),
start = $bindable(""), start = $bindable(""),
gamemode = $bindable(""), gamemode = $bindable(""),
map = $bindable(""), map = $bindable(""),
spectatePort = $bindable(null), spectatePort = $bindable(null),
group = $bindable(""), group = $bindable(""),
groupSearch = $bindable("") groupSearch = $bindable(""),
}: Props = $props(); }: Props = $props();
let selectableTeams = $derived(teams.map(team => { let selectableTeams = $derived(
return { teams
name: team.name, .map((team) => {
value: team.id.toString() return {
}; name: team.name,
}).sort((a, b) => a.name.localeCompare(b.name))); value: team.id.toString(),
};
})
.sort((a, b) => a.name.localeCompare(b.name))
);
let selectableGamemodes = $derived($gamemodes.map(gamemode => { let selectableGamemodes = $derived(
return { $gamemodes
name: gamemode, .map((gamemode) => {
value: gamemode return {
}; name: gamemode,
}).sort((a, b) => a.name.localeCompare(b.name))); value: gamemode,
};
})
.sort((a, b) => a.name.localeCompare(b.name))
);
let customGamemode = $derived(!selectableGamemodes.some((e) => e.name === gamemode) && gamemode !== ""); let customGamemode = $derived(!selectableGamemodes.some((e) => e.name === gamemode) && gamemode !== "");
let selectableCustomGamemode = $derived([ let selectableCustomGamemode = $derived([
...selectableGamemodes, { ...selectableGamemodes,
{
name: gamemode + " (custom)", name: gamemode + " (custom)",
value: gamemode value: gamemode,
} },
]); ]);
let mapsStore = $derived(maps(gamemode)); let mapsStore = $derived(maps(gamemode));
let selectableMaps = $derived($mapsStore.map(map => { let selectableMaps = $derived(
return { $mapsStore
name: map, .map((map) => {
value: map return {
}; name: map,
}).sort((a, b) => a.name.localeCompare(b.name))); value: map,
};
})
.sort((a, b) => a.name.localeCompare(b.name))
);
let customMap = $derived(!selectableMaps.some((e) => e.name === map) && map !== ""); let customMap = $derived(!selectableMaps.some((e) => e.name === map) && map !== "");
let selectableCustomMaps = $derived([ let selectableCustomMaps = $derived([
...selectableMaps, { ...selectableMaps,
{
name: map + " (custom)", name: map + " (custom)",
value: map value: map,
} },
]); ]);
let selectableGroups = $derived([{ let selectableGroups = $derived([
name: "None", {
value: "" name: "None",
}, { value: "",
value: groupSearch, },
name: `Create: '${groupSearch}'` {
}, ...$groups.map(group => { value: groupSearch,
return { name: `Create: '${groupSearch}'`,
name: group, },
value: group ...$groups
}; .map((group) => {
}).sort((a, b) => a.name.localeCompare(b.name))]); return {
name: group,
value: group,
};
})
.sort((a, b) => a.name.localeCompare(b.name)),
]);
</script> </script>
<div class="m-2"> <div class="m-2">
@@ -107,32 +127,29 @@
</div> </div>
<div class="mt-4"> <div class="mt-4">
<Label for="fight-start">Start</Label> <Label for="fight-start">Start</Label>
<Input id="fight-start" bind:value={start} > <Input id="fight-start" bind:value={start}>
{#snippet children({ props })} {#snippet children({ props })}
<input type="datetime-local" {...props} bind:value={start}/> <input type="datetime-local" {...props} bind:value={start} />
{/snippet} {/snippet}
</Input> </Input>
</div> </div>
<div class="m-2"> <div class="m-2">
<Label for="fight-gamemode">Gamemode</Label> <Label for="fight-gamemode">Gamemode</Label>
<Select items={customGamemode ? selectableCustomGamemode : selectableGamemodes} bind:value={gamemode} <Select items={customGamemode ? selectableCustomGamemode : selectableGamemodes} bind:value={gamemode} id="fight-gamemode"></Select>
id="fight-gamemode"></Select>
</div> </div>
<div class="m-2"> <div class="m-2">
<Label for="fight-maps">Map</Label> <Label for="fight-maps">Map</Label>
<Select items={customMap ? selectableCustomMaps : selectableMaps} bind:value={map} id="fight-maps" <Select items={customMap ? selectableCustomMaps : selectableMaps} bind:value={map} id="fight-maps" disabled={customGamemode} class={customGamemode ? "cursor-not-allowed" : ""}></Select>
disabled={customGamemode} class={customGamemode ? "cursor-not-allowed" : ""}></Select>
</div> </div>
<div class="m-2"> <div class="m-2">
<Label for="fight-port">Spectate Port</Label> <Label for="fight-port">Spectate Port</Label>
<Input id="fight-port" bind:value={spectatePort} > <Input id="fight-port" bind:value={spectatePort}>
{#snippet children({ props })} {#snippet children({ props })}
<input type="number" inputmode="numeric" {...props} bind:value={spectatePort}/> <input type="number" inputmode="numeric" {...props} bind:value={spectatePort} />
{/snippet} {/snippet}
</Input> </Input>
</div> </div>
<div class="m-2"> <div class="m-2">
<Label for="fight-kampf">Group</Label> <Label for="fight-kampf">Group</Label>
<TypeAheadSearch items={selectableGroups} bind:selected={group} bind:searchValue={groupSearch} <TypeAheadSearch items={selectableGroups} bind:selected={group} bind:searchValue={groupSearch} all></TypeAheadSearch>
all></TypeAheadSearch>
</div> </div>

View File

@@ -18,18 +18,18 @@
--> -->
<script lang="ts"> <script lang="ts">
import { run, preventDefault } from 'svelte/legacy'; import { run, preventDefault } from "svelte/legacy";
import {Button, Card, Checkbox, Input, Label, Navbar, NavBrand, Radio, Spinner} from "flowbite-svelte"; import { Button, Card, Checkbox, Input, Label, Navbar, NavBrand, Radio, Spinner } from "flowbite-svelte";
import {ArrowLeftOutline} from "flowbite-svelte-icons"; import { ArrowLeftOutline } from "flowbite-svelte-icons";
import {capitalize} from "../util.ts"; import { capitalize } from "../util.ts";
import {permsRepo} from "@repo/perms.ts"; import { permsRepo } from "@repo/perms.ts";
import {me} from "@stores/me.ts"; import { me } from "@stores/me.ts";
import SWButton from "@components/styled/SWButton.svelte"; import SWButton from "@components/styled/SWButton.svelte";
import SWModal from "@components/styled/SWModal.svelte"; import SWModal from "@components/styled/SWModal.svelte";
import {userRepo} from "@repo/user.ts"; import { userRepo } from "@repo/user.ts";
import {dataRepo} from "@repo/data.ts"; import { dataRepo } from "@repo/data.ts";
import type {Player} from "@type/data"; import type { Player } from "@type/data";
let search = $state(""); let search = $state("");
let playersList: Player[] = $state([]); let playersList: Player[] = $state([]);
@@ -62,7 +62,7 @@
if (!id) { if (!id) {
return; return;
} }
return $permsRepo.getPerms(id).then(value => { return $permsRepo.getPerms(id).then((value) => {
activePerms = value.perms; activePerms = value.perms;
prefixEdit = value.prefix.name; prefixEdit = value.prefix.name;
return value; return value;
@@ -72,7 +72,7 @@
function togglePerm(perm: string) { function togglePerm(perm: string) {
return () => { return () => {
if (activePerms.includes(perm)) { if (activePerms.includes(perm)) {
activePerms = activePerms.filter(value => value !== perm); activePerms = activePerms.filter((value) => value !== perm);
} else { } else {
activePerms = [...activePerms, perm]; activePerms = [...activePerms, perm];
} }
@@ -80,7 +80,7 @@
} }
function save() { function save() {
playerPerms!.then(async perms => { playerPerms!.then(async (perms) => {
if (perms.prefix.name != prefixEdit) { if (perms.prefix.name != prefixEdit) {
await $permsRepo.setPrefix(selectedPlayer!, prefixEdit); await $permsRepo.setPrefix(selectedPlayer!, prefixEdit);
} }
@@ -115,22 +115,20 @@
resetPasswordRepeat = ""; resetPasswordRepeat = "";
resetPasswordModal = false; resetPasswordModal = false;
} }
run(() => { run(() => {
playerPerms = loadPlayer(selectedPlayer); playerPerms = loadPlayer(selectedPlayer);
}); });
</script> </script>
<div class="flex flex-col h-screen overflow-hidden"> <div class="flex flex-col h-screen overflow-hidden">
<Navbar > <Navbar>
{#snippet children({ hidden, toggle })} {#snippet children({ hidden, toggle })}
<NavBrand href="#"> <NavBrand href="#">
<ArrowLeftOutline></ArrowLeftOutline> <ArrowLeftOutline></ArrowLeftOutline>
<span class="ml-4 self-center whitespace-nowrap text-xl font-semibold dark:text-white"> <span class="ml-4 self-center whitespace-nowrap text-xl font-semibold dark:text-white"> Permissions </span>
Permissions </NavBrand>
</span> {/snippet}
</NavBrand>
{/snippet}
</Navbar> </Navbar>
<div class="p-4 flex-1 overflow-hidden"> <div class="p-4 flex-1 overflow-hidden">
@@ -138,17 +136,19 @@
<Card class="h-full flex flex-col overflow-hidden !max-w-full"> <Card class="h-full flex flex-col overflow-hidden !max-w-full">
<div class="border-b border-b-gray-600 pb-2"> <div class="border-b border-b-gray-600 pb-2">
<Label for="user_search" class="mb-2">Search Users...</Label> <Label for="user_search" class="mb-2">Search Users...</Label>
<Input type="text" id="user_search" placeholder="Name..." bind:value={search}/> <Input type="text" id="user_search" placeholder="Name..." bind:value={search} />
</div> </div>
{#if playersList.length < 100} {#if playersList.length < 100}
<ul class="flex-1 overflow-scroll"> <ul class="flex-1 overflow-scroll">
{#each playersList as player (player.uuid)} {#each playersList as player (player.uuid)}
<li class="p-4 transition-colors hover:bg-gray-700 cursor-pointer" <li
class="p-4 transition-colors hover:bg-gray-700 cursor-pointer"
class:text-orange-500={player.uuid === selectedPlayer} class:text-orange-500={player.uuid === selectedPlayer}
onclick={preventDefault(() => { onclick={preventDefault(() => {
selectedPlayer = player.uuid; selectedPlayer = player.uuid;
selectedPlayerName = player.name; selectedPlayerName = player.name;
})}> })}
>
{player.name} {player.name}
</li> </li>
{/each} {/each}
@@ -166,39 +166,27 @@
{:then player} {:then player}
<h1>Prefix</h1> <h1>Prefix</h1>
{#each Object.entries(perms.prefixes) as [key, prefix]} {#each Object.entries(perms.prefixes) as [key, prefix]}
<Radio name="prefix" bind:group={prefixEdit} <Radio name="prefix" bind:group={prefixEdit} value={prefix.name}>{capitalize(prefix.name.substring(7).toLowerCase())}</Radio>
value={prefix.name}>{capitalize(prefix.name.substring(7).toLowerCase())}</Radio>
{/each} {/each}
<h1>Permissions</h1> <h1>Permissions</h1>
{#each perms.perms as perm} {#each perms.perms as perm}
<Checkbox checked={activePerms.includes(perm)} <Checkbox checked={activePerms.includes(perm)} onclick={togglePerm(perm)}>{capitalize(perm.toLowerCase())}</Checkbox>
onclick={togglePerm(perm)}>{capitalize(perm.toLowerCase())}</Checkbox>
{/each} {/each}
<div class="mt-4"> <div class="mt-4">
<Button disabled={prefixEdit === (player?.prefix.name ?? "") && activePerms === (player?.perms ?? [])} <Button disabled={prefixEdit === (player?.prefix.name ?? "") && activePerms === (player?.perms ?? [])} onclick={save}>Save</Button>
onclick={save}>Save
</Button>
{#if $me != null && $me.perms.includes("ADMINISTRATION")} {#if $me != null && $me.perms.includes("ADMINISTRATION")}
<Button onclick={() => resetPasswordModal = true}> <Button onclick={() => (resetPasswordModal = true)}>Reset Password</Button>
Reset Password
</Button>
<SWModal bind:open={resetPasswordModal} title="Reset Password"> <SWModal bind:open={resetPasswordModal} title="Reset Password">
<Label for="new_password">New Password</Label> <Label for="new_password">New Password</Label>
<Input type="password" id="new_password" placeholder="New Password" bind:value={resetPassword}/> <Input type="password" id="new_password" placeholder="New Password" bind:value={resetPassword} />
<Label for="repeat_password">Repeat Password</Label> <Label for="repeat_password">Repeat Password</Label>
<Input type="password" id="repeat_password" placeholder="Repeat Password" bind:value={resetPasswordRepeat}/> <Input type="password" id="repeat_password" placeholder="Repeat Password" bind:value={resetPasswordRepeat} />
{#snippet footer()} {#snippet footer()}
<Button class="ml-auto mr-4" onclick={resetResetPassword}>Cancel</Button>
<Button class="ml-auto mr-4" onclick={resetResetPassword}> <Button disabled={resetPassword === "" || resetPassword !== resetPasswordRepeat} onclick={resetPW}>Reset Password</Button>
Cancel {/snippet}
</Button>
<Button disabled={resetPassword === "" || resetPassword !== resetPasswordRepeat} onclick={resetPW}>
Reset Password
</Button>
{/snippet}
</SWModal> </SWModal>
{/if} {/if}
</div> </div>

View File

@@ -18,19 +18,19 @@
--> -->
<script lang="ts"> <script lang="ts">
import type {ExtendedEvent} from "@type/event.ts"; import type { ExtendedEvent } from "@type/event.ts";
import {Button} from "flowbite-svelte"; import { Button } from "flowbite-svelte";
import {PlusOutline} from "flowbite-svelte-icons"; import { PlusOutline } from "flowbite-svelte-icons";
import SWModal from "@components/styled/SWModal.svelte"; import SWModal from "@components/styled/SWModal.svelte";
import SWButton from "@components/styled/SWButton.svelte"; import SWButton from "@components/styled/SWButton.svelte";
import PlayerSelector from "@components/ui/PlayerSelector.svelte"; import PlayerSelector from "@components/ui/PlayerSelector.svelte";
import {eventRepo} from "@repo/event.ts"; import { eventRepo } from "@repo/event.ts";
interface Props { interface Props {
data: ExtendedEvent; data: ExtendedEvent;
} }
let { data }: Props = $props(); let { data }: Props = $props();
let searchValue = $state(""); let searchValue = $state("");
let selectedPlayer: string | null = $state(null); let selectedPlayer: string | null = $state(null);
@@ -41,17 +41,19 @@
async function addReferee() { async function addReferee() {
if (selectedPlayer) { if (selectedPlayer) {
referees = (await $eventRepo.updateEvent(data.event.id.toString(), { referees = (
deadline: null, await $eventRepo.updateEvent(data.event.id.toString(), {
end: null, deadline: null,
maxTeamMembers: null, end: null,
name: null, maxTeamMembers: null,
publicSchemsOnly: null, name: null,
removeReferee: null, publicSchemsOnly: null,
schemType: null, removeReferee: null,
start: null, schemType: null,
addReferee: [selectedPlayer] start: null,
})).referees; addReferee: [selectedPlayer],
})
).referees;
} }
reset(); reset();
@@ -59,18 +61,20 @@
function removeReferee(id: string) { function removeReferee(id: string) {
return async () => { return async () => {
referees = (await $eventRepo.updateEvent(data.event.id.toString(), { referees = (
deadline: null, await $eventRepo.updateEvent(data.event.id.toString(), {
end: null, deadline: null,
maxTeamMembers: null, end: null,
name: null, maxTeamMembers: null,
publicSchemsOnly: null, name: null,
addReferee: null, publicSchemsOnly: null,
schemType: null, addReferee: null,
start: null, schemType: null,
removeReferee: [id], start: null,
})).referees; removeReferee: [id],
} })
).referees;
};
} }
function reset() { function reset() {
@@ -83,9 +87,7 @@
{#each referees as referee} {#each referees as referee}
<li class="flex flex-grow justify-between"> <li class="flex flex-grow justify-between">
{referee.name} {referee.name}
<SWButton onclick={removeReferee(referee.uuid)}> <SWButton onclick={removeReferee(referee.uuid)}>Entfernen</SWButton>
Entfernen
</SWButton>
</li> </li>
{/each} {/each}
@@ -94,8 +96,8 @@
{/if} {/if}
</ul> </ul>
<Button class="fixed bottom-6 right-6 !p-4 z-10 shadow-lg" onclick={() => showAdd = true}> <Button class="fixed bottom-6 right-6 !p-4 z-10 shadow-lg" onclick={() => (showAdd = true)}>
<PlusOutline/> <PlusOutline />
</Button> </Button>
<SWModal title="Schiedsrichter hinzufügen" bind:open={showAdd}> <SWModal title="Schiedsrichter hinzufügen" bind:open={showAdd}>
@@ -105,11 +107,11 @@
</div> </div>
</div> </div>
{#snippet footer()} {#snippet footer()}
<div class="flex flex-grow justify-end"> <div class="flex flex-grow justify-end">
<SWButton onclick={reset} type="gray">Abbrechen</SWButton> <SWButton onclick={reset} type="gray">Abbrechen</SWButton>
<SWButton onclick={addReferee}>Hinzufügen</SWButton> <SWButton onclick={addReferee}>Hinzufügen</SWButton>
</div> </div>
{/snippet} {/snippet}
</SWModal> </SWModal>
<style> <style>

View File

@@ -18,24 +18,22 @@
--> -->
<script lang="ts"> <script lang="ts">
import {permissions} from "@stores/stores.ts"; import { permissions } from "@stores/stores.ts";
import {Select, SelectContent, SelectItem} from "@components/ui/select"; import { Select, SelectContent, SelectItem } from "@components/ui/select";
import {SelectTrigger} from "@components/ui/select/index.js"; import { SelectTrigger } from "@components/ui/select/index.js";
import {permsRepo} from "@repo/perms.ts"; import { permsRepo } from "@repo/perms.ts";
const { const { perms, uuid }: { perms: string[]; uuid: string } = $props();
perms, uuid
}: { perms: string[], uuid: string } = $props();
let value = $state(perms); let value = $state(perms);
let prevValue = $state(perms); let prevValue = $state(perms);
function onChange(change: string[]) { function onChange(change: string[]) {
$permissions.perms.forEach(perm => { $permissions.perms.forEach((perm) => {
if (prevValue.includes(perm) && !change.includes(perm)) { if (prevValue.includes(perm) && !change.includes(perm)) {
$permsRepo.removePerm(uuid, perm) $permsRepo.removePerm(uuid, perm);
} else if (!prevValue.includes(perm) && change.includes(perm)) { } else if (!prevValue.includes(perm) && change.includes(perm)) {
$permsRepo.addPerm(uuid, perm) $permsRepo.addPerm(uuid, perm);
} }
}); });
@@ -53,4 +51,4 @@
<SelectItem value={permission}>{permission}</SelectItem> <SelectItem value={permission}>{permission}</SelectItem>
{/each} {/each}
</SelectContent> </SelectContent>
</Select> </Select>