Files
immich/web/src/routes/admin/users/+page.svelte

115 lines
4.5 KiB
Svelte
Raw Normal View History

<script lang="ts">
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';
import { locale } from '$lib/stores/preferences.store';
import { websocketEvents } from '$lib/stores/websocket';
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';
import { onMount } from 'svelte';
feat(web): translations (#9854) * First test * Added translation using Weblate (French) * Translated using Weblate (German) Currently translated at 100.0% (4 of 4 strings) Translation: immich/web Translate-URL: http://familie-mach.net/projects/immich/web/de/ * Translated using Weblate (French) Currently translated at 100.0% (4 of 4 strings) Translation: immich/web Translate-URL: http://familie-mach.net/projects/immich/web/fr/ * Further testing * Further testing * Translated using Weblate (German) Currently translated at 100.0% (18 of 18 strings) Translation: immich/web Translate-URL: http://familie-mach.net/projects/immich/web/de/ * Further work * Update string file. * More strings * Automatically changed strings * Add automatically translated german file for testing purposes * Fix merge-face-selector component * Make server stats strings uppercase * Fix uppercase string * Fix some strings in jobs-panel * Fix lower and uppercase strings. Add a few additional string. Fix a few unnecessary replacements * Update german test translations * Fix typo in locales file * Change string keys * Extract more strings * Extract and replace some more strings * Update testtranslationfile * Change translation keys * Fix rebase errors * Fix one more rebase error * Remove german translation file * Co-authored-by: Daniel Dietzler <danieldietzler@users.noreply.github.com> * chore: clean up translations * chore: add new line * fix formatting * chore: fixes * fix: loading and tests --------- Co-authored-by: root <root@Blacki> Co-authored-by: admin <admin@example.com> Co-authored-by: Jason Rasmussen <jrasm91@gmail.com> Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
2024-06-04 21:53:00 +02:00
import { t } from 'svelte-i18n';
import type { PageData } from './$types';
interface Props {
data: PageData;
}
let { data }: Props = $props();
let allUsers: UserAdminResponseDto[] = $state([]);
const refresh = async () => {
allUsers = await searchUsersAdmin({ withDeleted: true });
};
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 } }));
}
};
onMount(() => {
allUsers = $page.data.allUsers;
return websocketEvents.on('on_user_delete', onDeleteSuccess);
});
2025-11-11 07:42:33 -05:00
const UserAdminsActions = $derived(getUserAdminsActions($t));
2025-11-11 07:42:33 -05:00
const onUpdate = async () => {
await refresh();
};
</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}>
{#snippet buttons()}
<HStack gap={1}>
2025-11-11 07:42:33 -05:00
<HeaderButton action={UserAdminsActions.Create} />
</HStack>
{/snippet}
2023-10-13 11:02:28 -04:00
<section id="setting-content" class="flex place-content-center sm:mx-4">
<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">
feat(web): translations (#9854) * First test * Added translation using Weblate (French) * Translated using Weblate (German) Currently translated at 100.0% (4 of 4 strings) Translation: immich/web Translate-URL: http://familie-mach.net/projects/immich/web/de/ * Translated using Weblate (French) Currently translated at 100.0% (4 of 4 strings) Translation: immich/web Translate-URL: http://familie-mach.net/projects/immich/web/fr/ * Further testing * Further testing * Translated using Weblate (German) Currently translated at 100.0% (18 of 18 strings) Translation: immich/web Translate-URL: http://familie-mach.net/projects/immich/web/de/ * Further work * Update string file. * More strings * Automatically changed strings * Add automatically translated german file for testing purposes * Fix merge-face-selector component * Make server stats strings uppercase * Fix uppercase string * Fix some strings in jobs-panel * Fix lower and uppercase strings. Add a few additional string. Fix a few unnecessary replacements * Update german test translations * Fix typo in locales file * Change string keys * Extract more strings * Extract and replace some more strings * Update testtranslationfile * Change translation keys * Fix rebase errors * Fix one more rebase error * Remove german translation file * Co-authored-by: Daniel Dietzler <danieldietzler@users.noreply.github.com> * chore: clean up translations * chore: add new line * fix formatting * chore: fixes * fix: loading and tests --------- Co-authored-by: root <root@Blacki> Co-authored-by: admin <admin@example.com> Co-authored-by: Jason Rasmussen <jrasm91@gmail.com> Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
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>
</tr>
2023-10-13 11:02:28 -04:00
</thead>
<tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
2023-10-13 11:02:28 -04:00
{#if allUsers}
2025-11-11 07:42:33 -05:00
{#each allUsers as user (user.id)}
{@const UserAdminActions = getUserAdminActions($t, user)}
2023-10-13 11:02:28 -04:00
<tr
2025-11-11 07:42:33 -05:00
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'}"
2023-10-13 11:02:28 -04:00
>
<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">
2025-11-11 07:42:33 -05:00
{user.email}
</td>
2025-11-11 07:42:33 -05:00
<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">
2025-11-11 07:42:33 -05:00
{#if user.quotaSizeInBytes !== null && user.quotaSizeInBytes >= 0}
{getByteUnitString(user.quotaSizeInBytes, $locale)}
{:else}
2025-09-16 21:40:43 +02:00
<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"
>
2025-11-11 07:42:33 -05:00
<TableButton action={UserAdminActions.View} />
<TableButton action={UserAdminActions.ContextMenu} />
2023-10-13 11:02:28 -04:00
</td>
</tr>
{/each}
{/if}
</tbody>
</table>
</section>
</section>
2025-05-14 11:23:57 -04:00
</AdminPageLayout>