mirror of
https://github.com/immich-app/immich.git
synced 2025-12-20 09:15:35 +03:00
chore: minor admin pages refactorings (#24160)
This commit is contained in:
@@ -7,20 +7,11 @@
|
|||||||
import { mdiCameraIris, mdiChartPie, mdiPlayCircle } from '@mdi/js';
|
import { mdiCameraIris, mdiChartPie, mdiPlayCircle } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
stats?: ServerStatsResponseDto;
|
stats: ServerStatsResponseDto;
|
||||||
}
|
};
|
||||||
|
|
||||||
let {
|
const { stats }: Props = $props();
|
||||||
stats = {
|
|
||||||
photos: 0,
|
|
||||||
videos: 0,
|
|
||||||
usage: 0,
|
|
||||||
usagePhotos: 0,
|
|
||||||
usageVideos: 0,
|
|
||||||
usageByUser: [],
|
|
||||||
},
|
|
||||||
}: Props = $props();
|
|
||||||
|
|
||||||
const zeros = (value: number) => {
|
const zeros = (value: number) => {
|
||||||
const maxLength = 13;
|
const maxLength = 13;
|
||||||
|
|||||||
@@ -1,35 +1,33 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import AdminPageLayout from '$lib/components/layouts/AdminPageLayout.svelte';
|
import AdminPageLayout from '$lib/components/layouts/AdminPageLayout.svelte';
|
||||||
import ServerStatisticsPanel from '$lib/components/server-statistics/ServerStatisticsPanel.svelte';
|
import ServerStatisticsPanel from '$lib/components/server-statistics/ServerStatisticsPanel.svelte';
|
||||||
import { asyncTimeout } from '$lib/utils';
|
|
||||||
import { getServerStatistics } from '@immich/sdk';
|
import { getServerStatistics } from '@immich/sdk';
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
data: PageData;
|
data: PageData;
|
||||||
}
|
};
|
||||||
|
|
||||||
let { data = $bindable() }: Props = $props();
|
const { data }: Props = $props();
|
||||||
|
|
||||||
let running = true;
|
let stats = $state(data.stats);
|
||||||
|
|
||||||
onMount(async () => {
|
const updateStatistics = async () => {
|
||||||
while (running) {
|
stats = await getServerStatistics();
|
||||||
data.stats = await getServerStatistics();
|
};
|
||||||
await asyncTimeout(5000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onDestroy(() => {
|
onMount(() => {
|
||||||
running = false;
|
const interval = setInterval(() => void updateStatistics(), 5000);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<AdminPageLayout title={data.meta.title}>
|
<AdminPageLayout title={data.meta.title}>
|
||||||
<section id="setting-content" class="flex place-content-center sm:mx-4">
|
<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">
|
<section class="w-full pb-28 sm:w-5/6 md:w-212.5">
|
||||||
<ServerStatisticsPanel stats={data.stats} />
|
<ServerStatisticsPanel {stats} />
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</AdminPageLayout>
|
</AdminPageLayout>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import { getUserAdminActions, getUserAdminsActions } from '$lib/services/user-admin.service';
|
import { getUserAdminActions, getUserAdminsActions } from '$lib/services/user-admin.service';
|
||||||
import { locale } from '$lib/stores/preferences.store';
|
import { locale } from '$lib/stores/preferences.store';
|
||||||
import { getByteUnitString } from '$lib/utils/byte-units';
|
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 { HStack, Icon } from '@immich/ui';
|
||||||
import { mdiInfinity } from '@mdi/js';
|
import { mdiInfinity } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
@@ -18,24 +18,20 @@
|
|||||||
|
|
||||||
let { data }: Props = $props();
|
let { data }: Props = $props();
|
||||||
|
|
||||||
let allUsers: UserAdminResponseDto[] = $derived(data.allUsers);
|
let allUsers: UserAdminResponseDto[] = $state(data.allUsers);
|
||||||
|
|
||||||
const refresh = async () => {
|
const onUpdate = (user: UserAdminResponseDto) => {
|
||||||
allUsers = await searchUsersAdmin({ withDeleted: true });
|
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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const UserAdminsActions = $derived(getUserAdminsActions($t));
|
const onUserAdminDeleted = ({ id: userId }: { id: string }) => {
|
||||||
|
allUsers = allUsers.filter(({ id }) => id !== userId);
|
||||||
const onUpdate = async () => {
|
|
||||||
await refresh();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { Create } = $derived(getUserAdminsActions($t));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<OnEvents
|
<OnEvents
|
||||||
@@ -49,7 +45,7 @@
|
|||||||
<AdminPageLayout title={data.meta.title}>
|
<AdminPageLayout title={data.meta.title}>
|
||||||
{#snippet buttons()}
|
{#snippet buttons()}
|
||||||
<HStack gap={1}>
|
<HStack gap={1}>
|
||||||
<HeaderButton action={UserAdminsActions.Create} />
|
<HeaderButton action={Create} />
|
||||||
</HStack>
|
</HStack>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
<section id="setting-content" class="flex place-content-center sm:mx-4">
|
<section id="setting-content" class="flex place-content-center sm:mx-4">
|
||||||
@@ -69,7 +65,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
|
<tbody class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
|
||||||
{#each allUsers as user (user.id)}
|
{#each allUsers as user (user.id)}
|
||||||
{@const UserAdminActions = getUserAdminActions($t, user)}
|
{@const { View, ContextMenu } = getUserAdminActions($t, user)}
|
||||||
<tr
|
<tr
|
||||||
class="flex h-20 overflow-hidden w-full place-items-center text-center dark:text-immich-dark-fg {user.deletedAt
|
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'
|
? 'bg-red-300 dark:bg-red-900'
|
||||||
@@ -91,8 +87,8 @@
|
|||||||
<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"
|
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={View} />
|
||||||
<TableButton action={UserAdminActions.ContextMenu} />
|
<TableButton action={ContextMenu} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
Reference in New Issue
Block a user