From 87d13ac0d96fc4c83351168afdeefd3091132ab4 Mon Sep 17 00:00:00 2001 From: Alex Tran Date: Sat, 2 Nov 2024 13:52:04 -0500 Subject: [PATCH 01/70] chore(web): migration svelte 5 syntax --- web/package-lock.json | 6 +- web/package.json | 6 +- .../actions/__test__/focus-trap-test.svelte | 10 +- .../admin-page/delete-confirm-dialogue.svelte | 35 ++- .../admin-page/jobs/job-tile-button.svelte | 16 +- .../admin-page/jobs/job-tile-status.svelte | 11 +- .../admin-page/jobs/job-tile.svelte | 62 +++-- .../admin-page/jobs/jobs-panel.svelte | 1 + .../jobs/storage-migration-description.svelte | 16 +- .../admin-page/restore-dialogue.svelte | 35 ++- .../server-stats/server-stats-panel.svelte | 14 +- .../admin-page/server-stats/stats-card.svelte | 21 +- .../admin-page/settings/admin-settings.svelte | 19 +- .../settings/auth/auth-settings.svelte | 90 ++++--- .../backup-settings/backup-settings.svelte | 66 +++-- .../settings/ffmpeg/ffmpeg-settings.svelte | 60 +++-- .../settings/image/image-settings.svelte | 31 ++- .../settings/job-settings/job-settings.svelte | 28 +- .../library-settings/library-settings.svelte | 67 +++-- .../logging-settings/logging-settings.svelte | 28 +- .../machine-learning-settings.svelte | 42 ++- .../settings/map-settings/map-settings.svelte | 60 +++-- .../metadata-settings.svelte | 28 +- .../new-version-check-settings.svelte | 28 +- .../notification-settings.svelte | 32 ++- .../settings/server/server-settings.svelte | 28 +- .../storage-template-settings.svelte | 130 +++++---- .../supported-datetime-panel.svelte | 6 +- .../settings/theme/theme-settings.svelte | 28 +- .../trash-settings/trash-settings.svelte | 28 +- .../user-settings/user-settings.svelte | 28 +- .../album-page/album-card-group.svelte | 34 ++- .../components/album-page/album-card.svelte | 23 +- .../components/album-page/album-cover.svelte | 16 +- .../album-page/album-description.svelte | 10 +- .../album-page/album-options.svelte | 38 ++- .../album-page/album-summary.svelte | 10 +- .../components/album-page/album-title.svelte | 26 +- .../components/album-page/album-viewer.svelte | 54 ++-- .../album-page/albums-controls.svelte | 62 +++-- .../components/album-page/albums-list.svelte | 70 +++-- .../album-page/albums-table-header.svelte | 12 +- .../album-page/albums-table-row.svelte | 15 +- .../components/album-page/albums-table.svelte | 13 +- .../album-page/share-info-modal.svelte | 25 +- .../album-page/user-selection-modal.svelte | 29 +- .../actions/add-to-album-action.svelte | 12 +- .../actions/archive-action.svelte | 8 +- .../asset-viewer/actions/close-action.svelte | 6 +- .../asset-viewer/actions/delete-action.svelte | 10 +- .../actions/download-action.svelte | 8 +- .../actions/favorite-action.svelte | 8 +- .../actions/motion-photo-action.svelte | 8 +- .../actions/next-asset-action.svelte | 6 +- .../actions/previous-asset-action.svelte | 6 +- .../actions/restore-action.svelte | 8 +- .../actions/set-album-cover-action.svelte | 8 +- .../actions/set-profile-picture-action.svelte | 8 +- .../asset-viewer/actions/share-action.svelte | 8 +- .../actions/show-detail-action.svelte | 6 +- .../actions/unstack-action.svelte | 8 +- .../asset-viewer/activity-status.svelte | 24 +- .../asset-viewer/activity-viewer.svelte | 85 +++--- .../album-list-item-details.svelte | 6 +- .../asset-viewer/album-list-item.svelte | 20 +- .../asset-viewer/asset-viewer-nav-bar.svelte | 1 + .../asset-viewer/asset-viewer.svelte | 114 ++++---- .../detail-panel-description.svelte | 15 +- .../asset-viewer/detail-panel-location.svelte | 14 +- .../detail-panel-star-rating.svelte | 10 +- .../asset-viewer/detail-panel-tags.svelte | 16 +- .../asset-viewer/detail-panel.svelte | 111 ++++---- .../editor/crop-tool/crop-area.svelte | 1 + .../editor/crop-tool/crop-preset.svelte | 29 +- .../editor/crop-tool/crop-tool.svelte | 8 +- .../asset-viewer/editor/editor-panel.svelte | 16 +- .../asset-viewer/navigation-area.svelte | 13 +- .../asset-viewer/panorama-viewer.svelte | 9 +- .../photo-sphere-viewer-adapter.svelte | 22 +- .../asset-viewer/photo-viewer.svelte | 72 +++-- .../asset-viewer/slideshow-bar.svelte | 36 ++- .../asset-viewer/video-native-viewer.svelte | 56 ++-- .../asset-viewer/video-wrapper-viewer.svelte | 23 +- .../lib/components/assets/broken-asset.svelte | 19 +- .../assets/thumbnail/image-thumbnail.svelte | 61 +++-- .../assets/thumbnail/thumbnail.svelte | 128 +++++---- .../assets/thumbnail/video-thumbnail.svelte | 68 +++-- web/src/lib/components/elements/badge.svelte | 13 +- .../components/elements/buttons/button.svelte | 59 ++-- .../buttons/circle-icon-button.svelte | 72 +++-- .../elements/buttons/link-button.svelte | 14 +- .../elements/buttons/skip-link.svelte | 13 +- .../lib/components/elements/checkbox.svelte | 30 ++- .../lib/components/elements/date-input.svelte | 28 +- .../lib/components/elements/dropdown.svelte | 43 ++- .../lib/components/elements/group-tab.svelte | 19 +- web/src/lib/components/elements/icon.svelte | 52 ++-- .../components/elements/radio-button.svelte | 20 +- .../lib/components/elements/search-bar.svelte | 29 +- web/src/lib/components/elements/slider.svelte | 28 +- web/src/lib/components/error.svelte | 6 +- .../faces-page/assign-face-side-panel.svelte | 40 ++- .../faces-page/edit-name-input.svelte | 27 +- .../faces-page/face-thumbnail.svelte | 28 +- .../manage-people-visibility.svelte | 105 +++++--- .../faces-page/merge-face-selector.svelte | 52 ++-- .../faces-page/merge-suggestion-modal.svelte | 32 ++- .../components/faces-page/people-card.svelte | 31 ++- .../faces-page/people-infinite-scroll.svelte | 34 ++- .../components/faces-page/people-list.svelte | 29 +- .../faces-page/people-search.svelte | 39 ++- .../faces-page/person-side-panel.svelte | 41 +-- .../faces-page/set-birth-date-modal.svelte | 15 +- .../faces-page/unmerge-face-selector.svelte | 117 ++++---- .../forms/admin-registration-form.svelte | 20 +- .../lib/components/forms/api-key-form.svelte | 28 +- .../components/forms/api-key-secret.svelte | 9 +- .../forms/change-password-form.svelte | 22 +- .../components/forms/create-user-form.svelte | 52 ++-- .../components/forms/edit-album-form.svelte | 28 +- .../components/forms/edit-user-form.svelte | 36 ++- .../library-exclusion-pattern-form.svelte | 35 ++- .../forms/library-import-path-form.svelte | 41 ++- .../forms/library-import-paths-form.svelte | 26 +- .../forms/library-rename-form.svelte | 14 +- .../forms/library-scan-settings-form.svelte | 24 +- .../forms/library-user-picker-form.svelte | 17 +- .../lib/components/forms/login-form.svelte | 26 +- .../components/forms/tag-asset-form.svelte | 35 ++- .../i18n/__test__/format-tag-b.svelte | 18 +- .../i18n/format-bold-message.svelte | 18 +- .../lib/components/i18n/format-message.svelte | 19 +- .../layouts/user-page-layout.svelte | 49 ++-- .../map-page/map-settings-modal.svelte | 17 +- .../memory-page/memory-viewer.svelte | 54 ++-- .../onboarding-page/onboarding-card.svelte | 11 +- .../onboarding-page/onboarding-hello.svelte | 6 +- .../onboarding-page/onboarding-privacy.svelte | 76 +++--- .../onboarding-storage-template.svelte | 86 +++--- .../onboarding-page/onboarding-theme.svelte | 10 +- .../photos-page/actions/add-to-album.svelte | 10 +- .../photos-page/actions/archive-action.svelte | 16 +- .../actions/asset-job-actions.svelte | 10 +- .../actions/change-date-action.svelte | 8 +- .../actions/change-location-action.svelte | 8 +- .../actions/create-shared-link.svelte | 2 +- .../photos-page/actions/delete-assets.svelte | 16 +- .../actions/download-action.svelte | 10 +- .../actions/favorite-action.svelte | 16 +- .../actions/link-live-photo-action.svelte | 23 +- .../actions/remove-from-album.svelte | 10 +- .../actions/remove-from-shared-link.svelte | 6 +- .../photos-page/actions/restore-assets.svelte | 8 +- .../actions/select-all-assets.svelte | 8 +- .../photos-page/actions/stack-action.svelte | 10 +- .../photos-page/actions/tag-action.svelte | 10 +- .../photos-page/asset-date-group.svelte | 76 ++++-- .../components/photos-page/asset-grid.svelte | 221 ++++++++------- .../asset-select-control-bar.svelte | 32 ++- .../photos-page/delete-asset-dialog.svelte | 38 +-- .../photos-page/measure-date-group.svelte | 12 +- .../components/photos-page/memory-lane.svelte | 20 +- .../components/photos-page/skeleton.svelte | 8 +- .../individual-shared-viewer.svelte | 52 ++-- .../album-selection-modal.svelte | 49 ++-- .../autogrow-textarea.svelte | 36 ++- .../shared-components/change-date.svelte | 38 ++- .../shared-components/change-location.svelte | 190 ++++++------- .../shared-components/combobox.svelte | 69 +++-- .../context-menu/button-context-menu.svelte | 69 +++-- .../context-menu/context-menu.svelte | 51 ++-- .../context-menu/menu-option.svelte | 35 ++- .../right-click-context-menu.svelte | 51 ++-- .../shared-components/control-app-bar.svelte | 36 ++- .../coordinates-input.svelte | 10 +- .../create-shared-link-modal.svelte | 55 ++-- .../dialog/confirm-dialog.svelte | 1 + .../drag-and-drop-upload-overlay.svelte | 20 +- .../empty-placeholder.svelte | 23 +- .../full-screen-modal.svelte | 1 + .../fullscreen-container.svelte | 19 +- .../gallery-viewer/gallery-viewer.svelte | 38 ++- .../help-and-feedback-modal.svelte | 8 +- .../immich-logo-small-link.svelte | 6 +- .../shared-components/immich-logo.svelte | 10 +- .../shared-components/loading-spinner.svelte | 6 +- .../shared-components/map/map.svelte | 216 ++++++++------- .../shared-components/modal-header.svelte | 29 +- .../navigation-bar/account-info-panel.svelte | 12 +- .../navigation-bar/avatar-selector.svelte | 12 +- .../navigation-bar/navigation-bar.svelte | 28 +- .../navigation-loading-bar.svelte | 2 +- .../notification-component-test.svelte | 6 +- .../notification/notification-card.svelte | 20 +- .../number-range-input.svelte | 33 ++- .../shared-components/password-field.svelte | 22 +- .../shared-components/portal/portal.svelte | 14 +- .../profile-image-cropper.svelte | 11 +- .../progress-bar/progress-bar.svelte | 50 ++-- .../purchase-activation-success.svelte | 6 +- .../purchasing/purchase-content.svelte | 16 +- .../purchasing/purchase-modal.svelte | 8 +- .../scrubber/scrubber.svelte | 82 +++--- .../search-bar/search-bar.svelte | 40 +-- .../search-bar/search-camera-section.svelte | 26 +- .../search-bar/search-date-section.svelte | 8 +- .../search-bar/search-display-section.svelte | 8 +- .../search-bar/search-filter-modal.svelte | 21 +- .../search-bar/search-history-box.svelte | 51 ++-- .../search-bar/search-location-section.svelte | 32 ++- .../search-bar/search-media-section.svelte | 6 +- .../search-bar/search-people-section.svelte | 14 +- .../search-bar/search-text-section.svelte | 8 +- .../server-about-modal.svelte | 10 +- .../settings/setting-accordion-state.svelte | 35 ++- .../settings/setting-accordion.svelte | 1 + .../settings/setting-buttons-row.svelte | 19 +- .../settings/setting-checkboxes.svelte | 28 +- .../settings/setting-combobox.svelte | 30 ++- .../settings/setting-dropdown.svelte | 27 +- .../settings/setting-input-field.svelte | 1 + .../settings/setting-select.svelte | 34 ++- .../settings/setting-switch.svelte | 31 ++- .../settings/setting-textarea.svelte | 1 + .../shared-components/show-shortcuts.svelte | 10 +- .../side-bar/more-information-albums.svelte | 6 +- .../side-bar/more-information-assets.svelte | 6 +- .../side-bar/purchase-info.svelte | 48 ++-- .../side-bar/server-status.svelte | 12 +- .../side-bar/side-bar-link.svelte | 45 +++- .../side-bar/side-bar-section.svelte | 7 +- .../side-bar/side-bar.svelte | 64 +++-- .../side-bar/storage-space.svelte | 20 +- .../side-bar/supporter-badge.svelte | 8 +- .../shared-components/single-grid-row.svelte | 27 +- .../shared-components/star-rating.svelte | 45 ++-- .../shared-components/theme-button.svelte | 12 +- .../shared-components/tree/breadcrumbs.svelte | 19 +- .../tree/tree-item-thumbnails.svelte | 12 +- .../shared-components/tree/tree-items.svelte | 23 +- .../shared-components/tree/tree.svelte | 43 ++- .../upload-asset-preview.svelte | 12 +- .../shared-components/upload-panel.svelte | 26 +- .../shared-components/user-avatar.svelte | 55 ++-- .../version-announcement-box.svelte | 43 +-- .../actions/shared-link-copy.svelte | 8 +- .../actions/shared-link-delete.svelte | 8 +- .../actions/shared-link-edit.svelte | 8 +- .../covers/asset-cover.svelte | 23 +- .../sharedlinks-page/covers/no-cover.svelte | 12 +- .../covers/share-cover.svelte | 12 +- .../sharedlinks-page/shared-link-card.svelte | 14 +- .../lib/components/slideshow-settings.svelte | 3 +- .../user-settings-page/app-settings.svelte | 38 +-- .../change-password-settings.svelte | 11 +- .../user-settings-page/device-card.svelte | 8 +- .../user-settings-page/device-list.svelte | 10 +- .../download-settings.svelte | 9 +- .../feature-settings.svelte | 21 +- .../notifications-settings.svelte | 11 +- .../user-settings-page/oauth-settings.svelte | 8 +- .../partner-selection-modal.svelte | 16 +- .../partner-settings.svelte | 10 +- .../user-api-key-list.svelte | 12 +- .../user-profile-settings.svelte | 7 +- .../user-purchase-settings.svelte | 4 +- .../user-settings-list.svelte | 8 +- .../duplicates/duplicate-asset.svelte | 25 +- .../duplicates-compare-control.svelte | 18 +- web/src/routes/(user)/+layout.svelte | 13 +- web/src/routes/(user)/albums/+page.svelte | 22 +- .../[[assetId=id]]/+page.svelte | 253 ++++++++++-------- .../[[assetId=id]]/+page.svelte | 12 +- web/src/routes/(user)/buy/+page.svelte | 8 +- web/src/routes/(user)/explore/+page.svelte | 73 ++--- .../[[assetId=id]]/+page.svelte | 12 +- .../[[assetId=id]]/+page.svelte | 48 ++-- .../[[assetId=id]]/+page.svelte | 22 +- .../[[assetId=id]]/+page.svelte | 18 +- web/src/routes/(user)/people/+page.svelte | 130 +++++---- .../[[assetId=id]]/+page.svelte | 110 ++++---- .../(user)/photos/[[assetId=id]]/+page.svelte | 18 +- web/src/routes/(user)/places/+page.svelte | 12 +- .../[[assetId=id]]/+page.svelte | 1 + .../[[assetId=id]]/+page.svelte | 36 ++- web/src/routes/(user)/sharing/+page.svelte | 40 +-- .../(user)/sharing/sharedlinks/+page.svelte | 8 +- .../[[assetId=id]]/+page.svelte | 113 ++++---- .../[[assetId=id]]/+page.svelte | 40 +-- .../routes/(user)/user-settings/+page.svelte | 24 +- web/src/routes/(user)/utilities/+page.svelte | 6 +- .../[[assetId=id]]/+page.svelte | 50 ++-- web/src/routes/+layout.svelte | 27 +- web/src/routes/admin/jobs-status/+page.svelte | 66 +++-- .../admin/library-management/+page.svelte | 52 ++-- web/src/routes/admin/repair/+page.svelte | 82 +++--- .../routes/admin/server-status/+page.svelte | 6 +- .../routes/admin/system-settings/+page.svelte | 110 ++++---- .../routes/admin/user-management/+page.svelte | 60 +++-- .../routes/auth/change-password/+page.svelte | 20 +- web/src/routes/auth/login/+page.svelte | 16 +- web/src/routes/auth/onboarding/+page.svelte | 13 +- web/src/routes/auth/register/+page.svelte | 14 +- 303 files changed, 5873 insertions(+), 3343 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index a24de1cd75832..a8f3262492d7a 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -36,7 +36,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", @@ -53,7 +53,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", @@ -68,7 +68,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" } }, diff --git a/web/package.json b/web/package.json index b67f1cf4713e9..e14f3780a1713 100644 --- a/web/package.json +++ b/web/package.json @@ -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", @@ -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", @@ -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", diff --git a/web/src/lib/actions/__test__/focus-trap-test.svelte b/web/src/lib/actions/__test__/focus-trap-test.svelte index 207c880cd9d8f..e1cb6fa4fba79 100644 --- a/web/src/lib/actions/__test__/focus-trap-test.svelte +++ b/web/src/lib/actions/__test__/focus-trap-test.svelte @@ -1,16 +1,20 @@ - + {#if show}
text - +
diff --git a/web/src/lib/components/admin-page/delete-confirm-dialogue.svelte b/web/src/lib/components/admin-page/delete-confirm-dialogue.svelte index a2fbbe787a1e9..c81c18f230e3c 100644 --- a/web/src/lib/components/admin-page/delete-confirm-dialogue.svelte +++ b/web/src/lib/components/admin-page/delete-confirm-dialogue.svelte @@ -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 () => { @@ -47,12 +51,14 @@ {onCancel} disabled={deleteButtonDisabled} > - + {#snippet prompt()}
{#if forceDelete}

- - {message} + + {#snippet children({ message })} + {message} + {/snippet}

{:else} @@ -60,9 +66,10 @@ - {message} + {#snippet children({ message })} + {message} + {/snippet}

{/if} @@ -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; }} /> @@ -92,9 +99,9 @@ aria-describedby="confirm-user-desc" name="confirm-user-id" type="text" - on:input={handleConfirm} + oninput={handleConfirm} /> {/if}
-
+ {/snippet} diff --git a/web/src/lib/components/admin-page/jobs/job-tile-button.svelte b/web/src/lib/components/admin-page/jobs/job-tile-button.svelte index 69d3706230de9..7f270428defdf 100644 --- a/web/src/lib/components/admin-page/jobs/job-tile-button.svelte +++ b/web/src/lib/components/admin-page/jobs/job-tile-button.svelte @@ -1,10 +1,16 @@ -
- + {@render children?.()}
diff --git a/web/src/lib/components/admin-page/jobs/job-tile.svelte b/web/src/lib/components/admin-page/jobs/job-tile.svelte index 81c23e927b684..f734ba4af3580 100644 --- a/web/src/lib/components/admin-page/jobs/job-tile.svelte +++ b/web/src/lib/components/admin-page/jobs/job-tile.svelte @@ -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'; @@ -87,8 +102,9 @@ {/if} {#if description} + {@const SvelteComponent = description}
- +
{/if} @@ -118,7 +134,7 @@ onCommand({ command: JobCommand.Start, force: false })} + onClick={() => onCommand({ command: JobCommand.Start, force: false })} > {$t('disabled').toUpperCase()} @@ -127,20 +143,20 @@ {#if !disabled && !isIdle} {#if waitingCount > 0} - onCommand({ command: JobCommand.Empty, force: false })}> + onCommand({ command: JobCommand.Empty, force: false })}> {$t('clear').toUpperCase()} {/if} {#if queueStatus.isPaused} {@const size = waitingCount > 0 ? '24' : '48'} - onCommand({ command: JobCommand.Resume, force: false })}> + onCommand({ command: JobCommand.Resume, force: false })}> {$t('resume').toUpperCase()} {:else} - onCommand({ command: JobCommand.Pause, force: false })}> + onCommand({ command: JobCommand.Pause, force: false })}> {$t('pause').toUpperCase()} @@ -149,25 +165,25 @@ {#if !disabled && multipleButtons && isIdle} {#if allText} - onCommand({ command: JobCommand.Start, force: true })}> + onCommand({ command: JobCommand.Start, force: true })}> {allText} {/if} {#if refreshText} - onCommand({ command: JobCommand.Start, force: undefined })}> + onCommand({ command: JobCommand.Start, force: undefined })}> {refreshText} {/if} - onCommand({ command: JobCommand.Start, force: false })}> + onCommand({ command: JobCommand.Start, force: false })}> {missingText} {/if} {#if !disabled && !multipleButtons && isIdle} - onCommand({ command: JobCommand.Start, force: false })}> + onCommand({ command: JobCommand.Start, force: false })}> {$t('start').toUpperCase()} diff --git a/web/src/lib/components/admin-page/jobs/jobs-panel.svelte b/web/src/lib/components/admin-page/jobs/jobs-panel.svelte index 67d672d398806..be5a41829f31f 100644 --- a/web/src/lib/components/admin-page/jobs/jobs-panel.svelte +++ b/web/src/lib/components/admin-page/jobs/jobs-panel.svelte @@ -1,3 +1,4 @@ +
diff --git a/web/src/lib/components/admin-page/server-stats/stats-card.svelte b/web/src/lib/components/admin-page/server-stats/stats-card.svelte index 31baa0afdd780..3ea14026f895e 100644 --- a/web/src/lib/components/admin-page/server-stats/stats-card.svelte +++ b/web/src/lib/components/admin-page/server-stats/stats-card.svelte @@ -2,18 +2,27 @@ import Icon from '$lib/components/elements/icon.svelte'; import { ByteUnit } from '$lib/utils/byte-units'; - export let icon: string; - export let title: string; - export let value: number; - export let unit: ByteUnit | undefined = undefined; + interface Props { + icon: string; + title: string; + value: number; + unit?: ByteUnit | undefined; + } - $: zeros = () => { + let { + icon, + title, + value, + unit = undefined + }: Props = $props(); + + let zeros = $derived(() => { const maxLength = 13; const valueLength = value.toString().length; const zeroLength = maxLength - valueLength; return '0'.repeat(zeroLength); - }; + });
diff --git a/web/src/lib/components/admin-page/settings/admin-settings.svelte b/web/src/lib/components/admin-page/settings/admin-settings.svelte index 19a8580d6bb90..1fda33a2d6d55 100644 --- a/web/src/lib/components/admin-page/settings/admin-settings.svelte +++ b/web/src/lib/components/admin-page/settings/admin-settings.svelte @@ -1,4 +1,4 @@ - + {#if savedConfig && defaultConfig} - + {@render children?.({ handleReset, handleSave, savedConfig, defaultConfig, })} {/if} diff --git a/web/src/lib/components/admin-page/settings/auth/auth-settings.svelte b/web/src/lib/components/admin-page/settings/auth/auth-settings.svelte index 9b0e4b32706b5..661fa19972873 100644 --- a/web/src/lib/components/admin-page/settings/auth/auth-settings.svelte +++ b/web/src/lib/components/admin-page/settings/auth/auth-settings.svelte @@ -1,4 +1,7 @@
-
+
- -

- - - {message} -
-
-
-

-
+ {#snippet desc()} + +

+ + {#snippet children({ message })} + + {message} +
+
+ {/snippet} +
+

+ + {/snippet} + import { createBubbler, preventDefault } from 'svelte/legacy'; + + const bubble = createBubbler(); import Icon from '$lib/components/elements/icon.svelte'; import { AudioCodec, @@ -25,35 +28,48 @@ import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; - export let savedConfig: SystemConfigDto; - export let defaultConfig: SystemConfigDto; - export let config: SystemConfigDto; // this is the config that is being edited - export let disabled = false; - export let onReset: SettingsResetEvent; - export let onSave: SettingsSaveEvent; + interface Props { + savedConfig: SystemConfigDto; + defaultConfig: SystemConfigDto; + config: SystemConfigDto; + disabled?: boolean; + onReset: SettingsResetEvent; + onSave: SettingsSaveEvent; + } + + let { + savedConfig, + defaultConfig, + config = $bindable(), + disabled = false, + onReset, + onSave + }: Props = $props();
- +

- - {#if tag === 'h264-link'} - - {message} - - {:else if tag === 'hevc-link'} - - {message} - - {:else if tag === 'vp9-link'} - - {message} - - {/if} - + + {#snippet children({ tag, message })} + {#if tag === 'h264-link'} + + {message} + + {:else if tag === 'hevc-link'} + + {message} + + {:else if tag === 'vp9-link'} + + {message} + + {/if} + {/snippet} +

+ import { createBubbler, preventDefault } from 'svelte/legacy'; + + const bubble = createBubbler(); import { Colorspace, ImageFormat, type SystemConfigDto } from '@immich/sdk'; import { isEqual } from 'lodash-es'; import { fade } from 'svelte/transition'; @@ -13,18 +16,30 @@ import { t } from 'svelte-i18n'; import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte'; - export let savedConfig: SystemConfigDto; - export let defaultConfig: SystemConfigDto; - export let config: SystemConfigDto; // this is the config that is being edited - export let disabled = false; - export let onReset: SettingsResetEvent; - export let onSave: SettingsSaveEvent; - export let openByDefault = false; + interface Props { + savedConfig: SystemConfigDto; + defaultConfig: SystemConfigDto; + config: SystemConfigDto; + disabled?: boolean; + onReset: SettingsResetEvent; + onSave: SettingsSaveEvent; + openByDefault?: boolean; + } + + let { + savedConfig, + defaultConfig, + config = $bindable(), + disabled = false, + onReset, + onSave, + openByDefault = false + }: Props = $props();
- +
+ import { createBubbler, preventDefault } from 'svelte/legacy'; + + const bubble = createBubbler(); import { getJobName } from '$lib/utils'; import { JobName, type SystemConfigDto, type SystemConfigJobDto } from '@immich/sdk'; import { isEqual } from 'lodash-es'; @@ -10,12 +13,23 @@ } from '$lib/components/shared-components/settings/setting-input-field.svelte'; import { t } from 'svelte-i18n'; - export let savedConfig: SystemConfigDto; - export let defaultConfig: SystemConfigDto; - export let config: SystemConfigDto; // this is the config that is being edited - export let disabled = false; - export let onReset: SettingsResetEvent; - export let onSave: SettingsSaveEvent; + interface Props { + savedConfig: SystemConfigDto; + defaultConfig: SystemConfigDto; + config: SystemConfigDto; + disabled?: boolean; + onReset: SettingsResetEvent; + onSave: SettingsSaveEvent; + } + + let { + savedConfig, + defaultConfig, + config = $bindable(), + disabled = false, + onReset, + onSave + }: Props = $props(); const jobNames = [ JobName.ThumbnailGeneration, @@ -38,7 +52,7 @@
- + {#each jobNames as jobName}
{#if isSystemConfigJobDto(jobName)} diff --git a/web/src/lib/components/admin-page/settings/library-settings/library-settings.svelte b/web/src/lib/components/admin-page/settings/library-settings/library-settings.svelte index b494dca53ffd5..2f04328421f74 100644 --- a/web/src/lib/components/admin-page/settings/library-settings/library-settings.svelte +++ b/web/src/lib/components/admin-page/settings/library-settings/library-settings.svelte @@ -1,4 +1,7 @@
- +
- -

- - - {message} - - -

-
+ {#snippet desc()} + +

+ + {#snippet children({ message })} + + {message} + + {/snippet} + +

+ + {/snippet}
diff --git a/web/src/lib/components/admin-page/settings/logging-settings/logging-settings.svelte b/web/src/lib/components/admin-page/settings/logging-settings/logging-settings.svelte index 6e71ba926c79f..cd61c22689f73 100644 --- a/web/src/lib/components/admin-page/settings/logging-settings/logging-settings.svelte +++ b/web/src/lib/components/admin-page/settings/logging-settings/logging-settings.svelte @@ -1,4 +1,7 @@
- +
+ import { createBubbler, preventDefault } from 'svelte/legacy'; + + const bubble = createBubbler(); import type { SystemConfigDto } from '@immich/sdk'; import { isEqual } from 'lodash-es'; import { fade } from 'svelte/transition'; @@ -14,17 +17,28 @@ import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; - export let savedConfig: SystemConfigDto; - export let defaultConfig: SystemConfigDto; - export let config: SystemConfigDto; // this is the config that is being edited - export let disabled = false; - export let onReset: SettingsResetEvent; - export let onSave: SettingsSaveEvent; + interface Props { + savedConfig: SystemConfigDto; + defaultConfig: SystemConfigDto; + config: SystemConfigDto; + disabled?: boolean; + onReset: SettingsResetEvent; + onSave: SettingsSaveEvent; + } + + let { + savedConfig, + defaultConfig, + config = $bindable(), + disabled = false, + onReset, + onSave + }: Props = $props();
- +
-

- - {message} - -

+ {#snippet desc()} +

+ + {#snippet children({ message })} + {message} + {/snippet} + +

+ {/snippet}
diff --git a/web/src/lib/components/admin-page/settings/map-settings/map-settings.svelte b/web/src/lib/components/admin-page/settings/map-settings/map-settings.svelte index 7c2c5c856aedc..6f801e66b1629 100644 --- a/web/src/lib/components/admin-page/settings/map-settings/map-settings.svelte +++ b/web/src/lib/components/admin-page/settings/map-settings/map-settings.svelte @@ -1,4 +1,7 @@
- +
@@ -55,20 +69,24 @@ > - -

- - - {message} - - -

-
+ {#snippet subtitle()} + +

+ + {#snippet children({ message })} + + {message} + + {/snippet} + +

+ + {/snippet}
+ import { createBubbler, preventDefault } from 'svelte/legacy'; + + const bubble = createBubbler(); import type { SystemConfigDto } from '@immich/sdk'; import { isEqual } from 'lodash-es'; import { fade } from 'svelte/transition'; @@ -7,17 +10,28 @@ import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte'; import { t } from 'svelte-i18n'; - export let savedConfig: SystemConfigDto; - export let defaultConfig: SystemConfigDto; - export let config: SystemConfigDto; // this is the config that is being edited - export let disabled = false; - export let onReset: SettingsResetEvent; - export let onSave: SettingsSaveEvent; + interface Props { + savedConfig: SystemConfigDto; + defaultConfig: SystemConfigDto; + config: SystemConfigDto; + disabled?: boolean; + onReset: SettingsResetEvent; + onSave: SettingsSaveEvent; + } + + let { + savedConfig, + defaultConfig, + config = $bindable(), + disabled = false, + onReset, + onSave + }: Props = $props();
- +
+ import { createBubbler, preventDefault } from 'svelte/legacy'; + + const bubble = createBubbler(); import type { SystemConfigDto } from '@immich/sdk'; import { isEqual } from 'lodash-es'; import { fade } from 'svelte/transition'; @@ -7,17 +10,28 @@ import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte'; import { t } from 'svelte-i18n'; - export let savedConfig: SystemConfigDto; - export let defaultConfig: SystemConfigDto; - export let config: SystemConfigDto; // this is the config that is being edited - export let disabled = false; - export let onReset: SettingsResetEvent; - export let onSave: SettingsSaveEvent; + interface Props { + savedConfig: SystemConfigDto; + defaultConfig: SystemConfigDto; + config: SystemConfigDto; + disabled?: boolean; + onReset: SettingsResetEvent; + onSave: SettingsSaveEvent; + } + + let { + savedConfig, + defaultConfig, + config = $bindable(), + disabled = false, + onReset, + onSave + }: Props = $props();
- +
+ import { createBubbler, preventDefault } from 'svelte/legacy'; + + const bubble = createBubbler(); import { sendTestEmail, type SystemConfigDto } from '@immich/sdk'; import { isEqual } from 'lodash-es'; import { fade } from 'svelte/transition'; @@ -19,14 +22,25 @@ import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte'; import { handleError } from '$lib/utils/handle-error'; - export let savedConfig: SystemConfigDto; - export let defaultConfig: SystemConfigDto; - export let config: SystemConfigDto; // this is the config that is being edited - export let disabled = false; - export let onReset: SettingsResetEvent; - export let onSave: SettingsSaveEvent; - - let isSending = false; + interface Props { + savedConfig: SystemConfigDto; + defaultConfig: SystemConfigDto; + config: SystemConfigDto; + disabled?: boolean; + onReset: SettingsResetEvent; + onSave: SettingsSaveEvent; + } + + let { + savedConfig, + defaultConfig, + config = $bindable(), + disabled = false, + onReset, + onSave + }: Props = $props(); + + let isSending = $state(false); const handleSendTestEmail = async () => { if (isSending) { @@ -69,7 +83,7 @@
- +
diff --git a/web/src/lib/components/admin-page/settings/server/server-settings.svelte b/web/src/lib/components/admin-page/settings/server/server-settings.svelte index f021c99f24a1c..38d5515d1b9cf 100644 --- a/web/src/lib/components/admin-page/settings/server/server-settings.svelte +++ b/web/src/lib/components/admin-page/settings/server/server-settings.svelte @@ -1,4 +1,7 @@
- +
+ import { createBubbler, preventDefault } from 'svelte/legacy'; + + const bubble = createBubbler(); import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte'; import { AppRoute } from '$lib/constants'; import { user } from '$lib/stores/user.store'; @@ -22,17 +25,32 @@ import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; - export let savedConfig: SystemConfigDto; - export let defaultConfig: SystemConfigDto; - export let config: SystemConfigDto; // this is the config that is being edited - export let disabled = false; - export let minified = false; - export let onReset: SettingsResetEvent; - export let onSave: SettingsSaveEvent; - export let duration: number = 500; + interface Props { + savedConfig: SystemConfigDto; + defaultConfig: SystemConfigDto; + config: SystemConfigDto; + disabled?: boolean; + minified?: boolean; + onReset: SettingsResetEvent; + onSave: SettingsSaveEvent; + duration?: number; + children?: import('svelte').Snippet; + } + + let { + savedConfig, + defaultConfig, + config = $bindable(), + disabled = false, + minified = false, + onReset, + onSave, + duration = 500, + children + }: Props = $props(); - let templateOptions: SystemConfigTemplateStorageOptionDto; - let selectedPreset = ''; + let templateOptions: SystemConfigTemplateStorageOptionDto = $state(); + let selectedPreset = $state(''); const getTemplateOptions = async () => { templateOptions = await getStorageTemplateOptions(); @@ -41,13 +59,6 @@ const getSupportDateTimeFormat = () => getStorageTemplateOptions(); - $: parsedTemplate = () => { - try { - return renderTemplate(config.storageTemplate.template); - } catch { - return 'error'; - } - }; const renderTemplate = (templateString: string) => { const template = handlebar.compile(templateString, { @@ -85,32 +96,41 @@ const handlePresetSelection = () => { config.storageTemplate.template = selectedPreset; }; + let parsedTemplate = $derived(() => { + try { + return renderTemplate(config.storageTemplate.template); + } catch { + return 'error'; + } + });

- - {#if tag === 'template-link'} - - {message} - - {:else if tag === 'implications-link'} - - {message} - - {/if} - + + {#snippet children({ tag, message })} + {#if tag === 'template-link'} + + {message} + + {:else if tag === 'implications-link'} + + {message} + + {/if} + {/snippet} +

{#await getTemplateOptions() then} @@ -164,20 +184,24 @@ - {message} - + {#snippet children({ message })} + {message} + {/snippet} +

- {message} - + {#snippet children({ message })} + {message} + {/snippet} +

@@ -186,7 +210,7 @@ >/{parsedTemplate()}.jpg

- +
@@ -247,7 +273,7 @@ {/if} {#if minified} - + {@render children?.()} {:else} onReset({ ...options, configKeys: ['storageTemplate'] })} diff --git a/web/src/lib/components/admin-page/settings/storage-template/supported-datetime-panel.svelte b/web/src/lib/components/admin-page/settings/storage-template/supported-datetime-panel.svelte index 10f22c18057f3..379e366df60f1 100644 --- a/web/src/lib/components/admin-page/settings/storage-template/supported-datetime-panel.svelte +++ b/web/src/lib/components/admin-page/settings/storage-template/supported-datetime-panel.svelte @@ -4,7 +4,11 @@ import { DateTime } from 'luxon'; import { t } from 'svelte-i18n'; - export let options: SystemConfigTemplateStorageOptionDto; + interface Props { + options: SystemConfigTemplateStorageOptionDto; + } + + let { options }: Props = $props(); const getLuxonExample = (format: string) => { return DateTime.fromISO('2022-09-04T20:03:05.250Z', { locale: $locale }).toFormat(format); diff --git a/web/src/lib/components/admin-page/settings/theme/theme-settings.svelte b/web/src/lib/components/admin-page/settings/theme/theme-settings.svelte index 84a12e05c9674..96dae6a5848c7 100644 --- a/web/src/lib/components/admin-page/settings/theme/theme-settings.svelte +++ b/web/src/lib/components/admin-page/settings/theme/theme-settings.svelte @@ -1,4 +1,7 @@
- +
+ import { createBubbler, preventDefault } from 'svelte/legacy'; + + const bubble = createBubbler(); import type { SystemConfigDto } from '@immich/sdk'; import { isEqual } from 'lodash-es'; import { fade } from 'svelte/transition'; @@ -10,17 +13,28 @@ import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte'; import { t } from 'svelte-i18n'; - export let savedConfig: SystemConfigDto; - export let defaultConfig: SystemConfigDto; - export let config: SystemConfigDto; // this is the config that is being edited - export let disabled = false; - export let onReset: SettingsResetEvent; - export let onSave: SettingsSaveEvent; + interface Props { + savedConfig: SystemConfigDto; + defaultConfig: SystemConfigDto; + config: SystemConfigDto; + disabled?: boolean; + onReset: SettingsResetEvent; + onSave: SettingsSaveEvent; + } + + let { + savedConfig, + defaultConfig, + config = $bindable(), + disabled = false, + onReset, + onSave + }: Props = $props();
- +
diff --git a/web/src/lib/components/admin-page/settings/user-settings/user-settings.svelte b/web/src/lib/components/admin-page/settings/user-settings/user-settings.svelte index 21453cbc7023c..4bbdd7546582b 100644 --- a/web/src/lib/components/admin-page/settings/user-settings/user-settings.svelte +++ b/web/src/lib/components/admin-page/settings/user-settings/user-settings.svelte @@ -1,4 +1,7 @@
- +
+ import { preventDefault } from 'svelte/legacy'; + import { flip } from 'svelte/animate'; import { slide } from 'svelte/transition'; import { AppRoute } from '$lib/constants'; @@ -11,28 +13,38 @@ import Icon from '$lib/components/elements/icon.svelte'; import { t } from 'svelte-i18n'; - export let albums: AlbumResponseDto[]; - export let group: AlbumGroup | undefined = undefined; - export let showOwner = false; - export let showDateRange = false; - export let showItemCount = false; - export let onShowContextMenu: ((position: ContextMenuPosition, album: AlbumResponseDto) => unknown) | undefined = - undefined; + interface Props { + albums: AlbumResponseDto[]; + group?: AlbumGroup | undefined; + showOwner?: boolean; + showDateRange?: boolean; + showItemCount?: boolean; + onShowContextMenu?: ((position: ContextMenuPosition, album: AlbumResponseDto) => unknown) | undefined; + } + + let { + albums, + group = undefined, + showOwner = false, + showDateRange = false, + showItemCount = false, + onShowContextMenu = undefined + }: Props = $props(); - $: isCollapsed = !!group && isAlbumGroupCollapsed($albumViewSettings, group.id); + let isCollapsed = $derived(!!group && isAlbumGroupCollapsed($albumViewSettings, group.id)); const showContextMenu = (position: ContextMenuPosition, album: AlbumResponseDto) => { onShowContextMenu?.(position, album); }; - $: iconRotation = isCollapsed ? 'rotate-0' : 'rotate-90'; + let iconRotation = $derived(isCollapsed ? 'rotate-0' : 'rotate-90'); {#if group}