goto(Route.sharing())}>
{#snippet leading()}
{data.partner.name}'s photos
diff --git a/web/src/routes/(user)/people/[personId]/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/people/[personId]/[[photos=photos]]/[[assetId=id]]/+page.svelte
index 48f559ffe6..98c3796f05 100644
--- a/web/src/routes/(user)/people/[personId]/[[photos=photos]]/[[assetId=id]]/+page.svelte
+++ b/web/src/routes/(user)/people/[personId]/[[photos=photos]]/[[assetId=id]]/+page.svelte
@@ -31,6 +31,7 @@
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
import PersonMergeSuggestionModal from '$lib/modals/PersonMergeSuggestionModal.svelte';
+ import { Route } from '$lib/route';
import { getPersonActions } from '$lib/services/person.service';
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
@@ -73,7 +74,7 @@
let viewMode: PersonPageViewMode = $state(PersonPageViewMode.VIEW_ASSETS);
let isEditingName = $state(false);
- let previousRoute: string = $state(AppRoute.EXPLORE);
+ let previousRoute = $state(Route.explore());
let personMerge1: PersonResponseDto | undefined = $state();
let personMerge2: PersonResponseDto | undefined = $state();
let potentialMergePeople: PersonResponseDto[] = $state([]);
diff --git a/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte
index de14774ff1..640b487167 100644
--- a/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte
+++ b/web/src/routes/(user)/photos/[[assetId=id]]/+page.svelte
@@ -20,8 +20,9 @@
import TagAction from '$lib/components/timeline/actions/TagAction.svelte';
import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte';
import Timeline from '$lib/components/timeline/Timeline.svelte';
- import { AppRoute, AssetAction, QueryParameter } from '$lib/constants';
+ import { AssetAction } from '$lib/constants';
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
+ import { Route } from '$lib/route';
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { isFaceEditMode } from '$lib/stores/face-edit.svelte';
@@ -95,7 +96,7 @@
memoryStore.memories.map((memory) => ({
id: memory.id,
title: $memoryLaneTitle(memory),
- href: `${AppRoute.MEMORY}?${QueryParameter.ID}=${memory.assets[0].id}`,
+ href: Route.memories({ id: memory.assets[0].id }),
alt: $t('memory_lane_title', { values: { title: $getAltText(toTimelineAsset(memory.assets[0])) } }),
src: getAssetThumbnailUrl(memory.assets[0].id),
})),
diff --git a/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte b/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte
index 3a91858b85..3c81231efd 100644
--- a/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte
+++ b/web/src/routes/(user)/search/[[photos=photos]]/[[assetId=id]]/+page.svelte
@@ -20,9 +20,10 @@
import SetVisibilityAction from '$lib/components/timeline/actions/SetVisibilityAction.svelte';
import TagAction from '$lib/components/timeline/actions/TagAction.svelte';
import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte';
- import { AppRoute, QueryParameter } from '$lib/constants';
+ import { QueryParameter } from '$lib/constants';
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
import type { Viewport } from '$lib/managers/timeline-manager/types';
+ import { Route } from '$lib/route';
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { lang, locale } from '$lib/stores/preferences.store';
@@ -55,7 +56,7 @@
// The GalleryViewer pushes it's own history state, which causes weird
// behavior for history.back(). To prevent that we store the previous page
// manually and navigate back to that.
- let previousRoute = $state(AppRoute.EXPLORE as string);
+ let previousRoute = $state(Route.explore());
let nextPage = $state(1);
let searchResultAlbums: AlbumResponseDto[] = $state([]);
@@ -108,11 +109,11 @@
const route = from?.route?.id;
if (isPeopleRoute(route)) {
- previousRoute = AppRoute.PHOTOS;
+ previousRoute = Route.photos();
}
if (isAlbumsRoute(route)) {
- previousRoute = AppRoute.EXPLORE;
+ previousRoute = Route.explore();
}
tick()
diff --git a/web/src/routes/(user)/shared-links/(list)/+layout.svelte b/web/src/routes/(user)/shared-links/(list)/+layout.svelte
index ce14870923..881a098255 100644
--- a/web/src/routes/(user)/shared-links/(list)/+layout.svelte
+++ b/web/src/routes/(user)/shared-links/(list)/+layout.svelte
@@ -4,8 +4,9 @@
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
import OnEvents from '$lib/components/OnEvents.svelte';
import SharedLinkCard from '$lib/components/sharedlinks-page/SharedLinkCard.svelte';
- import { AppRoute } from '$lib/constants';
+ import { type SharedLinkTab } from '$lib/constants';
import GroupTab from '$lib/elements/GroupTab.svelte';
+ import { Route } from '$lib/route';
import { getAllSharedLinks, SharedLinkType, type SharedLinkResponseDto } from '@immich/sdk';
import { Container } from '@immich/ui';
import { onMount, type Snippet } from 'svelte';
@@ -29,9 +30,7 @@
await refresh();
});
- type Filter = 'all' | 'album' | 'individual';
-
- const filterMap: Record = {
+ const filterMap: Record = {
all: $t('all'),
album: $t('albums'),
individual: $t('individual_shares'),
@@ -46,9 +45,6 @@
};
let selectedTab = $derived(getActiveTab(page.url));
- const handleSelectTab = async (value: string) => {
- await goto(`${AppRoute.SHARED_LINKS}?filter=${value}`);
- };
let filteredSharedLinks = $derived(
sharedLinks.filter(
@@ -76,7 +72,13 @@
{#snippet buttons()}
-
+ goto(Route.sharedLinks({ filter: value as SharedLinkTab }))}
+ />
{/snippet}
diff --git a/web/src/routes/(user)/shared-links/(list)/[id]/+layout.ts b/web/src/routes/(user)/shared-links/(list)/[id]/+layout.ts
index df1209e0c4..71bc626e58 100644
--- a/web/src/routes/(user)/shared-links/(list)/[id]/+layout.ts
+++ b/web/src/routes/(user)/shared-links/(list)/[id]/+layout.ts
@@ -1,4 +1,5 @@
-import { AppRoute, UUID_REGEX } from '$lib/constants';
+import { UUID_REGEX } from '$lib/constants';
+import { Route } from '$lib/route';
import { authenticate } from '$lib/utils/auth';
import { getFormatter } from '$lib/utils/i18n';
import { getAllSharedLinks } from '@immich/sdk';
@@ -9,12 +10,12 @@ export const load = (async ({ params, url }) => {
await authenticate(url);
if (!UUID_REGEX.test(params.id)) {
- redirect(307, AppRoute.SHARED_LINKS);
+ redirect(307, Route.sharedLinks());
}
const [sharedLink] = await getAllSharedLinks({ id: params.id });
if (!sharedLink) {
- redirect(307, AppRoute.SHARED_LINKS);
+ redirect(307, Route.sharedLinks());
}
const $t = await getFormatter();
diff --git a/web/src/routes/(user)/shared-links/(list)/[id]/edit/+page.svelte b/web/src/routes/(user)/shared-links/(list)/[id]/edit/+page.svelte
index 6fef129583..5760932bfb 100644
--- a/web/src/routes/(user)/shared-links/(list)/[id]/edit/+page.svelte
+++ b/web/src/routes/(user)/shared-links/(list)/[id]/edit/+page.svelte
@@ -1,7 +1,7 @@
{
- const photoId = params.photoId;
- return redirect(307, `${AppRoute.PHOTOS}/${photoId}`);
-}) satisfies PageLoad;
+export const load = (({ params }) => redirect(307, Route.viewAsset({ id: params.photoId }))) satisfies PageLoad;
diff --git a/web/src/routes/(user)/utilities/workflows/[workflowId]/+page.svelte b/web/src/routes/(user)/utilities/workflows/[workflowId]/+page.svelte
index a050598a90..88af032b03 100644
--- a/web/src/routes/(user)/utilities/workflows/[workflowId]/+page.svelte
+++ b/web/src/routes/(user)/utilities/workflows/[workflowId]/+page.svelte
@@ -7,8 +7,8 @@
import WorkflowJsonEditor from '$lib/components/workflows/WorkflowJsonEditor.svelte';
import WorkflowSummarySidebar from '$lib/components/workflows/WorkflowSummary.svelte';
import WorkflowTriggerCard from '$lib/components/workflows/WorkflowTriggerCard.svelte';
- import { AppRoute } from '$lib/constants';
import AddWorkflowStepModal from '$lib/modals/AddWorkflowStepModal.svelte';
+ import { Route } from '$lib/route';
import {
buildWorkflowPayload,
getActionsByContext,
@@ -580,7 +580,7 @@
- goto(AppRoute.WORKFLOWS)} backIcon={mdiArrowLeft} tailwindClasses="fixed! top-0! w-full">
+ goto(Route.workflows())} backIcon={mdiArrowLeft} tailwindClasses="fixed! top-0! w-full">
{#snippet leading()}
{data.meta.title}
{/snippet}
diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte
index 286573ef78..046b98da98 100644
--- a/web/src/routes/+layout.svelte
+++ b/web/src/routes/+layout.svelte
@@ -14,6 +14,7 @@
import { themeManager } from '$lib/managers/theme-manager.svelte';
import ServerRestartingModal from '$lib/modals/ServerRestartingModal.svelte';
import VersionAnnouncementModal from '$lib/modals/VersionAnnouncementModal.svelte';
+ import { Route } from '$lib/route';
import { sidebarStore } from '$lib/stores/sidebar.svelte';
import { user } from '$lib/stores/user.store';
import { closeWebsocketConnection, openWebsocketConnection, websocketStore } from '$lib/stores/websocket';
@@ -155,32 +156,32 @@
title: $t('users'),
description: $t('admin.users_page_description'),
icon: mdiAccountMultipleOutline,
- onAction: () => goto(AppRoute.ADMIN_USERS),
+ onAction: () => goto(Route.users()),
},
{
title: $t('settings'),
description: $t('admin.settings_page_description'),
icon: mdiCog,
- onAction: () => goto(AppRoute.ADMIN_SETTINGS),
+ onAction: () => goto(Route.systemSettings()),
},
{
title: $t('admin.queues'),
description: $t('admin.queues_page_description'),
icon: mdiSync,
type: $t('page'),
- onAction: () => goto(AppRoute.ADMIN_QUEUES),
+ onAction: () => goto(Route.queues()),
},
{
title: $t('external_libraries'),
description: $t('admin.external_libraries_page_description'),
icon: mdiBookshelf,
- onAction: () => goto(AppRoute.ADMIN_LIBRARIES),
+ onAction: () => goto(Route.libraries()),
},
{
title: $t('server_stats'),
description: $t('admin.server_stats_page_description'),
icon: mdiServer,
- onAction: () => goto(AppRoute.ADMIN_STATS),
+ onAction: () => goto(Route.systemStatistics()),
},
].map((route) => ({ ...route, type: $t('page'), $if: () => $user?.isAdmin }));
diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte
index a414702cfd..47d39d45f1 100644
--- a/web/src/routes/+page.svelte
+++ b/web/src/routes/+page.svelte
@@ -1,6 +1,6 @@
@@ -9,7 +9,7 @@
{$t('welcome_to_immich')}
-
+
{$t('getting_started')}
diff --git a/web/src/routes/+page.ts b/web/src/routes/+page.ts
index 058a49982a..4dde14a40d 100644
--- a/web/src/routes/+page.ts
+++ b/web/src/routes/+page.ts
@@ -1,5 +1,6 @@
import { AppRoute } from '$lib/constants';
import { serverConfigManager } from '$lib/managers/server-config-manager.svelte';
+import { Route } from '$lib/route';
import { getFormatter } from '$lib/utils/i18n';
import { init } from '$lib/utils/server';
import { redirect } from '@sveltejs/kit';
@@ -19,12 +20,12 @@ export const load = (async ({ fetch }) => {
const authenticated = await loadUser();
if (authenticated) {
- redirect(307, AppRoute.PHOTOS);
+ redirect(307, Route.photos());
}
if (serverConfigManager.value.isInitialized) {
// Redirect to login page if there exists an admin account (i.e. server is initialized)
- redirect(307, AppRoute.AUTH_LOGIN);
+ redirect(307, Route.login());
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
diff --git a/web/src/routes/admin/+page.ts b/web/src/routes/admin/+page.ts
index 28dac3389e..76a831b77e 100644
--- a/web/src/routes/admin/+page.ts
+++ b/web/src/routes/admin/+page.ts
@@ -1,7 +1,5 @@
-import { AppRoute } from '$lib/constants';
+import { Route } from '$lib/route';
import { redirect } from '@sveltejs/kit';
import type { PageLoad } from './$types';
-export const load = (() => {
- redirect(307, AppRoute.ADMIN_SETTINGS);
-}) satisfies PageLoad;
+export const load = (() => redirect(307, Route.systemSettings())) satisfies PageLoad;
diff --git a/web/src/routes/admin/jobs-status/+page.ts b/web/src/routes/admin/jobs-status/+page.ts
index 92971ccd9a..d7eb35ad53 100644
--- a/web/src/routes/admin/jobs-status/+page.ts
+++ b/web/src/routes/admin/jobs-status/+page.ts
@@ -1,5 +1,5 @@
-import { AppRoute } from '$lib/constants';
+import { Route } from '$lib/route';
import { redirect } from '@sveltejs/kit';
import type { PageLoad } from './$types';
-export const load = (() => redirect(307, AppRoute.ADMIN_QUEUES)) satisfies PageLoad;
+export const load = (() => redirect(307, Route.queues())) satisfies PageLoad;
diff --git a/web/src/routes/admin/library-management/(list)/+layout.svelte b/web/src/routes/admin/library-management/(list)/+layout.svelte
index fe6114fbc1..17a91b2a13 100644
--- a/web/src/routes/admin/library-management/(list)/+layout.svelte
+++ b/web/src/routes/admin/library-management/(list)/+layout.svelte
@@ -3,8 +3,8 @@
import AdminPageLayout from '$lib/components/layouts/AdminPageLayout.svelte';
import OnEvents from '$lib/components/OnEvents.svelte';
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
- import { AppRoute } from '$lib/constants';
- import { getLibrariesActions, handleViewLibrary } from '$lib/services/library.service';
+ import { Route } from '$lib/route';
+ import { getLibrariesActions } from '$lib/services/library.service';
import { locale } from '$lib/stores/preferences.store';
import { getBytesWithUnit } from '$lib/utils/byte-units';
import { getLibrary, getLibraryStatistics, type LibraryResponseDto } from '@immich/sdk';
@@ -36,7 +36,7 @@
let owners = $state(data.owners);
const onLibraryCreate = async (library: LibraryResponseDto) => {
- await goto(`${AppRoute.ADMIN_LIBRARIES}/${library.id}`);
+ await goto(Route.viewLibrary(library));
};
const onLibraryUpdate = async (library: LibraryResponseDto) => {
@@ -96,7 +96,7 @@
{videos.toLocaleString($locale)}
{diskUsage} {diskUsageUnit}
- handleViewLibrary(library)}>{$t('view')}
+ {$t('view')}
{/each}
@@ -106,7 +106,7 @@
goto(AppRoute.ADMIN_LIBRARIES_NEW)}
+ onClick={() => goto(Route.newLibrary())}
class="mt-10 mx-auto"
/>
{/if}
diff --git a/web/src/routes/admin/library-management/(list)/new/+page.svelte b/web/src/routes/admin/library-management/(list)/new/+page.svelte
index ac41d76fbd..e271e04b02 100644
--- a/web/src/routes/admin/library-management/(list)/new/+page.svelte
+++ b/web/src/routes/admin/library-management/(list)/new/+page.svelte
@@ -1,6 +1,6 @@
diff --git a/web/src/routes/admin/library-management/[id]/+layout.svelte b/web/src/routes/admin/library-management/[id]/+layout.svelte
index 762d3ea073..280c302882 100644
--- a/web/src/routes/admin/library-management/[id]/+layout.svelte
+++ b/web/src/routes/admin/library-management/[id]/+layout.svelte
@@ -7,8 +7,8 @@
import ServerStatisticsCard from '$lib/components/server-statistics/ServerStatisticsCard.svelte';
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
import TableButton from '$lib/components/TableButton.svelte';
- import { AppRoute } from '$lib/constants';
import LibraryFolderAddModal from '$lib/modals/LibraryFolderAddModal.svelte';
+ import { Route } from '$lib/route';
import {
getLibraryActions,
getLibraryExclusionPatternActions,
@@ -42,7 +42,7 @@
const onLibraryDelete = async ({ id }: { id: string }) => {
if (id === library.id) {
- await goto(AppRoute.ADMIN_LIBRARIES);
+ await goto(Route.libraries());
}
};
@@ -54,7 +54,7 @@
diff --git a/web/src/routes/admin/library-management/[id]/+layout.ts b/web/src/routes/admin/library-management/[id]/+layout.ts
index c07c9281e9..19bef0844d 100644
--- a/web/src/routes/admin/library-management/[id]/+layout.ts
+++ b/web/src/routes/admin/library-management/[id]/+layout.ts
@@ -1,4 +1,4 @@
-import { AppRoute } from '$lib/constants';
+import { Route } from '$lib/route';
import { authenticate } from '$lib/utils/auth';
import { getFormatter } from '$lib/utils/i18n';
import { getLibrary, getLibraryStatistics, type LibraryResponseDto } from '@immich/sdk';
@@ -13,7 +13,7 @@ export const load = (async ({ params: { id }, url }) => {
try {
library = await getLibrary({ id });
} catch {
- redirect(307, AppRoute.ADMIN_LIBRARIES);
+ redirect(307, Route.libraries());
}
const statistics = await getLibraryStatistics({ id });
diff --git a/web/src/routes/admin/library-management/[id]/edit/+page.svelte b/web/src/routes/admin/library-management/[id]/edit/+page.svelte
index 06e0af13e6..02c89e521d 100644
--- a/web/src/routes/admin/library-management/[id]/edit/+page.svelte
+++ b/web/src/routes/admin/library-management/[id]/edit/+page.svelte
@@ -1,6 +1,6 @@
@@ -102,7 +102,7 @@
diff --git a/web/src/routes/admin/users/[id]/+layout.ts b/web/src/routes/admin/users/[id]/+layout.ts
index 64d31da58e..84de38d300 100644
--- a/web/src/routes/admin/users/[id]/+layout.ts
+++ b/web/src/routes/admin/users/[id]/+layout.ts
@@ -1,4 +1,5 @@
-import { AppRoute, UUID_REGEX } from '$lib/constants';
+import { UUID_REGEX } from '$lib/constants';
+import { Route } from '$lib/route';
import { authenticate, requestServerInfo } from '$lib/utils/auth';
import { getFormatter } from '$lib/utils/i18n';
import { getUserPreferencesAdmin, getUserSessionsAdmin, getUserStatisticsAdmin, searchUsersAdmin } from '@immich/sdk';
@@ -10,12 +11,12 @@ export const load = (async ({ params, url }) => {
await requestServerInfo();
if (!UUID_REGEX.test(params.id)) {
- redirect(307, AppRoute.ADMIN_USERS);
+ redirect(307, Route.users());
}
const [user] = await searchUsersAdmin({ id: params.id, withDeleted: true }).catch(() => []);
if (!user) {
- redirect(307, AppRoute.ADMIN_USERS);
+ redirect(307, Route.users());
}
const [userPreferences, userStatistics, userSessions] = await Promise.all([
diff --git a/web/src/routes/admin/users/[id]/edit/+page.svelte b/web/src/routes/admin/users/[id]/edit/+page.svelte
index 14158f65c5..e8f03bf121 100644
--- a/web/src/routes/admin/users/[id]/edit/+page.svelte
+++ b/web/src/routes/admin/users/[id]/edit/+page.svelte
@@ -1,6 +1,6 @@