2022-12-09 15:51:42 -05:00
|
|
|
<script lang="ts">
|
2024-02-13 17:07:37 -05:00
|
|
|
import { page } from '$app/stores';
|
2025-11-11 07:42:33 -05:00
|
|
|
import HeaderButton from '$lib/components/HeaderButton.svelte';
|
2025-05-14 11:23:57 -04:00
|
|
|
import AdminPageLayout from '$lib/components/layouts/AdminPageLayout.svelte';
|
2025-11-11 07:42:33 -05:00
|
|
|
import OnEvents from '$lib/components/OnEvents.svelte';
|
|
|
|
|
import TableButton from '$lib/components/TableButton.svelte';
|
|
|
|
|
import { getUserAdminActions, getUserAdminsActions } from '$lib/services/user-admin.service';
|
2024-02-13 17:07:37 -05:00
|
|
|
import { locale } from '$lib/stores/preferences.store';
|
2024-03-08 17:49:39 -05:00
|
|
|
import { websocketEvents } from '$lib/stores/websocket';
|
2024-06-14 19:27:46 +02:00
|
|
|
import { getByteUnitString } from '$lib/utils/byte-units';
|
2025-11-11 07:42:33 -05:00
|
|
|
import { searchUsersAdmin, type UserAdminResponseDto } from '@immich/sdk';
|
|
|
|
|
import { HStack, Icon, toastManager } from '@immich/ui';
|
|
|
|
|
import { mdiInfinity } from '@mdi/js';
|
2024-02-13 17:07:37 -05:00
|
|
|
import { onMount } from 'svelte';
|
2024-06-04 21:53:00 +02:00
|
|
|
import { t } from 'svelte-i18n';
|
2024-09-19 18:20:09 -04:00
|
|
|
import type { PageData } from './$types';
|
2023-05-21 23:18:10 -04:00
|
|
|
|
2024-11-14 08:43:25 -06:00
|
|
|
interface Props {
|
|
|
|
|
data: PageData;
|
|
|
|
|
}
|
2022-12-09 15:51:42 -05:00
|
|
|
|
2024-11-14 08:43:25 -06:00
|
|
|
let { data }: Props = $props();
|
|
|
|
|
|
|
|
|
|
let allUsers: UserAdminResponseDto[] = $state([]);
|
2022-12-09 15:51:42 -05:00
|
|
|
|
2024-03-08 17:49:39 -05:00
|
|
|
const refresh = async () => {
|
2024-05-26 18:15:52 -04:00
|
|
|
allUsers = await searchUsersAdmin({ withDeleted: true });
|
2024-03-08 17:49:39 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onDeleteSuccess = (userId: string) => {
|
|
|
|
|
const user = allUsers.find(({ id }) => id === userId);
|
|
|
|
|
if (user) {
|
|
|
|
|
allUsers = allUsers.filter((user) => user.id !== userId);
|
2025-10-28 15:09:11 -04:00
|
|
|
toastManager.success($t('admin.user_successfully_removed', { values: { email: user.email } }));
|
2024-03-08 17:49:39 -05:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2023-07-01 00:50:47 -04:00
|
|
|
onMount(() => {
|
|
|
|
|
allUsers = $page.data.allUsers;
|
2022-12-09 15:51:42 -05:00
|
|
|
|
2024-03-08 17:49:39 -05:00
|
|
|
return websocketEvents.on('on_user_delete', onDeleteSuccess);
|
|
|
|
|
});
|
2022-12-09 15:51:42 -05:00
|
|
|
|
2025-11-11 07:42:33 -05:00
|
|
|
const UserAdminsActions = $derived(getUserAdminsActions($t));
|
2022-12-09 15:51:42 -05:00
|
|
|
|
2025-11-11 07:42:33 -05:00
|
|
|
const onUpdate = async () => {
|
2024-03-08 17:49:39 -05:00
|
|
|
await refresh();
|
2023-07-01 00:50:47 -04:00
|
|
|
};
|
2022-12-09 15:51:42 -05:00
|
|
|
</script>
|
|
|
|
|
|
2025-11-11 07:42:33 -05:00
|
|
|
<OnEvents
|
|
|
|
|
onUserAdminCreate={onUpdate}
|
|
|
|
|
onUserAdminUpdate={onUpdate}
|
|
|
|
|
onUserAdminDelete={onUpdate}
|
|
|
|
|
onUserAdminRestore={onUpdate}
|
|
|
|
|
/>
|
|
|
|
|
|
2025-05-14 11:23:57 -04:00
|
|
|
<AdminPageLayout title={data.meta.title}>
|
2025-05-13 10:40:50 -04:00
|
|
|
{#snippet buttons()}
|
|
|
|
|
<HStack gap={1}>
|
2025-11-11 07:42:33 -05:00
|
|
|
<HeaderButton action={UserAdminsActions.Create} />
|
2025-05-13 10:40:50 -04:00
|
|
|
</HStack>
|
|
|
|
|
{/snippet}
|
2023-10-13 11:02:28 -04:00
|
|
|
<section id="setting-content" class="flex place-content-center sm:mx-4">
|
2025-10-31 16:38:17 +01:00
|
|
|
<section class="w-full pb-28 lg:w-212.5">
|
2025-04-28 09:53:53 -04:00
|
|
|
<table class="my-5 w-full text-start">
|
2023-10-13 11:02:28 -04:00
|
|
|
<thead
|
2025-09-17 12:12:51 -04:00
|
|
|
class="mb-4 flex h-12 w-full rounded-md border bg-gray-50 text-primary dark:border-immich-dark-gray dark:bg-immich-dark-gray"
|
2023-10-13 11:02:28 -04:00
|
|
|
>
|
|
|
|
|
<tr class="flex w-full place-items-center">
|
2024-06-04 21:53:00 +02:00
|
|
|
<th class="w-8/12 sm:w-5/12 lg:w-6/12 xl:w-4/12 2xl:w-5/12 text-center text-sm font-medium"
|
|
|
|
|
>{$t('email')}</th
|
|
|
|
|
>
|
|
|
|
|
<th class="hidden sm:block w-3/12 text-center text-sm font-medium">{$t('name')}</th>
|
|
|
|
|
<th class="hidden xl:block w-3/12 2xl:w-2/12 text-center text-sm font-medium">{$t('has_quota')}</th>
|
|
|
|
|
<th class="w-4/12 lg:w-3/12 xl:w-2/12 text-center text-sm font-medium">{$t('action')}</th>
|
2023-07-01 00:50:47 -04:00
|
|
|
</tr>
|
2023-10-13 11:02:28 -04:00
|
|
|
</thead>
|
2024-04-14 04:41:00 +02:00
|
|
|
<tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
|
2025-11-18 21:27:41 +01:00
|
|
|
{#each allUsers as user (user.id)}
|
|
|
|
|
{@const UserAdminActions = getUserAdminActions($t, user)}
|
|
|
|
|
<tr
|
|
|
|
|
class="flex h-20 overflow-hidden w-full place-items-center text-center dark:text-immich-dark-fg {user.deletedAt
|
|
|
|
|
? 'bg-red-300 dark:bg-red-900'
|
|
|
|
|
: 'even:bg-subtle/20 odd:bg-subtle/80'}"
|
|
|
|
|
>
|
|
|
|
|
<td class="w-8/12 sm:w-5/12 lg:w-6/12 xl:w-4/12 2xl:w-5/12 text-ellipsis break-all px-2 text-sm">
|
|
|
|
|
{user.email}
|
|
|
|
|
</td>
|
|
|
|
|
<td class="hidden sm:block w-3/12 text-ellipsis break-all px-2 text-sm">{user.name}</td>
|
|
|
|
|
<td class="hidden xl:block w-3/12 2xl:w-2/12 text-ellipsis break-all px-2 text-sm">
|
|
|
|
|
<div class="container mx-auto flex flex-wrap justify-center">
|
|
|
|
|
{#if user.quotaSizeInBytes !== null && user.quotaSizeInBytes >= 0}
|
|
|
|
|
{getByteUnitString(user.quotaSizeInBytes, $locale)}
|
|
|
|
|
{:else}
|
|
|
|
|
<Icon icon={mdiInfinity} size="16" />
|
|
|
|
|
{/if}
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td
|
|
|
|
|
class="flex flex-row flex-wrap justify-center gap-x-2 gap-y-1 w-4/12 lg:w-3/12 xl:w-2/12 text-ellipsis break-all text-sm"
|
2023-10-13 11:02:28 -04:00
|
|
|
>
|
2025-11-18 21:27:41 +01:00
|
|
|
<TableButton action={UserAdminActions.View} />
|
|
|
|
|
<TableButton action={UserAdminActions.ContextMenu} />
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
{/each}
|
2023-10-13 11:02:28 -04:00
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</section>
|
|
|
|
|
</section>
|
2025-05-14 11:23:57 -04:00
|
|
|
</AdminPageLayout>
|