feat(dashboard): edit log channels page
This commit is contained in:
parent
ec7aa9faba
commit
32ddb9fae2
16 changed files with 471 additions and 95 deletions
|
|
@ -1,6 +1,8 @@
|
|||
import { addToast } from "$lib/toast";
|
||||
import { redirect } from "@sveltejs/kit";
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
export const load = async ({ parent }) => {
|
||||
const data = await parent();
|
||||
if (!data.user) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@
|
|||
$: unjoinedGuilds = data.guilds.filter((g) => !g.bot_in_guild);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Catalogger - Dashboard</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>Manage your servers</h1>
|
||||
|
||||
<div class="row">
|
||||
|
|
|
|||
86
Catalogger.Frontend/src/routes/dash/[guildId]/+layout.svelte
Normal file
86
Catalogger.Frontend/src/routes/dash/[guildId]/+layout.svelte
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<script lang="ts">
|
||||
import { Button, Nav, NavItem, NavLink } from "@sveltestrap/sveltestrap";
|
||||
import type { LayoutData } from "./$types";
|
||||
import { page } from "$app/stores";
|
||||
import apiFetch, { type ApiError, type GuildConfig } from "$lib/api";
|
||||
import { addToast } from "$lib/toast";
|
||||
|
||||
export let data: LayoutData;
|
||||
|
||||
// This only saves log channels. All other pages are lists and are saved immediately upon adding/removing an entry.
|
||||
const save = async () => {
|
||||
try {
|
||||
const resp = await apiFetch<GuildConfig>(
|
||||
"PATCH",
|
||||
`/api/guilds/${data.guild.id}`,
|
||||
data.guild.config,
|
||||
);
|
||||
data.guild.config = resp;
|
||||
} catch (e) {
|
||||
addToast({
|
||||
header: "Error saving changes to log channels",
|
||||
body:
|
||||
(e as ApiError).message || "Unknown error. Please try again later.",
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Catalogger - Managing {data.guild.name}</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="d-flex flex-column flex-lg-row justify-content-lg-between">
|
||||
<Nav pills={true} class="flex-column flex-lg-row">
|
||||
<NavItem
|
||||
><NavLink href="#" disabled>Managing {data.guild.name}</NavLink></NavItem
|
||||
>
|
||||
<NavItem
|
||||
><NavLink
|
||||
href="/dash/{data.guild.id}"
|
||||
active={$page.url.pathname === `/dash/${data.guild.id}`}
|
||||
>
|
||||
Log channels
|
||||
</NavLink></NavItem
|
||||
>
|
||||
<NavItem
|
||||
><NavLink
|
||||
href="/dash/{data.guild.id}/redirects"
|
||||
active={$page.url.pathname === `/dash/${data.guild.id}/redirects`}
|
||||
>
|
||||
Redirects
|
||||
</NavLink></NavItem
|
||||
>
|
||||
<NavItem
|
||||
><NavLink
|
||||
href="/dash/{data.guild.id}/ignored-channels"
|
||||
active={$page.url.pathname ===
|
||||
`/dash/${data.guild.id}/ignored-channels`}
|
||||
>
|
||||
Ignored channels
|
||||
</NavLink></NavItem
|
||||
>
|
||||
<NavItem
|
||||
><NavLink
|
||||
href="/dash/{data.guild.id}/ignored-users"
|
||||
active={$page.url.pathname === `/dash/${data.guild.id}/ignored-users`}
|
||||
>
|
||||
Ignored users
|
||||
</NavLink></NavItem
|
||||
>
|
||||
<NavItem
|
||||
><NavLink
|
||||
href="/dash/{data.guild.id}/key-roles"
|
||||
active={$page.url.pathname === `/dash/${data.guild.id}/key-roles`}
|
||||
>
|
||||
Key roles
|
||||
</NavLink></NavItem
|
||||
>
|
||||
</Nav>
|
||||
|
||||
{#if $page.url.pathname === `/dash/${data.guild.id}`}
|
||||
<Button on:click={save}>Save changes</Button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
17
Catalogger.Frontend/src/routes/dash/[guildId]/+layout.ts
Normal file
17
Catalogger.Frontend/src/routes/dash/[guildId]/+layout.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import apiFetch, { type ApiError, type FullGuild } from "$lib/api";
|
||||
import { error } from "@sveltejs/kit";
|
||||
|
||||
export const load = async ({ params }) => {
|
||||
try {
|
||||
const guild = await apiFetch<FullGuild>(
|
||||
"GET",
|
||||
`/api/guilds/${params.guildId}`,
|
||||
);
|
||||
|
||||
return { guild };
|
||||
} catch (e) {
|
||||
const err = e as ApiError;
|
||||
console.log("Fetching guild", params.guildId, ":", e);
|
||||
error(404, err.message);
|
||||
}
|
||||
};
|
||||
138
Catalogger.Frontend/src/routes/dash/[guildId]/+page.svelte
Normal file
138
Catalogger.Frontend/src/routes/dash/[guildId]/+page.svelte
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<script lang="ts">
|
||||
import { Label } from "@sveltestrap/sveltestrap";
|
||||
import type { FullGuild, GuildChannelConfig } from "$lib/api";
|
||||
import type { PageData } from "./$types";
|
||||
import ChannelSelect from "./ChannelSelect.svelte";
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
$: channels = data.guild.config as GuildChannelConfig;
|
||||
|
||||
const logChannelOptions = (g: FullGuild) => {
|
||||
let options = [];
|
||||
|
||||
const channelsWithoutCategory = g.channels_without_category.filter(
|
||||
(c) => c.can_log_to,
|
||||
);
|
||||
if (channelsWithoutCategory.length > 0)
|
||||
options.push({
|
||||
label: "(no category)",
|
||||
options: channelsWithoutCategory.map((c) => ({
|
||||
value: c.id,
|
||||
label: `#${c.name}`,
|
||||
})),
|
||||
});
|
||||
|
||||
options.push(
|
||||
...data.guild.categories
|
||||
.map((cat) => ({
|
||||
label: cat.name,
|
||||
options: cat.channels
|
||||
.filter((c) => c.can_log_to)
|
||||
.map((c) => ({ value: c.id, label: `#${c.name}` })),
|
||||
}))
|
||||
.filter((c) => c.options.length > 0),
|
||||
);
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
$: options = logChannelOptions(data.guild);
|
||||
</script>
|
||||
|
||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3">
|
||||
<div class="p-2">
|
||||
<Label><strong>Server changes</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_update} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Changes to emotes</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_emojis_update} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>New roles</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_role_create} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Changes to roles</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_role_update} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Deleted roles</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_role_delete} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>New channels</strong></Label>
|
||||
<ChannelSelect bind:value={channels.channel_create} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Changes to channels</strong></Label>
|
||||
<ChannelSelect bind:value={channels.channel_update} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Deleted channels</strong></Label>
|
||||
<ChannelSelect bind:value={channels.channel_delete} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Users joining</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_member_add} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Users leaving</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_member_remove} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Changes to key roles</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_update} {options} />
|
||||
<small>
|
||||
Key roles can be designated with the <code>/key-roles</code> command or the
|
||||
"Key roles" tab above.
|
||||
</small>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Member name changes</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_member_nick_update} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Member icon changes</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_member_avatar_update} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Timeouts</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_member_timeout} {options} />
|
||||
<small> Note that this will not log timeouts naturally expiring. </small>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Kicked users</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_member_kick} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Banned users</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_ban_add} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Unbanned users</strong></Label>
|
||||
<ChannelSelect bind:value={channels.guild_ban_remove} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>New invites</strong></Label>
|
||||
<ChannelSelect bind:value={channels.invite_create} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Deleted invites</strong></Label>
|
||||
<ChannelSelect bind:value={channels.invite_delete} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Edited messages</strong></Label>
|
||||
<ChannelSelect bind:value={channels.message_update} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Deleted messages</strong></Label>
|
||||
<ChannelSelect bind:value={channels.message_delete} {options} />
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<Label><strong>Bulk deleted messages</strong></Label>
|
||||
<ChannelSelect bind:value={channels.message_delete_bulk} {options} />
|
||||
<small> This will only be triggered by bots, not normal users. </small>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<script lang="ts">
|
||||
import Svelecte from "svelecte";
|
||||
|
||||
type Group = { label: string; options: Option[] };
|
||||
type Option = { label: string; value: string };
|
||||
|
||||
export let options: Group[];
|
||||
export let placeholder: string = "Select a channel";
|
||||
export let value: string;
|
||||
</script>
|
||||
|
||||
<Svelecte
|
||||
bind:value
|
||||
{options}
|
||||
{placeholder}
|
||||
labelField="label"
|
||||
valueField="value"
|
||||
groupLabelField="label"
|
||||
groupItemsField="options"
|
||||
searchable={true}
|
||||
/>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<h1>aaaaaaaaa</h1>
|
||||
Loading…
Add table
Add a link
Reference in a new issue