refactor(web): migrate away from event dispatcher (#12802)

This commit is contained in:
Jason Rasmussen 2024-09-19 18:20:09 -04:00 committed by GitHub
parent cfc575d89c
commit 94fc1f213a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 76 additions and 123 deletions

View File

@ -1,25 +1,21 @@
<script lang="ts"> <script lang="ts">
import Checkbox from '$lib/components/elements/checkbox.svelte';
import FormatMessage from '$lib/components/i18n/format-message.svelte';
import ConfirmDialog from '$lib/components/shared-components/dialog/confirm-dialog.svelte'; import ConfirmDialog from '$lib/components/shared-components/dialog/confirm-dialog.svelte';
import { serverConfig } from '$lib/stores/server-config.store';
import { handleError } from '$lib/utils/handle-error'; import { handleError } from '$lib/utils/handle-error';
import { deleteUserAdmin, type UserResponseDto } from '@immich/sdk'; import { deleteUserAdmin, type UserResponseDto } from '@immich/sdk';
import { serverConfig } from '$lib/stores/server-config.store';
import { createEventDispatcher } from 'svelte';
import Checkbox from '$lib/components/elements/checkbox.svelte';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
import FormatMessage from '$lib/components/i18n/format-message.svelte';
export let user: UserResponseDto; export let user: UserResponseDto;
export let onSuccess: () => void;
export let onFail: () => void;
export let onCancel: () => void;
let forceDelete = false; let forceDelete = false;
let deleteButtonDisabled = false; let deleteButtonDisabled = false;
let userIdInput: string = ''; let userIdInput: string = '';
const dispatch = createEventDispatcher<{
success: void;
fail: void;
cancel: void;
}>();
const handleDeleteUser = async () => { const handleDeleteUser = async () => {
try { try {
const { deletedAt } = await deleteUserAdmin({ const { deletedAt } = await deleteUserAdmin({
@ -28,13 +24,13 @@
}); });
if (deletedAt == undefined) { if (deletedAt == undefined) {
dispatch('fail'); onFail();
} else { } else {
dispatch('success'); onSuccess();
} }
} catch (error) { } catch (error) {
handleError(error, $t('errors.unable_to_delete_user')); handleError(error, $t('errors.unable_to_delete_user'));
dispatch('fail'); onFail();
} }
}; };
@ -48,7 +44,7 @@
title={$t('delete_user')} title={$t('delete_user')}
confirmText={forceDelete ? $t('permanently_delete') : $t('delete')} confirmText={forceDelete ? $t('permanently_delete') : $t('delete')}
onConfirm={handleDeleteUser} onConfirm={handleDeleteUser}
onCancel={() => dispatch('cancel')} {onCancel}
disabled={deleteButtonDisabled} disabled={deleteButtonDisabled}
> >
<svelte:fragment slot="prompt"> <svelte:fragment slot="prompt">

View File

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import Badge from '$lib/components/elements/badge.svelte'; import Badge from '$lib/components/elements/badge.svelte';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import Icon from '$lib/components/elements/icon.svelte'; import Icon from '$lib/components/elements/icon.svelte';
import { locale } from '$lib/stores/preferences.store'; import { locale } from '$lib/stores/preferences.store';
import { JobCommand, type JobCommandDto, type JobCountsDto, type QueueStatusDto } from '@immich/sdk'; import { JobCommand, type JobCommandDto, type JobCountsDto, type QueueStatusDto } from '@immich/sdk';
@ -12,11 +13,10 @@
mdiPlay, mdiPlay,
mdiSelectionSearch, mdiSelectionSearch,
} from '@mdi/js'; } from '@mdi/js';
import { createEventDispatcher, type ComponentType } from 'svelte'; import { type ComponentType } from 'svelte';
import { t } from 'svelte-i18n';
import JobTileButton from './job-tile-button.svelte'; import JobTileButton from './job-tile-button.svelte';
import JobTileStatus from './job-tile-status.svelte'; import JobTileStatus from './job-tile-status.svelte';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import { t } from 'svelte-i18n';
export let title: string; export let title: string;
export let subtitle: string | undefined; export let subtitle: string | undefined;
@ -29,13 +29,12 @@
export let allText: string; export let allText: string;
export let missingText: string; export let missingText: string;
export let onCommand: (command: JobCommandDto) => void;
$: waitingCount = jobCounts.waiting + jobCounts.paused + jobCounts.delayed; $: waitingCount = jobCounts.waiting + jobCounts.paused + jobCounts.delayed;
$: isIdle = !queueStatus.isActive && !queueStatus.isPaused; $: isIdle = !queueStatus.isActive && !queueStatus.isPaused;
const commonClasses = 'flex place-items-center justify-between w-full py-2 sm:py-4 pr-4 pl-6'; const commonClasses = 'flex place-items-center justify-between w-full py-2 sm:py-4 pr-4 pl-6';
const dispatch = createEventDispatcher<{ command: JobCommandDto }>();
</script> </script>
<div <div
@ -66,7 +65,7 @@
title={$t('clear_message')} title={$t('clear_message')}
size="12" size="12"
padding="1" padding="1"
on:click={() => dispatch('command', { command: JobCommand.ClearFailed, force: false })} on:click={() => onCommand({ command: JobCommand.ClearFailed, force: false })}
/> />
</div> </div>
</Badge> </Badge>
@ -117,54 +116,42 @@
<JobTileButton <JobTileButton
disabled={true} disabled={true}
color="light-gray" color="light-gray"
on:click={() => dispatch('command', { command: JobCommand.Start, force: false })} on:click={() => onCommand({ command: JobCommand.Start, force: false })}
> >
<Icon path={mdiAlertCircle} size="36" /> <Icon path={mdiAlertCircle} size="36" />
{$t('disabled').toUpperCase()} {$t('disabled').toUpperCase()}
</JobTileButton> </JobTileButton>
{:else if !isIdle} {:else if !isIdle}
{#if waitingCount > 0} {#if waitingCount > 0}
<JobTileButton color="gray" on:click={() => dispatch('command', { command: JobCommand.Empty, force: false })}> <JobTileButton color="gray" on:click={() => onCommand({ command: JobCommand.Empty, force: false })}>
<Icon path={mdiClose} size="24" /> <Icon path={mdiClose} size="24" />
{$t('clear').toUpperCase()} {$t('clear').toUpperCase()}
</JobTileButton> </JobTileButton>
{/if} {/if}
{#if queueStatus.isPaused} {#if queueStatus.isPaused}
{@const size = waitingCount > 0 ? '24' : '48'} {@const size = waitingCount > 0 ? '24' : '48'}
<JobTileButton <JobTileButton color="light-gray" on:click={() => onCommand({ command: JobCommand.Resume, force: false })}>
color="light-gray"
on:click={() => dispatch('command', { command: JobCommand.Resume, force: false })}
>
<!-- size property is not reactive, so have to use width and height --> <!-- size property is not reactive, so have to use width and height -->
<Icon path={mdiFastForward} {size} /> <Icon path={mdiFastForward} {size} />
{$t('resume').toUpperCase()} {$t('resume').toUpperCase()}
</JobTileButton> </JobTileButton>
{:else} {:else}
<JobTileButton <JobTileButton color="light-gray" on:click={() => onCommand({ command: JobCommand.Pause, force: false })}>
color="light-gray"
on:click={() => dispatch('command', { command: JobCommand.Pause, force: false })}
>
<Icon path={mdiPause} size="24" /> <Icon path={mdiPause} size="24" />
{$t('pause').toUpperCase()} {$t('pause').toUpperCase()}
</JobTileButton> </JobTileButton>
{/if} {/if}
{:else if allowForceCommand} {:else if allowForceCommand}
<JobTileButton color="gray" on:click={() => dispatch('command', { command: JobCommand.Start, force: true })}> <JobTileButton color="gray" on:click={() => onCommand({ command: JobCommand.Start, force: true })}>
<Icon path={mdiAllInclusive} size="24" /> <Icon path={mdiAllInclusive} size="24" />
{allText} {allText}
</JobTileButton> </JobTileButton>
<JobTileButton <JobTileButton color="light-gray" on:click={() => onCommand({ command: JobCommand.Start, force: false })}>
color="light-gray"
on:click={() => dispatch('command', { command: JobCommand.Start, force: false })}
>
<Icon path={mdiSelectionSearch} size="24" /> <Icon path={mdiSelectionSearch} size="24" />
{missingText} {missingText}
</JobTileButton> </JobTileButton>
{:else} {:else}
<JobTileButton <JobTileButton color="light-gray" on:click={() => onCommand({ command: JobCommand.Start, force: false })}>
color="light-gray"
on:click={() => dispatch('command', { command: JobCommand.Start, force: false })}
>
<Icon path={mdiPlay} size="48" /> <Icon path={mdiPlay} size="48" />
{$t('start').toUpperCase()} {$t('start').toUpperCase()}
</JobTileButton> </JobTileButton>

View File

@ -163,7 +163,7 @@
{allowForceCommand} {allowForceCommand}
{jobCounts} {jobCounts}
{queueStatus} {queueStatus}
on:command={({ detail }) => (handleCommandOverride || handleCommand)(jobName, detail)} onCommand={(command) => (handleCommandOverride || handleCommand)(jobName, command)}
/> />
{/each} {/each}
</div> </div>

View File

@ -3,28 +3,24 @@
import ConfirmDialog from '$lib/components/shared-components/dialog/confirm-dialog.svelte'; import ConfirmDialog from '$lib/components/shared-components/dialog/confirm-dialog.svelte';
import { handleError } from '$lib/utils/handle-error'; import { handleError } from '$lib/utils/handle-error';
import { restoreUserAdmin, type UserResponseDto } from '@immich/sdk'; import { restoreUserAdmin, type UserResponseDto } from '@immich/sdk';
import { createEventDispatcher } from 'svelte';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
export let user: UserResponseDto; export let user: UserResponseDto;
export let onSuccess: () => void;
const dispatch = createEventDispatcher<{ export let onFail: () => void;
success: void; export let onCancel: () => void;
fail: void;
cancel: void;
}>();
const handleRestoreUser = async () => { const handleRestoreUser = async () => {
try { try {
const { deletedAt } = await restoreUserAdmin({ id: user.id }); const { deletedAt } = await restoreUserAdmin({ id: user.id });
if (deletedAt == undefined) { if (deletedAt == undefined) {
dispatch('success'); onSuccess();
} else { } else {
dispatch('fail'); onFail();
} }
} catch (error) { } catch (error) {
handleError(error, $t('errors.unable_to_restore_user')); handleError(error, $t('errors.unable_to_restore_user'));
dispatch('fail'); onFail();
} }
}; };
</script> </script>
@ -34,7 +30,7 @@
confirmText={$t('continue')} confirmText={$t('continue')}
confirmColor="green" confirmColor="green"
onConfirm={handleRestoreUser} onConfirm={handleRestoreUser}
onCancel={() => dispatch('cancel')} {onCancel}
> >
<svelte:fragment slot="prompt"> <svelte:fragment slot="prompt">
<p> <p>

View File

@ -1,6 +1,4 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte';
/** /**
* Unique identifier for the checkbox element, used to associate labels with the input element. * Unique identifier for the checkbox element, used to associate labels with the input element.
*/ */
@ -11,9 +9,9 @@
export let ariaDescribedBy: string | undefined = undefined; export let ariaDescribedBy: string | undefined = undefined;
export let checked = false; export let checked = false;
export let disabled = false; export let disabled = false;
export let onToggle: ((checked: boolean) => void) | undefined = undefined;
const dispatch = createEventDispatcher<{ toggle: boolean }>(); const handleToggle = (event: Event) => onToggle?.((event.target as HTMLInputElement).checked);
const onToggle = (event: Event) => dispatch('toggle', (event.target as HTMLInputElement).checked);
</script> </script>
<label class="relative inline-block h-[10px] w-[36px] flex-none"> <label class="relative inline-block h-[10px] w-[36px] flex-none">
@ -22,7 +20,7 @@
class="disabled::cursor-not-allowed h-0 w-0 opacity-0 peer" class="disabled::cursor-not-allowed h-0 w-0 opacity-0 peer"
type="checkbox" type="checkbox"
bind:checked bind:checked
on:click={onToggle} on:click={handleToggle}
{disabled} {disabled}
aria-describedby={ariaDescribedBy} aria-describedby={ariaDescribedBy}
/> />

View File

@ -1,15 +1,15 @@
<script lang="ts"> <script lang="ts">
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
import { featureFlags } from '$lib/stores/server-config.store';
import { serverInfo } from '$lib/stores/server-info.store'; import { serverInfo } from '$lib/stores/server-info.store';
import { ByteUnit, convertToBytes } from '$lib/utils/byte-units';
import { handleError } from '$lib/utils/handle-error'; import { handleError } from '$lib/utils/handle-error';
import { createUserAdmin } from '@immich/sdk'; import { createUserAdmin } from '@immich/sdk';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import Button from '../elements/buttons/button.svelte';
import PasswordField from '../shared-components/password-field.svelte';
import Slider from '../elements/slider.svelte';
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
import { featureFlags } from '$lib/stores/server-config.store';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
import { ByteUnit, convertToBytes } from '$lib/utils/byte-units'; import Button from '../elements/buttons/button.svelte';
import Slider from '../elements/slider.svelte';
import PasswordField from '../shared-components/password-field.svelte';
export let onClose: () => void; export let onClose: () => void;

View File

@ -760,7 +760,7 @@
{/if} {/if}
{#if showShortcuts} {#if showShortcuts}
<ShowShortcuts on:close={() => (showShortcuts = !showShortcuts)} /> <ShowShortcuts onClose={() => (showShortcuts = !showShortcuts)} />
{/if} {/if}
{#if assetStore.buckets.length > 0} {#if assetStore.buckets.length > 0}
<Scrubber <Scrubber

View File

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import { page } from '$app/stores';
import { focusTrap } from '$lib/actions/focus-trap'; import { focusTrap } from '$lib/actions/focus-trap';
import Button from '$lib/components/elements/buttons/button.svelte'; import Button from '$lib/components/elements/buttons/button.svelte';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte'; import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
@ -9,12 +10,11 @@
import { deleteProfileImage, updateMyPreferences, type UserAvatarColor } from '@immich/sdk'; import { deleteProfileImage, updateMyPreferences, type UserAvatarColor } from '@immich/sdk';
import { mdiCog, mdiLogout, mdiPencil, mdiWrench } from '@mdi/js'; import { mdiCog, mdiLogout, mdiPencil, mdiWrench } from '@mdi/js';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import { NotificationType, notificationController } from '../notification/notification'; import { NotificationType, notificationController } from '../notification/notification';
import UserAvatar from '../user-avatar.svelte'; import UserAvatar from '../user-avatar.svelte';
import AvatarSelector from './avatar-selector.svelte'; import AvatarSelector from './avatar-selector.svelte';
import { t } from 'svelte-i18n';
import { page } from '$app/stores';
let isShowSelectAvatar = false; let isShowSelectAvatar = false;
@ -120,9 +120,5 @@
</div> </div>
{#if isShowSelectAvatar} {#if isShowSelectAvatar}
<AvatarSelector <AvatarSelector user={$user} onClose={() => (isShowSelectAvatar = false)} onChoose={handleSaveProfile} />
user={$user}
on:close={() => (isShowSelectAvatar = false)}
on:choose={({ detail: color }) => handleSaveProfile(color)}
/>
{/if} {/if}

View File

@ -1,24 +1,21 @@
<script lang="ts"> <script lang="ts">
import { UserAvatarColor, type UserResponseDto } from '@immich/sdk'; import { UserAvatarColor, type UserResponseDto } from '@immich/sdk';
import { createEventDispatcher } from 'svelte'; import { t } from 'svelte-i18n';
import FullScreenModal from '../full-screen-modal.svelte'; import FullScreenModal from '../full-screen-modal.svelte';
import UserAvatar from '../user-avatar.svelte'; import UserAvatar from '../user-avatar.svelte';
import { t } from 'svelte-i18n';
export let user: UserResponseDto; export let user: UserResponseDto;
export let onClose: () => void;
export let onChoose: (color: UserAvatarColor) => void;
const dispatch = createEventDispatcher<{
close: void;
choose: UserAvatarColor;
}>();
const colors: UserAvatarColor[] = Object.values(UserAvatarColor); const colors: UserAvatarColor[] = Object.values(UserAvatarColor);
</script> </script>
<FullScreenModal title={$t('select_avatar_color')} width="auto" onClose={() => dispatch('close')}> <FullScreenModal title={$t('select_avatar_color')} width="auto" {onClose}>
<div class="flex items-center justify-center mt-4"> <div class="flex items-center justify-center mt-4">
<div class="grid grid-cols-2 md:grid-cols-5 gap-4"> <div class="grid grid-cols-2 md:grid-cols-5 gap-4">
{#each colors as color} {#each colors as color}
<button type="button" on:click={() => dispatch('choose', color)}> <button type="button" on:click={() => onChoose(color)}>
<UserAvatar label={color} {user} {color} size="xl" showProfileImage={false} /> <UserAvatar label={color} {user} {color} size="xl" showProfileImage={false} />
</button> </button>
{/each} {/each}

View File

@ -43,11 +43,5 @@
<slot /> <slot />
</div> </div>
<Slider <Slider id={sliderId} bind:checked {disabled} {onToggle} ariaDescribedBy={subtitleId} />
id={sliderId}
bind:checked
{disabled}
on:toggle={({ detail }) => onToggle(detail)}
ariaDescribedBy={subtitleId}
/>
</div> </div>

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte';
import FullScreenModal from './full-screen-modal.svelte';
import { mdiInformationOutline } from '@mdi/js'; import { mdiInformationOutline } from '@mdi/js';
import Icon from '../elements/icon.svelte';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
import Icon from '../elements/icon.svelte';
import FullScreenModal from './full-screen-modal.svelte';
interface Shortcuts { interface Shortcuts {
general: ExplainedShortcut[]; general: ExplainedShortcut[];
@ -16,6 +15,8 @@
info?: string; info?: string;
} }
export let onClose: () => void;
export let shortcuts: Shortcuts = { export let shortcuts: Shortcuts = {
general: [ general: [
{ key: ['←', '→'], action: $t('previous_or_next_photo') }, { key: ['←', '→'], action: $t('previous_or_next_photo') },
@ -33,12 +34,9 @@
{ key: ['Del'], action: $t('trash_delete_asset'), info: $t('shift_to_permanent_delete') }, { key: ['Del'], action: $t('trash_delete_asset'), info: $t('shift_to_permanent_delete') },
], ],
}; };
const dispatch = createEventDispatcher<{
close: void;
}>();
</script> </script>
<FullScreenModal title={$t('keyboard_shortcuts')} width="auto" onClose={() => dispatch('close')}> <FullScreenModal title={$t('keyboard_shortcuts')} width="auto" {onClose}>
<div class="grid grid-cols-1 gap-4 px-4 pb-4 md:grid-cols-2"> <div class="grid grid-cols-1 gap-4 px-4 pb-4 md:grid-cols-2">
{#if shortcuts.general.length > 0} {#if shortcuts.general.length > 0}
<div class="p-4"> <div class="p-4">

View File

@ -15,14 +15,10 @@
mdiUbuntu, mdiUbuntu,
} from '@mdi/js'; } from '@mdi/js';
import { DateTime, type ToRelativeCalendarOptions } from 'luxon'; import { DateTime, type ToRelativeCalendarOptions } from 'luxon';
import { createEventDispatcher } from 'svelte';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
export let device: SessionResponseDto; export let device: SessionResponseDto;
export let onDelete: (() => void) | undefined = undefined;
const dispatcher = createEventDispatcher<{
delete: void;
}>();
const options: ToRelativeCalendarOptions = { const options: ToRelativeCalendarOptions = {
unit: 'days', unit: 'days',
@ -68,14 +64,14 @@
</span> </span>
</div> </div>
</div> </div>
{#if !device.current} {#if !device.current && onDelete}
<div> <div>
<CircleIconButton <CircleIconButton
color="primary" color="primary"
icon={mdiTrashCanOutline} icon={mdiTrashCanOutline}
title={$t('log_out')} title={$t('log_out')}
size="16" size="16"
on:click={() => dispatcher('delete')} on:click={onDelete}
/> />
</div> </div>
{/if} {/if}

View File

@ -68,7 +68,7 @@
{$t('other_devices').toUpperCase()} {$t('other_devices').toUpperCase()}
</h3> </h3>
{#each otherDevices as device, index} {#each otherDevices as device, index}
<DeviceCard {device} on:delete={() => handleDelete(device)} /> <DeviceCard {device} onDelete={() => handleDelete(device)} />
{#if index !== otherDevices.length - 1} {#if index !== otherDevices.length - 1}
<hr class="my-3" /> <hr class="my-3" />
{/if} {/if}

View File

@ -1,19 +1,18 @@
<script lang="ts"> <script lang="ts">
import { searchUsers, getPartners, type UserResponseDto, PartnerDirection } from '@immich/sdk'; import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
import { createEventDispatcher, onMount } from 'svelte'; import { getPartners, PartnerDirection, searchUsers, type UserResponseDto } from '@immich/sdk';
import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
import Button from '../elements/buttons/button.svelte'; import Button from '../elements/buttons/button.svelte';
import UserAvatar from '../shared-components/user-avatar.svelte'; import UserAvatar from '../shared-components/user-avatar.svelte';
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
import { t } from 'svelte-i18n';
export let user: UserResponseDto; export let user: UserResponseDto;
export let onClose: () => void; export let onClose: () => void;
export let onAddUsers: (users: UserResponseDto[]) => void;
let availableUsers: UserResponseDto[] = []; let availableUsers: UserResponseDto[] = [];
let selectedUsers: UserResponseDto[] = []; let selectedUsers: UserResponseDto[] = [];
const dispatch = createEventDispatcher<{ 'add-users': UserResponseDto[] }>();
onMount(async () => { onMount(async () => {
let users = await searchUsers(); let users = await searchUsers();
@ -69,7 +68,7 @@
{#if selectedUsers.length > 0} {#if selectedUsers.length > 0}
<div class="pt-5"> <div class="pt-5">
<Button size="sm" fullwidth on:click={() => dispatch('add-users', selectedUsers)}>{$t('add')}</Button> <Button size="sm" fullwidth on:click={() => onAddUsers(selectedUsers)}>{$t('add')}</Button>
</div> </div>
{/if} {/if}
</div> </div>

View File

@ -191,9 +191,5 @@
</section> </section>
{#if createPartnerFlag} {#if createPartnerFlag}
<PartnerSelectionModal <PartnerSelectionModal {user} onClose={() => (createPartnerFlag = false)} onAddUsers={handleCreatePartners} />
{user}
onClose={() => (createPartnerFlag = false)}
on:add-users={(event) => handleCreatePartners(event.detail)}
/>
{/if} {/if}

View File

@ -27,5 +27,5 @@
</UserPageLayout> </UserPageLayout>
{#if isShowKeyboardShortcut} {#if isShowKeyboardShortcut}
<ShowShortcuts on:close={() => (isShowKeyboardShortcut = false)} /> <ShowShortcuts onClose={() => (isShowKeyboardShortcut = false)} />
{/if} {/if}

View File

@ -196,5 +196,5 @@
</UserPageLayout> </UserPageLayout>
{#if isShowKeyboardShortcut} {#if isShowKeyboardShortcut}
<ShowShortcuts shortcuts={duplicateShortcuts} on:close={() => (isShowKeyboardShortcut = false)} /> <ShowShortcuts shortcuts={duplicateShortcuts} onClose={() => (isShowKeyboardShortcut = false)} />
{/if} {/if}

View File

@ -1,6 +1,5 @@
<script lang="ts"> <script lang="ts">
import { page } from '$app/stores'; import { page } from '$app/stores';
import ConfirmDialog from '$lib/components/shared-components/dialog/confirm-dialog.svelte';
import DeleteConfirmDialog from '$lib/components/admin-page/delete-confirm-dialogue.svelte'; import DeleteConfirmDialog from '$lib/components/admin-page/delete-confirm-dialogue.svelte';
import RestoreDialogue from '$lib/components/admin-page/restore-dialogue.svelte'; import RestoreDialogue from '$lib/components/admin-page/restore-dialogue.svelte';
import Button from '$lib/components/elements/buttons/button.svelte'; import Button from '$lib/components/elements/buttons/button.svelte';
@ -10,6 +9,7 @@
import CreateUserForm from '$lib/components/forms/create-user-form.svelte'; import CreateUserForm from '$lib/components/forms/create-user-form.svelte';
import EditUserForm from '$lib/components/forms/edit-user-form.svelte'; import EditUserForm from '$lib/components/forms/edit-user-form.svelte';
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte'; import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
import ConfirmDialog from '$lib/components/shared-components/dialog/confirm-dialog.svelte';
import { import {
NotificationType, NotificationType,
notificationController, notificationController,
@ -21,11 +21,11 @@
import { copyToClipboard } from '$lib/utils'; import { copyToClipboard } from '$lib/utils';
import { getByteUnitString } from '$lib/utils/byte-units'; import { getByteUnitString } from '$lib/utils/byte-units';
import { UserStatus, searchUsersAdmin, type UserAdminResponseDto } from '@immich/sdk'; import { UserStatus, searchUsersAdmin, type UserAdminResponseDto } from '@immich/sdk';
import { mdiInfinity, mdiContentCopy, mdiDeleteRestore, mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js'; import { mdiContentCopy, mdiDeleteRestore, mdiInfinity, mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import type { PageData } from './$types';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
import type { PageData } from './$types';
export let data: PageData; export let data: PageData;
@ -130,18 +130,18 @@
{#if shouldShowDeleteConfirmDialog} {#if shouldShowDeleteConfirmDialog}
<DeleteConfirmDialog <DeleteConfirmDialog
user={selectedUser} user={selectedUser}
on:success={onUserDelete} onSuccess={onUserDelete}
on:fail={onUserDelete} onFail={onUserDelete}
on:cancel={() => (shouldShowDeleteConfirmDialog = false)} onCancel={() => (shouldShowDeleteConfirmDialog = false)}
/> />
{/if} {/if}
{#if shouldShowRestoreDialog} {#if shouldShowRestoreDialog}
<RestoreDialogue <RestoreDialogue
user={selectedUser} user={selectedUser}
on:success={onUserRestore} onSuccess={onUserRestore}
on:fail={onUserRestore} onFail={onUserRestore}
on:cancel={() => (shouldShowRestoreDialog = false)} onCancel={() => (shouldShowRestoreDialog = false)}
/> />
{/if} {/if}