chore: minor admin pages refactorings (#24160)

pull/24087/merge
Daniel Dietzler 2025-11-25 13:57:30 +07:00 committed by GitHub
parent 2801a6e672
commit 939d2c8b27
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 45 deletions

@ -7,20 +7,11 @@
import { mdiCameraIris, mdiChartPie, mdiPlayCircle } from '@mdi/js';
import { t } from 'svelte-i18n';
interface Props {
stats?: ServerStatsResponseDto;
}
type Props = {
stats: ServerStatsResponseDto;
};
let {
stats = {
photos: 0,
videos: 0,
usage: 0,
usagePhotos: 0,
usageVideos: 0,
usageByUser: [],
},
}: Props = $props();
const { stats }: Props = $props();
const zeros = (value: number) => {
const maxLength = 13;

@ -1,35 +1,33 @@
<script lang="ts">
import AdminPageLayout from '$lib/components/layouts/AdminPageLayout.svelte';
import ServerStatisticsPanel from '$lib/components/server-statistics/ServerStatisticsPanel.svelte';
import { asyncTimeout } from '$lib/utils';
import { getServerStatistics } from '@immich/sdk';
import { onDestroy, onMount } from 'svelte';
import { onMount } from 'svelte';
import type { PageData } from './$types';
interface Props {
type Props = {
data: PageData;
}
};
let { data = $bindable() }: Props = $props();
const { data }: Props = $props();
let running = true;
let stats = $state(data.stats);
onMount(async () => {
while (running) {
data.stats = await getServerStatistics();
await asyncTimeout(5000);
}
});
const updateStatistics = async () => {
stats = await getServerStatistics();
};
onMount(() => {
const interval = setInterval(() => void updateStatistics(), 5000);
onDestroy(() => {
running = false;
return () => clearInterval(interval);
});
</script>
<AdminPageLayout title={data.meta.title}>
<section id="setting-content" class="flex place-content-center sm:mx-4">
<section class="w-full pb-28 sm:w-5/6 md:w-212.5">
<ServerStatisticsPanel stats={data.stats} />
<ServerStatisticsPanel {stats} />
</section>
</section>
</AdminPageLayout>

@ -6,7 +6,7 @@
import { getUserAdminActions, getUserAdminsActions } from '$lib/services/user-admin.service';
import { locale } from '$lib/stores/preferences.store';
import { getByteUnitString } from '$lib/utils/byte-units';
import { searchUsersAdmin, type UserAdminResponseDto } from '@immich/sdk';
import { type UserAdminResponseDto } from '@immich/sdk';
import { HStack, Icon } from '@immich/ui';
import { mdiInfinity } from '@mdi/js';
import { t } from 'svelte-i18n';
@ -18,24 +18,20 @@
let { data }: Props = $props();
let allUsers: UserAdminResponseDto[] = $derived(data.allUsers);
let allUsers: UserAdminResponseDto[] = $state(data.allUsers);
const refresh = async () => {
allUsers = await searchUsersAdmin({ withDeleted: true });
const onUpdate = (user: UserAdminResponseDto) => {
const index = allUsers.findIndex(({ id }) => id === user.id);
if (index !== -1) {
allUsers[index] = user;
}
};
const onUserAdminDeleted = ({ id: userId }: { id: string }) => {
const user = allUsers.find(({ id }) => id === userId);
if (user) {
allUsers = allUsers.filter((user) => user.id !== userId);
}
allUsers = allUsers.filter(({ id }) => id !== userId);
};
const UserAdminsActions = $derived(getUserAdminsActions($t));
const onUpdate = async () => {
await refresh();
};
const { Create } = $derived(getUserAdminsActions($t));
</script>
<OnEvents
@ -49,7 +45,7 @@
<AdminPageLayout title={data.meta.title}>
{#snippet buttons()}
<HStack gap={1}>
<HeaderButton action={UserAdminsActions.Create} />
<HeaderButton action={Create} />
</HStack>
{/snippet}
<section id="setting-content" class="flex place-content-center sm:mx-4">
@ -69,7 +65,7 @@
</thead>
<tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
{#each allUsers as user (user.id)}
{@const UserAdminActions = getUserAdminActions($t, user)}
{@const { View, ContextMenu } = 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'
@ -91,8 +87,8 @@
<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"
>
<TableButton action={UserAdminActions.View} />
<TableButton action={UserAdminActions.ContextMenu} />
<TableButton action={View} />
<TableButton action={ContextMenu} />
</td>
</tr>
{/each}