2024-08-12 11:00:25 +02:00
|
|
|
<script lang="ts">
|
2024-10-31 17:22:58 +01:00
|
|
|
import { goto } from '$app/navigation';
|
2024-10-16 08:49:19 +02:00
|
|
|
import AdvancedTable from '$lib/components/advanced-table.svelte';
|
2024-08-12 11:00:25 +02:00
|
|
|
import { openConfirmDialog } from '$lib/components/confirm-dialog/';
|
|
|
|
|
import { Badge } from '$lib/components/ui/badge/index';
|
2024-10-31 17:22:58 +01:00
|
|
|
import { buttonVariants } from '$lib/components/ui/button';
|
2024-08-12 11:00:25 +02:00
|
|
|
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
|
|
|
|
|
import * as Table from '$lib/components/ui/table';
|
|
|
|
|
import UserService from '$lib/services/user-service';
|
2025-02-11 10:24:10 -06:00
|
|
|
import appConfigStore from '$lib/stores/application-configuration-store';
|
2025-01-11 20:14:12 +01:00
|
|
|
import type { Paginated, SearchPaginationSortRequest } from '$lib/types/pagination.type';
|
2024-08-12 11:00:25 +02:00
|
|
|
import type { User } from '$lib/types/user.type';
|
|
|
|
|
import { axiosErrorToast } from '$lib/utils/error-util';
|
|
|
|
|
import { LucideLink, LucidePencil, LucideTrash } from 'lucide-svelte';
|
|
|
|
|
import Ellipsis from 'lucide-svelte/icons/ellipsis';
|
|
|
|
|
import { toast } from 'svelte-sonner';
|
2025-03-10 12:45:45 +01:00
|
|
|
import OneTimeLinkModal from '$lib/components/one-time-link-modal.svelte';
|
2024-08-12 11:00:25 +02:00
|
|
|
|
2025-03-10 12:37:16 +01:00
|
|
|
let {
|
|
|
|
|
users = $bindable(),
|
|
|
|
|
requestOptions
|
|
|
|
|
}: { users: Paginated<User>; requestOptions: SearchPaginationSortRequest } = $props();
|
2024-08-12 11:00:25 +02:00
|
|
|
|
2025-01-11 20:14:12 +01:00
|
|
|
let userIdToCreateOneTimeLink: string | null = $state(null);
|
2024-08-12 11:00:25 +02:00
|
|
|
|
2024-10-16 08:49:19 +02:00
|
|
|
const userService = new UserService();
|
2024-08-12 11:00:25 +02:00
|
|
|
|
|
|
|
|
async function deleteUser(user: User) {
|
|
|
|
|
openConfirmDialog({
|
|
|
|
|
title: `Delete ${user.firstName} ${user.lastName}`,
|
|
|
|
|
message: 'Are you sure you want to delete this user?',
|
|
|
|
|
confirm: {
|
|
|
|
|
label: 'Delete',
|
|
|
|
|
destructive: true,
|
|
|
|
|
action: async () => {
|
|
|
|
|
try {
|
|
|
|
|
await userService.remove(user.id);
|
2025-01-11 20:14:12 +01:00
|
|
|
users = await userService.list(requestOptions!);
|
2024-08-12 11:00:25 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
axiosErrorToast(e);
|
|
|
|
|
}
|
|
|
|
|
toast.success('User deleted successfully');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
2024-10-16 08:49:19 +02:00
|
|
|
<AdvancedTable
|
|
|
|
|
items={users}
|
2025-01-11 20:14:12 +01:00
|
|
|
{requestOptions}
|
|
|
|
|
onRefresh={async (options) => (users = await userService.list(options))}
|
2024-10-16 08:49:19 +02:00
|
|
|
columns={[
|
2025-02-11 10:24:10 -06:00
|
|
|
{ label: 'First name', sortColumn: 'firstName' },
|
|
|
|
|
{ label: 'Last name', sortColumn: 'lastName' },
|
|
|
|
|
{ label: 'Email', sortColumn: 'email' },
|
|
|
|
|
{ label: 'Username', sortColumn: 'username' },
|
|
|
|
|
{ label: 'Role', sortColumn: 'isAdmin' },
|
|
|
|
|
...($appConfigStore.ldapEnabled ? [{ label: 'Source' }] : []),
|
|
|
|
|
{ label: 'Actions', hidden: true }
|
2024-10-16 08:49:19 +02:00
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
{#snippet rows({ item })}
|
|
|
|
|
<Table.Cell>{item.firstName}</Table.Cell>
|
|
|
|
|
<Table.Cell>{item.lastName}</Table.Cell>
|
|
|
|
|
<Table.Cell>{item.email}</Table.Cell>
|
|
|
|
|
<Table.Cell>{item.username}</Table.Cell>
|
2025-02-11 10:24:10 -06:00
|
|
|
<Table.Cell>
|
2024-10-16 08:49:19 +02:00
|
|
|
<Badge variant="outline">{item.isAdmin ? 'Admin' : 'User'}</Badge>
|
|
|
|
|
</Table.Cell>
|
2025-02-11 10:24:10 -06:00
|
|
|
{#if $appConfigStore.ldapEnabled}
|
|
|
|
|
<Table.Cell>
|
|
|
|
|
<Badge variant={item.ldapId ? 'default' : 'outline'}>{item.ldapId ? 'LDAP' : 'Local'}</Badge
|
|
|
|
|
>
|
|
|
|
|
</Table.Cell>
|
|
|
|
|
{/if}
|
2024-10-16 08:49:19 +02:00
|
|
|
<Table.Cell>
|
|
|
|
|
<DropdownMenu.Root>
|
2024-10-31 17:22:58 +01:00
|
|
|
<DropdownMenu.Trigger class={buttonVariants({ variant: 'ghost', size: 'icon' })}>
|
|
|
|
|
<Ellipsis class="h-4 w-4" />
|
|
|
|
|
<span class="sr-only">Toggle menu</span>
|
2024-10-16 08:49:19 +02:00
|
|
|
</DropdownMenu.Trigger>
|
|
|
|
|
<DropdownMenu.Content align="end">
|
2024-10-31 17:22:58 +01:00
|
|
|
<DropdownMenu.Item onclick={() => (userIdToCreateOneTimeLink = item.id)}
|
2025-03-10 12:45:45 +01:00
|
|
|
><LucideLink class="mr-2 h-4 w-4" />Login Code</DropdownMenu.Item
|
2024-10-16 08:49:19 +02:00
|
|
|
>
|
2024-10-31 17:22:58 +01:00
|
|
|
<DropdownMenu.Item onclick={() => goto(`/settings/admin/users/${item.id}`)}
|
2024-10-16 08:49:19 +02:00
|
|
|
><LucidePencil class="mr-2 h-4 w-4" /> Edit</DropdownMenu.Item
|
|
|
|
|
>
|
2025-02-03 08:58:20 +01:00
|
|
|
{#if !item.ldapId || !$appConfigStore.ldapEnabled}
|
2025-01-19 06:02:07 -06:00
|
|
|
<DropdownMenu.Item
|
|
|
|
|
class="text-red-500 focus:!text-red-700"
|
|
|
|
|
onclick={() => deleteUser(item)}
|
|
|
|
|
><LucideTrash class="mr-2 h-4 w-4" />Delete</DropdownMenu.Item
|
|
|
|
|
>
|
|
|
|
|
{/if}
|
2024-10-16 08:49:19 +02:00
|
|
|
</DropdownMenu.Content>
|
|
|
|
|
</DropdownMenu.Root>
|
|
|
|
|
</Table.Cell>
|
|
|
|
|
{/snippet}
|
|
|
|
|
</AdvancedTable>
|
2024-08-12 11:00:25 +02:00
|
|
|
|
2024-10-31 17:22:58 +01:00
|
|
|
<OneTimeLinkModal userId={userIdToCreateOneTimeLink} />
|