143 lines
5.7 KiB
Svelte
143 lines
5.7 KiB
Svelte
<!--
|
|
- This file is a part of the SteamWar software.
|
|
-
|
|
- Copyright (C) 2023 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 {Button, Card, Checkbox, Input, Label, Navbar, NavBrand, Radio, Spinner} from "flowbite-svelte";
|
|
import {ArrowLeftSolid} from "flowbite-svelte-icons";
|
|
import {players} from "@stores/stores.ts";
|
|
import {permsRepo} from "@repo/repo.ts";
|
|
import {capitalize} from "../util.ts";
|
|
|
|
let search = "";
|
|
$: lowerCaseSearch = search.toLowerCase();
|
|
$: filteredPlayers = $players.filter(value => value.name.toLowerCase().includes(lowerCaseSearch));
|
|
|
|
let selectedPlayer: number | null = null;
|
|
$: player = $players.find(value => value.id === selectedPlayer);
|
|
let playerPerms = loadPlayer(selectedPlayer);
|
|
$: playerPerms = loadPlayer(selectedPlayer);
|
|
|
|
let prefixEdit = "PREFIX_NONE";
|
|
let activePerms: string[] = [];
|
|
|
|
function loadPlayer(id: number | null) {
|
|
if (!id) {
|
|
return;
|
|
}
|
|
return $permsRepo.getPerms(id).then(value => {
|
|
activePerms = value.perms;
|
|
prefixEdit = value.prefix.name;
|
|
return value;
|
|
})
|
|
}
|
|
|
|
function togglePerm(perm: string) {
|
|
return () => {
|
|
if (activePerms.includes(perm)) {
|
|
activePerms = activePerms.filter(value => value !== perm);
|
|
} else {
|
|
activePerms = [...activePerms, perm];
|
|
}
|
|
}
|
|
}
|
|
|
|
function save() {
|
|
playerPerms!.then(async perms => {
|
|
if (perms.prefix.name != prefixEdit) {
|
|
await $permsRepo.setPrefix(selectedPlayer!, prefixEdit);
|
|
}
|
|
|
|
for (let value of activePerms) {
|
|
if (!perms.perms.includes(value)) {
|
|
await $permsRepo.addPerm(selectedPlayer!, value);
|
|
}
|
|
}
|
|
|
|
for (let value of perms.perms) {
|
|
if (!activePerms.includes(value)) {
|
|
await $permsRepo.removePerm(selectedPlayer!, value);
|
|
}
|
|
}
|
|
|
|
playerPerms = loadPlayer(selectedPlayer);
|
|
})
|
|
}
|
|
|
|
let permsFuture = $permsRepo.listPerms();
|
|
</script>
|
|
|
|
<div class="flex flex-col h-screen overflow-hidden">
|
|
<Navbar let:hidden let:toggle>
|
|
<NavBrand href="#">
|
|
<ArrowLeftSolid></ArrowLeftSolid>
|
|
<span class="ml-4 self-center whitespace-nowrap text-xl font-semibold dark:text-white">
|
|
Permissions
|
|
</span>
|
|
</NavBrand>
|
|
</Navbar>
|
|
|
|
<div class="p-4 flex-1 overflow-hidden">
|
|
<div class="grid md:grid-cols-3 grid-cols-1 h-full gap-8">
|
|
<Card class="h-full flex flex-col overflow-hidden !max-w-full">
|
|
<div class="border-b border-b-gray-600 pb-2">
|
|
<Label for="user_search" class="mb-2">Search Users...</Label>
|
|
<Input type="text" id="user_search" placeholder="Name..." bind:value={search}/>
|
|
</div>
|
|
{#if filteredPlayers.length < 100}
|
|
<ul class="flex-1 overflow-scroll">
|
|
{#each filteredPlayers as player (player.id)}
|
|
<li class="p-4 transition-colors hover:bg-gray-700 cursor-pointer" class:text-orange-500={player.id === selectedPlayer} on:click|preventDefault={() => selectedPlayer = player.id}>
|
|
{player.name}
|
|
</li>
|
|
{/each}
|
|
</ul>
|
|
{/if}
|
|
</Card>
|
|
<Card class="!max-w-full" style="grid-column: 2/4">
|
|
{#if selectedPlayer}
|
|
<h1 class="text-3xl">{player.name}</h1>
|
|
{#await permsFuture}
|
|
<Spinner></Spinner>
|
|
{:then perms}
|
|
{#await playerPerms}
|
|
<Spinner></Spinner>
|
|
{:then player}
|
|
<h1>Prefix</h1>
|
|
{#each Object.entries(perms.prefixes) as [key, prefix]}
|
|
<Radio name="prefix" bind:group={prefixEdit} value={prefix.name}>{capitalize(prefix.name.substring(7).toLowerCase())}</Radio>
|
|
{/each}
|
|
<h1>Permissions</h1>
|
|
{#each perms.perms as perm}
|
|
<Checkbox checked={activePerms.includes(perm)} on:click={togglePerm(perm)}>{capitalize(perm.toLowerCase())}</Checkbox>
|
|
{/each}
|
|
<div class="mt-4">
|
|
<Button disabled={prefixEdit === player.prefix.name && activePerms === player.perms} on:click={save}>Save</Button>
|
|
</div>
|
|
{:catch error}
|
|
<p>{error.toString()}</p>
|
|
{/await}
|
|
{:catch error}
|
|
<p>{error.toString()}</p>
|
|
{/await}
|
|
{/if}
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
</div>
|