Skip to content

Commit

Permalink
chore(web): migration svelte 5 syntax (immich-app#13883)
Browse files Browse the repository at this point in the history
  • Loading branch information
alextran1502 authored and bdavis2-PCTY committed Nov 18, 2024
1 parent d561ad9 commit ff5b0d5
Show file tree
Hide file tree
Showing 310 changed files with 6,441 additions and 4,182 deletions.
6 changes: 3 additions & 3 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@faker-js/faker": "^9.0.0",
"@socket.io/component-emitter": "^3.1.0",
"@sveltejs/adapter-static": "^3.0.5",
"@sveltejs/enhanced-img": "^0.3.0",
"@sveltejs/enhanced-img": "^0.3.9",
"@sveltejs/kit": "^2.7.2",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@testing-library/jest-dom": "^6.4.2",
Expand All @@ -45,7 +45,7 @@
"dotenv": "^16.4.5",
"eslint": "^9.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.43.0",
"eslint-plugin-svelte": "^2.45.1",
"eslint-plugin-unicorn": "^55.0.0",
"factory.ts": "^1.4.1",
"globals": "^15.9.0",
Expand All @@ -60,7 +60,7 @@
"tailwindcss": "^3.4.1",
"tslib": "^2.6.2",
"typescript": "^5.5.0",
"vite": "^5.1.4",
"vite": "^5.4.4",
"vitest": "^2.0.5"
},
"type": "module",
Expand Down
10 changes: 7 additions & 3 deletions web/src/lib/actions/__test__/focus-trap-test.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
<script lang="ts">
import { focusTrap } from '$lib/actions/focus-trap';
export let show: boolean;
interface Props {
show: boolean;
}
let { show = $bindable() }: Props = $props();
</script>

<button type="button" on:click={() => (show = true)}>Open</button>
<button type="button" onclick={() => (show = true)}>Open</button>

{#if show}
<div use:focusTrap>
<div>
<span>text</span>
<button data-testid="one" type="button" on:click={() => (show = false)}>Close</button>
<button data-testid="one" type="button" onclick={() => (show = false)}>Close</button>
</div>
<input data-testid="two" disabled />
<input data-testid="three" />
Expand Down
2 changes: 1 addition & 1 deletion web/src/lib/actions/autogrow.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const autoGrowHeight = (textarea: HTMLTextAreaElement, height = 'auto') => {
export const autoGrowHeight = (textarea?: HTMLTextAreaElement, height = 'auto') => {
if (!textarea) {
return;
}
Expand Down
8 changes: 6 additions & 2 deletions web/src/lib/actions/context-menu-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface Options {
/**
* The container element that with direct children that should be navigated.
*/
container: HTMLElement;
container?: HTMLElement;
/**
* Indicates if the dropdown is open.
*/
Expand Down Expand Up @@ -52,7 +52,11 @@ export const contextMenuNavigation: Action<HTMLElement, Options> = (node, option
await tick();
}

const children = Array.from(container?.children).filter((child) => child.tagName !== 'HR') as HTMLElement[];
if (!container) {
return;
}

const children = Array.from(container.children).filter((child) => child.tagName !== 'HR') as HTMLElement[];
if (children.length === 0) {
return;
}
Expand Down
9 changes: 8 additions & 1 deletion web/src/lib/actions/list-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ import type { Action } from 'svelte/action';
* @param node Element which listens for keyboard events
* @param container Element containing the list of elements
*/
export const listNavigation: Action<HTMLElement, HTMLElement> = (node, container: HTMLElement) => {
export const listNavigation: Action<HTMLElement, HTMLElement | undefined> = (
node: HTMLElement,
container?: HTMLElement,
) => {
const moveFocus = (direction: 'up' | 'down') => {
if (!container) {
return;
}

const children = Array.from(container?.children);
if (children.length === 0) {
return;
Expand Down
35 changes: 21 additions & 14 deletions web/src/lib/components/admin-page/delete-confirm-dialogue.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
import { deleteUserAdmin, type UserResponseDto } from '@immich/sdk';
import { t } from 'svelte-i18n';
export let user: UserResponseDto;
export let onSuccess: () => void;
export let onFail: () => void;
export let onCancel: () => void;
interface Props {
user: UserResponseDto;
onSuccess: () => void;
onFail: () => void;
onCancel: () => void;
}
let forceDelete = false;
let deleteButtonDisabled = false;
let { user, onSuccess, onFail, onCancel }: Props = $props();
let forceDelete = $state(false);
let deleteButtonDisabled = $state(false);
let userIdInput: string = '';
const handleDeleteUser = async () => {
Expand Down Expand Up @@ -47,22 +51,25 @@
{onCancel}
disabled={deleteButtonDisabled}
>
<svelte:fragment slot="prompt">
{#snippet promptSnippet()}
<div class="flex flex-col gap-4">
{#if forceDelete}
<p>
<FormatMessage key="admin.user_delete_immediately" values={{ user: user.name }} let:message>
<b>{message}</b>
<FormatMessage key="admin.user_delete_immediately" values={{ user: user.name }}>
{#snippet children({ message })}
<b>{message}</b>
{/snippet}
</FormatMessage>
</p>
{:else}
<p>
<FormatMessage
key="admin.user_delete_delay"
values={{ user: user.name, delay: $serverConfig.userDeleteDelay }}
let:message
>
<b>{message}</b>
{#snippet children({ message })}
<b>{message}</b>
{/snippet}
</FormatMessage>
</p>
{/if}
Expand All @@ -73,7 +80,7 @@
label={$t('admin.user_delete_immediately_checkbox')}
labelClass="text-sm dark:text-immich-dark-fg"
bind:checked={forceDelete}
on:change={() => {
onchange={() => {
deleteButtonDisabled = forceDelete;
}}
/>
Expand All @@ -92,9 +99,9 @@
aria-describedby="confirm-user-desc"
name="confirm-user-id"
type="text"
on:input={handleConfirm}
oninput={handleConfirm}
/>
{/if}
</div>
</svelte:fragment>
{/snippet}
</ConfirmDialog>
18 changes: 13 additions & 5 deletions web/src/lib/components/admin-page/jobs/job-tile-button.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
<script lang="ts" context="module">
<script lang="ts" module>
export type Colors = 'light-gray' | 'gray' | 'dark-gray';
</script>

<script lang="ts">
export let color: Colors;
export let disabled = false;
import type { Snippet } from 'svelte';
interface Props {
color: Colors;
disabled?: boolean;
children?: Snippet;
onClick?: () => void;
}
let { color, disabled = false, onClick = () => {}, children }: Props = $props();
const colorClasses: Record<Colors, string> = {
'light-gray': 'bg-gray-300/80 dark:bg-gray-700',
Expand All @@ -23,7 +31,7 @@
class="flex h-full w-full flex-col place-content-center place-items-center gap-2 px-8 py-2 text-xs text-gray-600 transition-colors dark:text-gray-200 {colorClasses[
color
]} {hoverClasses}"
on:click
onclick={onClick}
>
<slot />
{@render children?.()}
</button>
13 changes: 10 additions & 3 deletions web/src/lib/components/admin-page/jobs/job-tile-status.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
<script lang="ts" context="module">
<script lang="ts" module>
export type Color = 'success' | 'warning';
</script>

<script lang="ts">
export let color: Color;
import type { Snippet } from 'svelte';
interface Props {
color: Color;
children?: Snippet;
}
let { color, children }: Props = $props();
const colorClasses: Record<Color, string> = {
success: 'bg-green-500/70 text-gray-900 dark:bg-green-700/90 dark:text-gray-100',
Expand All @@ -12,5 +19,5 @@
</script>

<div class="w-full p-2 text-center text-sm {colorClasses[color]}">
<slot />
{@render children?.()}
</div>
64 changes: 40 additions & 24 deletions web/src/lib/components/admin-page/jobs/job-tile.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,37 @@
import JobTileButton from './job-tile-button.svelte';
import JobTileStatus from './job-tile-status.svelte';
export let title: string;
export let subtitle: string | undefined;
export let description: Component | undefined;
export let jobCounts: JobCountsDto;
export let queueStatus: QueueStatusDto;
export let icon: string;
export let disabled = false;
interface Props {
title: string;
subtitle: string | undefined;
description: Component | undefined;
jobCounts: JobCountsDto;
queueStatus: QueueStatusDto;
icon: string;
disabled?: boolean;
allText: string | undefined;
refreshText: string | undefined;
missingText: string;
onCommand: (command: JobCommandDto) => void;
}
export let allText: string | undefined;
export let refreshText: string | undefined;
export let missingText: string;
export let onCommand: (command: JobCommandDto) => void;
let {
title,
subtitle,
description,
jobCounts,
queueStatus,
icon,
disabled = false,
allText,
refreshText,
missingText,
onCommand,
}: Props = $props();
$: waitingCount = jobCounts.waiting + jobCounts.paused + jobCounts.delayed;
$: isIdle = !queueStatus.isActive && !queueStatus.isPaused;
$: multipleButtons = allText || refreshText;
let waitingCount = $derived(jobCounts.waiting + jobCounts.paused + jobCounts.delayed);
let isIdle = $derived(!queueStatus.isActive && !queueStatus.isPaused);
let multipleButtons = $derived(allText || refreshText);
const commonClasses = 'flex place-items-center justify-between w-full py-2 sm:py-4 pr-4 pl-6';
</script>
Expand Down Expand Up @@ -67,7 +82,7 @@
title={$t('clear_message')}
size="12"
padding="1"
on:click={() => onCommand({ command: JobCommand.ClearFailed, force: false })}
onclick={() => onCommand({ command: JobCommand.ClearFailed, force: false })}
/>
</div>
</Badge>
Expand All @@ -87,8 +102,9 @@
{/if}

{#if description}
{@const SvelteComponent = description}
<div class="text-sm dark:text-white">
<svelte:component this={description} />
<SvelteComponent />
</div>
{/if}

Expand Down Expand Up @@ -118,7 +134,7 @@
<JobTileButton
disabled={true}
color="light-gray"
on:click={() => onCommand({ command: JobCommand.Start, force: false })}
onClick={() => onCommand({ command: JobCommand.Start, force: false })}
>
<Icon path={mdiAlertCircle} size="36" />
{$t('disabled').toUpperCase()}
Expand All @@ -127,20 +143,20 @@

{#if !disabled && !isIdle}
{#if waitingCount > 0}
<JobTileButton color="gray" on:click={() => onCommand({ command: JobCommand.Empty, force: false })}>
<JobTileButton color="gray" onClick={() => onCommand({ command: JobCommand.Empty, force: false })}>
<Icon path={mdiClose} size="24" />
{$t('clear').toUpperCase()}
</JobTileButton>
{/if}
{#if queueStatus.isPaused}
{@const size = waitingCount > 0 ? '24' : '48'}
<JobTileButton color="light-gray" on:click={() => onCommand({ command: JobCommand.Resume, force: false })}>
<JobTileButton color="light-gray" onClick={() => onCommand({ command: JobCommand.Resume, force: false })}>
<!-- size property is not reactive, so have to use width and height -->
<Icon path={mdiFastForward} {size} />
{$t('resume').toUpperCase()}
</JobTileButton>
{:else}
<JobTileButton color="light-gray" on:click={() => onCommand({ command: JobCommand.Pause, force: false })}>
<JobTileButton color="light-gray" onClick={() => onCommand({ command: JobCommand.Pause, force: false })}>
<Icon path={mdiPause} size="24" />
{$t('pause').toUpperCase()}
</JobTileButton>
Expand All @@ -149,25 +165,25 @@

{#if !disabled && multipleButtons && isIdle}
{#if allText}
<JobTileButton color="dark-gray" on:click={() => onCommand({ command: JobCommand.Start, force: true })}>
<JobTileButton color="dark-gray" onClick={() => onCommand({ command: JobCommand.Start, force: true })}>
<Icon path={mdiAllInclusive} size="24" />
{allText}
</JobTileButton>
{/if}
{#if refreshText}
<JobTileButton color="gray" on:click={() => onCommand({ command: JobCommand.Start, force: undefined })}>
<JobTileButton color="gray" onClick={() => onCommand({ command: JobCommand.Start, force: undefined })}>
<Icon path={mdiImageRefreshOutline} size="24" />
{refreshText}
</JobTileButton>
{/if}
<JobTileButton color="light-gray" on:click={() => onCommand({ command: JobCommand.Start, force: false })}>
<JobTileButton color="light-gray" onClick={() => onCommand({ command: JobCommand.Start, force: false })}>
<Icon path={mdiSelectionSearch} size="24" />
{missingText}
</JobTileButton>
{/if}

{#if !disabled && !multipleButtons && isIdle}
<JobTileButton color="light-gray" on:click={() => onCommand({ command: JobCommand.Start, force: false })}>
<JobTileButton color="light-gray" onClick={() => onCommand({ command: JobCommand.Start, force: false })}>
<Icon path={mdiPlay} size="48" />
{$t('start').toUpperCase()}
</JobTileButton>
Expand Down
Loading

0 comments on commit ff5b0d5

Please sign in to comment.