Neues Referee zeug
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
Chaoscaot 2024-03-15 22:41:44 +01:00
Ursprung b52b2bcfe1
Commit 49fe9728e5
12 geänderte Dateien mit 163 neuen und 47 gelöschten Zeilen

Datei anzeigen

@ -29,7 +29,7 @@
export let start = ""; export let start = "";
export let gamemode = ""; export let gamemode = "";
export let map = ""; export let map = "";
export let kampfleiter: string | undefined = ""; export let spectatePort: string | null = null;
export let group: string | null = ""; export let group: string | null = "";
export let groupSearch = ""; export let groupSearch = "";
@ -115,8 +115,10 @@
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-kampf">Kampfleiter</Label> <Label for="fight-port">Spectate Port</Label>
<TypeAheadSearch items={selectPlayers} bind:selected={kampfleiter}></TypeAheadSearch> <Input id="fight-port" bind:value={spectatePort} let:props>
<input type="number" inputmode="numeric" {...props} bind:value={spectatePort}/>
</Input>
</div> </div>
<div class="m-2"> <div class="m-2">
<Label for="fight-kampf">Group</Label> <Label for="fight-kampf">Group</Label>

Datei anzeigen

@ -24,6 +24,7 @@
import FightList from "./event/FightList.svelte"; import FightList from "./event/FightList.svelte";
import TeamList from "./event/TeamList.svelte"; import TeamList from "./event/TeamList.svelte";
import {eventRepo} from "@repo/event.ts"; import {eventRepo} from "@repo/event.ts";
import RefereesList from "@components/admin/pages/event/RefereesList.svelte";
export let params: { id: number }; export let params: { id: number };
@ -54,6 +55,10 @@
<span slot="title">Teams</span> <span slot="title">Teams</span>
<TeamList {data}/> <TeamList {data}/>
</TabItem> </TabItem>
<TabItem>
<span slot="title">Referees</span>
<RefereesList {data}/>
</TabItem>
<TabItem> <TabItem>
<span slot="title">Fights</span> <span slot="title">Fights</span>
<FightList {data}/> <FightList {data}/>

Datei anzeigen

@ -39,7 +39,8 @@
let member = event.maxTeamMembers; let member = event.maxTeamMembers;
let schemType = event.schemType; let schemType = event.schemType;
let publicOnly = event.publicSchemsOnly; let publicOnly = event.publicSchemsOnly;
let spectateSystem = event.spectateSystem; let addReferee: {name: string, id: number}[] = [];
let removeReferee: {name: string, id: number}[] = [];
let errorOpen = false; let errorOpen = false;
let error: any = undefined; let error: any = undefined;
@ -65,7 +66,9 @@
member !== event.maxTeamMembers || member !== event.maxTeamMembers ||
schemType != event.schemType || schemType != event.schemType ||
publicOnly !== event.publicSchemsOnly || publicOnly !== event.publicSchemsOnly ||
spectateSystem !== event.spectateSystem; addReferee.length > 0 ||
removeReferee.length > 0;
async function del() { async function del() {
try { try {
@ -87,8 +90,9 @@
name: name, name: name,
publicSchemsOnly: publicOnly, publicSchemsOnly: publicOnly,
schemType: schemType ?? "null", schemType: schemType ?? "null",
spectateSystem: spectateSystem, start: startDate,
start: startDate addReferee: addReferee.map((ref) => ref.id),
removeReferee: removeReferee.map((ref) => ref.id)
}; };
try { try {
@ -138,7 +142,6 @@
<Select bind:value={schemType} items={selectTypes}/> <Select bind:value={schemType} items={selectTypes}/>
</div> </div>
<Toggle bind:checked={publicOnly} class="mt-4">Public Schematics Only</Toggle> <Toggle bind:checked={publicOnly} class="mt-4">Public Schematics Only</Toggle>
<Toggle bind:checked={spectateSystem} class="mt-4">Spectate System</Toggle>
<div class="flex mt-4"> <div class="flex mt-4">
<Button disabled={!changed} on:click={update}>Update</Button> <Button disabled={!changed} on:click={update}>Update</Button>
<Button class="ml-4" color="red" on:click={() => deleteOpen = true}>Delete</Button> <Button class="ml-4" color="red" on:click={() => deleteOpen = true}>Delete</Button>

Datei anzeigen

@ -92,21 +92,21 @@
deleteOpen = false; deleteOpen = false;
} }
let kampfleiterOpen = false; let spectatePortOpen = false;
$: selectPlayers = $players.map(player => { $: selectPlayers = $players.map(player => {
return { return {
name: player.name, name: player.name,
value: player.id.toString() value: player.id.toString()
}; };
}).sort((a, b) => a.name.localeCompare(b.name)); }).sort((a, b) => a.name.localeCompare(b.name));
let kampfleiter = ""; let spectatePort = "";
async function updateKampfleiter() { async function updateSpectatePort() {
for (const fight of selectedFights) { for (const fight of selectedFights) {
let f: UpdateFight = { let f: UpdateFight = {
blueTeam: null, blueTeam: null,
group: null, group: null,
kampfleiter: Number.parseInt(kampfleiter), spectatePort: Number.parseInt(spectatePort),
map: null, map: null,
redTeam: null, redTeam: null,
spielmodus: null, spielmodus: null,
@ -116,8 +116,8 @@
} }
fights = await $fightRepo.listFights(data.event.id); fights = await $fightRepo.listFights(data.event.id);
selectedFights = new Set(); selectedFights = new Set();
kampfleiter = ""; spectatePort = "";
kampfleiterOpen = false; spectatePortOpen = false;
} }
let groupChangeOpen = false; let groupChangeOpen = false;
@ -142,7 +142,7 @@
let f: UpdateFight = { let f: UpdateFight = {
blueTeam: null, blueTeam: null,
group: group, group: group,
kampfleiter: null, spectatePort: null,
map: null, map: null,
redTeam: null, redTeam: null,
spielmodus: null, spielmodus: null,
@ -168,7 +168,7 @@
let f: UpdateFight = { let f: UpdateFight = {
blueTeam: null, blueTeam: null,
group: null, group: null,
kampfleiter: null, spectatePort: null,
map: null, map: null,
redTeam: null, redTeam: null,
spielmodus: null, spielmodus: null,
@ -198,11 +198,11 @@
<CalendarWeekOutline/> <CalendarWeekOutline/>
</ToolbarButton> </ToolbarButton>
<Tooltip>Reschedule Fights</Tooltip> <Tooltip>Reschedule Fights</Tooltip>
<ToolbarButton on:click={() => selectedFights.size > 0 ? kampfleiterOpen = true : kampfleiterOpen = false} <ToolbarButton on:click={() => selectedFights.size > 0 ? spectatePortOpen = true : spectatePortOpen = false}
disabled={changedTime === undefined}> disabled={changedTime === undefined}>
<ProfileCardOutline/> <ProfileCardOutline/>
</ToolbarButton> </ToolbarButton>
<Tooltip>Change Kampfleiter</Tooltip> <Tooltip>Change Spectate Port</Tooltip>
<ToolbarButton on:click={() => selectedFights.size > 0 ? groupChangeOpen = true : groupChangeOpen = false}> <ToolbarButton on:click={() => selectedFights.size > 0 ? groupChangeOpen = true : groupChangeOpen = false}>
<UsersGroupOutline/> <UsersGroupOutline/>
</ToolbarButton> </ToolbarButton>
@ -249,14 +249,14 @@
</svelte:fragment> </svelte:fragment>
</Modal> </Modal>
<Modal bind:open={kampfleiterOpen} title="Change Kampfleiter" size="sm"> <Modal bind:open={spectatePortOpen} title="Change Kampfleiter" size="sm">
<div class="m-2"> <div class="m-2">
<Label for="fight-kampf">Kampfleiter</Label> <Label for="fight-kampf">Kampfleiter</Label>
<TypeAheadSearch items={selectPlayers} bind:selected={kampfleiter}></TypeAheadSearch> <TypeAheadSearch items={selectPlayers} bind:selected={spectatePort}></TypeAheadSearch>
</div> </div>
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<Button class="ml-auto" on:click={updateKampfleiter}>Change</Button> <Button class="ml-auto" on:click={updateSpectatePort}>Change</Button>
<Button on:click={() => kampfleiterOpen = false} color="alternative">Cancel</Button> <Button on:click={() => spectatePortOpen = false} color="alternative">Cancel</Button>
</svelte:fragment> </svelte:fragment>
</Modal> </Modal>

Datei anzeigen

@ -0,0 +1,99 @@
<!--
- This file is a part of the SteamWar software.
-
- Copyright (C) 2024 SteamWar.de-Serverteam
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<script lang="ts">
import type {ExtendedEvent} from "@type/event.ts";
import {Button} from "flowbite-svelte";
import {PlusSolid} from "flowbite-svelte-icons";
import SWModal from "@components/styled/SWModal.svelte";
import SWButton from "@components/styled/SWButton.svelte";
import TypeAheadSearch from "@components/admin/components/TypeAheadSearch.svelte";
import {players} from "@stores/stores.ts";
import {eventRepo} from "@repo/event.ts";
export let data: ExtendedEvent;
let searchValue = "";
let selectedPlayer: string | null = null;
let referees = data.event.referees;
let showAdd = false;
async function addReferee() {
if (selectedPlayer) {
referees = (await $eventRepo.updateEvent(data.event.id.toString(), {
addReferee: [parseInt(selectedPlayer)]
})).referees;
}
reset();
}
function removeReferee(id: number) {
return async () => {
referees = (await $eventRepo.updateEvent(data.event.id.toString(), {
removeReferee: [id]
})).referees;
}
}
function reset() {
selectedPlayer = null;
searchValue = "";
}
</script>
<ul class="mx-4 my-2 divide-y divide-neutral-600">
{#each referees as referee}
<li class="flex flex-grow justify-between">
{referee.name}
<SWButton on:click={removeReferee(referee.id)}>
Entfernen
</SWButton>
</li>
{/each}
{#if referees.length === 0}
<li>Keine Schiedsrichter</li>
{/if}
</ul>
<Button class="fixed bottom-6 right-6 !p-4 z-10 shadow-lg" on:click={() => showAdd = true}>
<PlusSolid/>
</Button>
<SWModal title="Schiedsrichter hinzufügen" bind:open={showAdd}>
<div class="flex flex-grow justify-center h-80">
<div>
<TypeAheadSearch bind:searchValue bind:selected={selectedPlayer}
items={$players.map(v => ({ name: v.name, value: v.id.toString() }))}/>
</div>
</div>
<div slot="footer" class="flex flex-grow justify-end">
<SWButton on:click={reset} type="gray">Abbrechen</SWButton>
<SWButton on:click={addReferee}>Hinzufügen</SWButton>
</div>
</SWModal>
<style>
li {
@apply py-2;
}
</style>

Datei anzeigen

@ -39,7 +39,7 @@
let gamemode: string = ""; let gamemode: string = "";
let map: string = ""; let map: string = "";
let kampfleiter: string | undefined = undefined; let spectatePort: string | null = null;
let group: string | null = null; let group: string | null = null;
let groupSearch = ""; let groupSearch = "";
@ -57,7 +57,7 @@
redTeam: parseInt(redTeam), redTeam: parseInt(redTeam),
start: dayjs(start), start: dayjs(start),
map, map,
kampfleiter: parseInt(kampfleiter!), spectatePort: spectatePort ? parseInt(spectatePort) : null,
group, group,
}); });
reset(); reset();
@ -76,7 +76,7 @@
start = ""; start = "";
gamemode = ""; gamemode = "";
map = ""; map = "";
kampfleiter = ""; spectatePort = "";
group = null; group = null;
groupSearch = ""; groupSearch = "";
} }
@ -88,7 +88,7 @@
bind:blueTeam bind:blueTeam
bind:redTeam bind:redTeam
bind:start bind:start
bind:kampfleiter bind:spectatePort
bind:gamemode bind:gamemode
bind:map bind:map
bind:group bind:group

Datei anzeigen

@ -36,7 +36,7 @@
let redTeam = fight.redTeam.id.toString(); let redTeam = fight.redTeam.id.toString();
let blueTeam = fight.blueTeam.id.toString(); let blueTeam = fight.blueTeam.id.toString();
let start = dayjs(fight.start).utc(true).toISOString().slice(0, -1); let start = dayjs(fight.start).utc(true).toISOString().slice(0, -1);
let kampfleiter = fight.kampfleiter?.id.toString(); let spectatePort = fight.spectatePort?.toString() ?? null;
let gamemode = fight.spielmodus; let gamemode = fight.spielmodus;
let map = fight.map; let map = fight.map;
let group = fight.group; let group = fight.group;
@ -51,7 +51,7 @@
const update: UpdateFight = { const update: UpdateFight = {
blueTeam: parseInt(blueTeam), blueTeam: parseInt(blueTeam),
group: group === "" ? null : group, group: group === "" ? null : group,
kampfleiter: parseInt(kampfleiter), spectatePort: spectatePort == null ? null : parseInt(spectatePort),
map: map, map: map,
redTeam: parseInt(redTeam), redTeam: parseInt(redTeam),
spielmodus: gamemode, spielmodus: gamemode,
@ -77,7 +77,7 @@
bind:blueTeam bind:blueTeam
bind:redTeam bind:redTeam
bind:start bind:start
bind:kampfleiter bind:spectatePort
bind:gamemode bind:gamemode
bind:map bind:map
bind:group bind:group

Datei anzeigen

@ -28,6 +28,10 @@
import {replace} from "svelte-spa-router"; import {replace} from "svelte-spa-router";
import dayjs from "dayjs"; import dayjs from "dayjs";
import {fightRepo} from "@repo/fight.ts"; import {fightRepo} from "@repo/fight.ts";
import utc from "dayjs/plugin/utc";
dayjs.extend(utc);
export let data: ExtendedEvent; export let data: ExtendedEvent;
$: teams = new Map<number, Team>(data.teams.map(team => [team.id, team])); $: teams = new Map<number, Team>(data.teams.map(team => [team.id, team]));

Datei anzeigen

@ -31,14 +31,15 @@ export interface CreateEvent {
} }
export interface UpdateEvent { export interface UpdateEvent {
name: string; name?: string;
start: Dayjs; start?: Dayjs;
end: Dayjs; end?: Dayjs;
deadline: Dayjs; deadline?: Dayjs;
maxTeamMembers: number; maxTeamMembers?: number;
schemType: string | null; schemType?: string | null;
publicSchemsOnly: boolean; publicSchemsOnly?: boolean;
spectateSystem: boolean; addReferee?: number[];
removeReferee?: number[];
} }
export class EventRepo { export class EventRepo {
@ -74,13 +75,14 @@ export class EventRepo {
method: "PUT", method: "PUT",
body: JSON.stringify({ body: JSON.stringify({
name: event.name, name: event.name,
start: +event.start, start: event.start?.valueOf(),
end: +event.end, end: event.end?.valueOf(),
deadline: +event.deadline, deadline: event.deadline?.valueOf(),
maxTeamMembers: event.maxTeamMembers, maxTeamMembers: event.maxTeamMembers,
schemType: event.schemType, schemType: event.schemType,
publicSchemsOnly: event.publicSchemsOnly, publicSchemsOnly: event.publicSchemsOnly,
spectateSystem: event.spectateSystem, addReferee: event.addReferee,
removeReferee: event.removeReferee,
}), }),
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",

Datei anzeigen

@ -30,7 +30,7 @@ export interface CreateFight {
blueTeam: number; blueTeam: number;
redTeam: number; redTeam: number;
start: Dayjs; start: Dayjs;
kampfleiter: number | null; spectatePort: number | null;
group: string | null; group: string | null;
} }
@ -40,7 +40,7 @@ export interface UpdateFight {
blueTeam: number | null; blueTeam: number | null;
redTeam: number | null; redTeam: number | null;
start: Dayjs | null; start: Dayjs | null;
kampfleiter: number | null; spectatePort: number | null;
group: string | null; group: string | null;
} }
@ -64,7 +64,7 @@ export class FightRepo {
blueTeam: fight.blueTeam, blueTeam: fight.blueTeam,
redTeam: fight.redTeam, redTeam: fight.redTeam,
start: +fight.start, start: +fight.start,
kampfleiter: fight.kampfleiter, spectatePort: fight.spectatePort,
group: fight.group, group: fight.group,
}), }),
}).then(value => value.json()) }).then(value => value.json())
@ -80,7 +80,7 @@ export class FightRepo {
blueTeam: fight.blueTeam, blueTeam: fight.blueTeam,
redTeam: fight.redTeam, redTeam: fight.redTeam,
start: fight.start?.valueOf(), start: fight.start?.valueOf(),
kampfleiter: fight.kampfleiter, spectatePort: fight.spectatePort ?? 0,
group: fight.group, group: fight.group,
}), }),
}).then(value => value.json()) }).then(value => value.json())

Datei anzeigen

@ -18,6 +18,7 @@
--> -->
<script lang="ts"> <script lang="ts">
import "@styles/button.css"
export let type: "primary" | "ghost" | "gray" = "primary"; export let type: "primary" | "ghost" | "gray" = "primary";
</script> </script>

Datei anzeigen

@ -35,7 +35,7 @@ export const SWEventSchema = ShortEventSchema.extend({
maxTeamMembers: z.number(), maxTeamMembers: z.number(),
schemType: z.string().nullable(), schemType: z.string().nullable(),
publicSchemsOnly: z.boolean(), publicSchemsOnly: z.boolean(),
spectateSystem: z.boolean(), referees: z.array(PlayerSchema),
}); });
export type SWEvent = z.infer<typeof SWEventSchema>; export type SWEvent = z.infer<typeof SWEventSchema>;
@ -46,9 +46,9 @@ export const EventFightSchema = z.object({
map: z.string(), map: z.string(),
blueTeam: TeamSchema, blueTeam: TeamSchema,
redTeam: TeamSchema, redTeam: TeamSchema,
kampfleiter: PlayerSchema.nullable(),
start: z.number(), start: z.number(),
ergebnis: z.number(), ergebnis: z.number(),
spectatePort: z.number().nullable(),
group: z.string().nullable(), group: z.string().nullable(),
}); });