mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
refactor(web): routes (#25313)
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
import Albums from '$lib/components/album-page/albums-list.svelte';
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import GroupTab from '$lib/elements/GroupTab.svelte';
|
||||
import SearchBar from '$lib/elements/SearchBar.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { AlbumFilter, albumViewSettings } from '$lib/stores/preferences.store';
|
||||
import { createAlbumAndRedirect } from '$lib/utils/album-utils';
|
||||
import { t } from 'svelte-i18n';
|
||||
@@ -22,7 +22,7 @@
|
||||
let albumGroups: string[] = $state([]);
|
||||
</script>
|
||||
|
||||
<UserPageLayout title={data.meta.title} use={[[scrollMemory, { routeStartsWith: AppRoute.ALBUMS }]]}>
|
||||
<UserPageLayout title={data.meta.title} use={[[scrollMemory, { routeStartsWith: Route.albums() }]]}>
|
||||
{#snippet buttons()}
|
||||
<div class="flex place-items-center gap-2">
|
||||
<AlbumsControls {albumGroups} bind:searchQuery />
|
||||
|
||||
+8
-7
@@ -29,7 +29,7 @@
|
||||
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 { AlbumPageViewMode, AppRoute } from '$lib/constants';
|
||||
import { AlbumPageViewMode } from '$lib/constants';
|
||||
import { activityManager } from '$lib/managers/activity-manager.svelte';
|
||||
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||
@@ -37,6 +37,7 @@
|
||||
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
||||
import AlbumOptionsModal from '$lib/modals/AlbumOptionsModal.svelte';
|
||||
import SharedLinkCreateModal from '$lib/modals/SharedLinkCreateModal.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import {
|
||||
getAlbumActions,
|
||||
getAlbumAssetsActions,
|
||||
@@ -90,7 +91,7 @@
|
||||
|
||||
let oldAt: AssetGridRouteSearchParams | null | undefined = $state();
|
||||
|
||||
let backUrl: string = $state(AppRoute.ALBUMS);
|
||||
let backUrl: string = $state(Route.albums());
|
||||
let viewMode: AlbumPageViewMode = $state(AlbumPageViewMode.VIEW);
|
||||
|
||||
let timelineManager = $state<TimelineManager>() as TimelineManager;
|
||||
@@ -108,13 +109,13 @@
|
||||
}
|
||||
|
||||
if (isAlbumsRoute(route) || isPeopleRoute(route)) {
|
||||
url = AppRoute.ALBUMS;
|
||||
url = Route.albums();
|
||||
}
|
||||
|
||||
backUrl = url || AppRoute.ALBUMS;
|
||||
backUrl = url || Route.albums();
|
||||
|
||||
if (backUrl === AppRoute.SHARED_LINKS) {
|
||||
backUrl = history.state?.backUrl || AppRoute.ALBUMS;
|
||||
if (backUrl === Route.sharedLinks()) {
|
||||
backUrl = history.state?.backUrl || Route.albums();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -347,7 +348,7 @@
|
||||
/>
|
||||
<CommandPaletteDefaultProvider name={$t('album')} actions={[AddAssets, Upload]} />
|
||||
|
||||
<div class="flex overflow-hidden" use:scrollMemoryClearer={{ routeStartsWith: AppRoute.ALBUMS }}>
|
||||
<div class="flex overflow-hidden" use:scrollMemoryClearer={{ routeStartsWith: Route.albums() }}>
|
||||
<div class="relative w-full shrink">
|
||||
<main class="relative h-dvh overflow-hidden px-2 md:px-6 max-md:pt-(--navbar-height-md) pt-(--navbar-height)">
|
||||
<Timeline
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import LicenseActivationSuccess from '$lib/components/shared-components/purchasing/purchase-activation-success.svelte';
|
||||
import LicenseContent from '$lib/components/shared-components/purchasing/purchase-content.svelte';
|
||||
import SupporterBadge from '$lib/components/shared-components/side-bar/supporter-badge.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { purchaseStore } from '$lib/stores/purchase.store';
|
||||
import { Alert, Container, Stack } from '@immich/ui';
|
||||
import { mdiAlertCircleOutline } from '@mdi/js';
|
||||
@@ -32,7 +32,7 @@
|
||||
{/if}
|
||||
|
||||
{#if showLicenseActivated || data.isActivated === true}
|
||||
<LicenseActivationSuccess onDone={() => goto(AppRoute.PHOTOS, { replaceState: false })} />
|
||||
<LicenseActivationSuccess onDone={() => goto(Route.photos(), { replaceState: false })} />
|
||||
{:else}
|
||||
<LicenseContent
|
||||
onActivate={() => {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import SingleGridRow from '$lib/components/shared-components/single-grid-row.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { websocketEvents } from '$lib/stores/websocket';
|
||||
import { getAssetThumbnailUrl, getPeopleThumbnailUrl } from '$lib/utils';
|
||||
import { getMetadataSearchQuery } from '$lib/utils/metadata-search';
|
||||
import { AssetMediaSize, type SearchExploreResponseDto } from '@immich/sdk';
|
||||
import { Icon } from '@immich/ui';
|
||||
import { mdiHeart } from '@mdi/js';
|
||||
@@ -81,7 +81,7 @@
|
||||
<div class="flex justify-between">
|
||||
<p class="mb-4 font-medium dark:text-immich-dark-fg">{$t('places')}</p>
|
||||
<a
|
||||
href={AppRoute.PLACES}
|
||||
href={Route.places()}
|
||||
class="pe-4 text-sm font-medium hover:text-immich-primary dark:text-immich-dark-fg dark:hover:text-immich-dark-primary"
|
||||
draggable="false">{$t('view_all')}</a
|
||||
>
|
||||
@@ -89,11 +89,7 @@
|
||||
<SingleGridRow class="grid grid-flow-col md:grid-auto-fill-36 grid-auto-fill-28 gap-x-4">
|
||||
{#snippet children({ itemCount })}
|
||||
{#each places.slice(0, itemCount) as item (item.data.id)}
|
||||
<a
|
||||
class="relative"
|
||||
href="{AppRoute.SEARCH}?{getMetadataSearchQuery({ city: item.value })}"
|
||||
draggable="false"
|
||||
>
|
||||
<a class="relative" href={Route.search({ city: item.value })} draggable="false">
|
||||
<div class="flex justify-center overflow-hidden rounded-xl brightness-75 filter">
|
||||
<img
|
||||
src={getAssetThumbnailUrl({ id: item.data.id, size: AssetMediaSize.Thumbnail })}
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
import SetVisibilityAction from '$lib/components/timeline/actions/SetVisibilityAction.svelte';
|
||||
import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte';
|
||||
import Timeline from '$lib/components/timeline/Timeline.svelte';
|
||||
import { AppRoute, AssetAction } 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 { AssetVisibility, lockAuthSession } from '@immich/sdk';
|
||||
import { Button } from '@immich/ui';
|
||||
@@ -45,7 +46,7 @@
|
||||
|
||||
const handleLock = async () => {
|
||||
await lockAuthSession();
|
||||
await goto(AppRoute.PHOTOS);
|
||||
await goto(Route.photos());
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -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 { getAuthStatus } from '@immich/sdk';
|
||||
@@ -10,7 +10,7 @@ export const load = (async ({ url }) => {
|
||||
|
||||
const { isElevated, pinCode } = await getAuthStatus();
|
||||
if (!isElevated || !pinCode) {
|
||||
redirect(307, `${AppRoute.AUTH_PIN_PROMPT}?continue=${encodeURIComponent(url.pathname + url.search)}`);
|
||||
redirect(307, Route.pinPrompt({ continue: url.pathname + url.search }));
|
||||
}
|
||||
|
||||
const $t = await getFormatter();
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import type { AssetCursor } from '$lib/components/asset-viewer/asset-viewer.svelte';
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import { AppRoute, timeToLoadTheMap } from '$lib/constants';
|
||||
import { timeToLoadTheMap } from '$lib/constants';
|
||||
import Portal from '$lib/elements/Portal.svelte';
|
||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import { handlePromiseError } from '$lib/utils';
|
||||
import { delay } from '$lib/utils/asset-utils';
|
||||
@@ -30,7 +31,7 @@
|
||||
});
|
||||
|
||||
if (!featureFlagsManager.value.map) {
|
||||
handlePromiseError(goto(AppRoute.PHOTOS));
|
||||
handlePromiseError(goto(Route.photos()));
|
||||
}
|
||||
|
||||
async function onViewAssets(assetIds: string[]) {
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@
|
||||
import DownloadAction from '$lib/components/timeline/actions/DownloadAction.svelte';
|
||||
import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte';
|
||||
import Timeline from '$lib/components/timeline/Timeline.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { AssetVisibility } from '@immich/sdk';
|
||||
import { mdiArrowLeft, mdiPlus } from '@mdi/js';
|
||||
@@ -53,7 +53,7 @@
|
||||
<DownloadAction />
|
||||
</AssetSelectControlBar>
|
||||
{:else}
|
||||
<ControlAppBar showBackButton backIcon={mdiArrowLeft} onClose={() => goto(AppRoute.SHARING)}>
|
||||
<ControlAppBar showBackButton backIcon={mdiArrowLeft} onClose={() => goto(Route.sharing())}>
|
||||
{#snippet leading()}
|
||||
<p class="whitespace-nowrap text-immich-fg dark:text-immich-dark-fg">
|
||||
{data.partner.name}'s photos
|
||||
|
||||
+2
-1
@@ -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<string>(Route.explore());
|
||||
let personMerge1: PersonResponseDto | undefined = $state();
|
||||
let personMerge2: PersonResponseDto | undefined = $state();
|
||||
let potentialMergePeople: PersonResponseDto[] = $state([]);
|
||||
|
||||
@@ -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),
|
||||
})),
|
||||
|
||||
@@ -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<string>(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()
|
||||
|
||||
@@ -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<Filter, string> = {
|
||||
const filterMap: Record<SharedLinkTab, string> = {
|
||||
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 @@
|
||||
<UserPageLayout title={data.meta.title}>
|
||||
{#snippet buttons()}
|
||||
<div class="hidden xl:block h-10">
|
||||
<GroupTab label={$t('show_shared_links')} {filters} {labels} selected={selectedTab} onSelect={handleSelectTab} />
|
||||
<GroupTab
|
||||
label={$t('show_shared_links')}
|
||||
{filters}
|
||||
{labels}
|
||||
selected={selectedTab}
|
||||
onSelect={(value) => goto(Route.sharedLinks({ filter: value as SharedLinkTab }))}
|
||||
/>
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import SharedLinkExpiration from '$lib/components/SharedLinkExpiration.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { handleUpdateSharedLink } from '$lib/services/shared-link.service';
|
||||
import { SharedLinkType } from '@immich/sdk';
|
||||
import { Field, FormModal, Input, PasswordInput, Switch, Text } from '@immich/ui';
|
||||
@@ -27,7 +27,7 @@
|
||||
let expiresAt = $state(sharedLink.expiresAt);
|
||||
|
||||
const onClose = async () => {
|
||||
await goto(`${AppRoute.SHARED_LINKS}`);
|
||||
await goto(Route.sharedLinks());
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import {
|
||||
AlbumFilter,
|
||||
AlbumGroupBy,
|
||||
@@ -48,7 +48,7 @@
|
||||
>
|
||||
<Text class="hidden md:block">{$t('create_album')}</Text>
|
||||
</Button>
|
||||
<Button leadingIcon={mdiLink} href={AppRoute.SHARED_LINKS} size="small" variant="ghost" color="secondary">
|
||||
<Button leadingIcon={mdiLink} href={Route.sharedLinks()} size="small" variant="ghost" color="secondary">
|
||||
<Text class="hidden md:block">{$t('shared_links')}</Text>
|
||||
</Button>
|
||||
</HStack>
|
||||
@@ -64,7 +64,7 @@
|
||||
<div class="flex flex-row flex-wrap gap-4">
|
||||
{#each data.partners as partner (partner.id)}
|
||||
<a
|
||||
href="{AppRoute.PARTNERS}/{partner.id}"
|
||||
href={Route.viewPartner(partner)}
|
||||
class="flex gap-4 rounded-lg px-5 py-4 transition-all hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||
>
|
||||
<UserAvatar user={partner} size="lg" />
|
||||
|
||||
@@ -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.SHARED_LINKS);
|
||||
}) satisfies PageLoad;
|
||||
export const load = (() => redirect(307, Route.sharedLinks())) satisfies PageLoad;
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
import SelectAllAssets from '$lib/components/timeline/actions/SelectAllAction.svelte';
|
||||
import AssetSelectControlBar from '$lib/components/timeline/AssetSelectControlBar.svelte';
|
||||
import Timeline from '$lib/components/timeline/Timeline.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||
import { serverConfigManager } from '$lib/managers/server-config-manager.svelte';
|
||||
import { TimelineManager } from '$lib/managers/timeline-manager/timeline-manager.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { getTrashActions } from '$lib/services/trash.service';
|
||||
import { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
|
||||
import { handlePromiseError } from '$lib/utils';
|
||||
@@ -30,7 +30,7 @@
|
||||
const assetInteraction = new AssetInteraction();
|
||||
|
||||
if (!featureFlagsManager.value.trash) {
|
||||
handlePromiseError(goto(AppRoute.PHOTOS));
|
||||
handlePromiseError(goto(Route.photos()));
|
||||
}
|
||||
|
||||
const handleEscape = () => {
|
||||
|
||||
+12
-21
@@ -4,10 +4,10 @@
|
||||
import { shortcuts } from '$lib/actions/shortcut';
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
import DuplicatesCompareControl from '$lib/components/utilities-page/duplicates/duplicates-compare-control.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||
import DuplicatesInformationModal from '$lib/modals/DuplicatesInformationModal.svelte';
|
||||
import ShortcutsModal from '$lib/modals/ShortcutsModal.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { stackAssets } from '$lib/utils/asset-utils';
|
||||
@@ -107,7 +107,7 @@
|
||||
duplicates = duplicates.filter((duplicate) => duplicate.duplicateId !== duplicateId);
|
||||
|
||||
deletedNotification(trashIds.length);
|
||||
await correctDuplicatesIndexAndGo(duplicatesIndex);
|
||||
await navigateToIndex(duplicatesIndex);
|
||||
},
|
||||
trashIds.length > 0 && !featureFlagsManager.value.trash ? $t('delete_duplicates_confirmation') : undefined,
|
||||
trashIds.length > 0 && !featureFlagsManager.value.trash ? $t('permanently_delete') : undefined,
|
||||
@@ -119,7 +119,7 @@
|
||||
const duplicateAssetIds = assets.map((asset) => asset.id);
|
||||
await updateAssets({ assetBulkUpdateDto: { ids: duplicateAssetIds, duplicateId: null } });
|
||||
duplicates = duplicates.filter((duplicate) => duplicate.duplicateId !== duplicateId);
|
||||
await correctDuplicatesIndexAndGo(duplicatesIndex);
|
||||
await navigateToIndex(duplicatesIndex);
|
||||
};
|
||||
|
||||
const handleDeduplicateAll = async () => {
|
||||
@@ -152,7 +152,7 @@
|
||||
deletedNotification(idsToDelete.length);
|
||||
|
||||
page.url.searchParams.delete('index');
|
||||
await goto(`${AppRoute.DUPLICATES}`);
|
||||
await goto(Route.duplicatesUtility());
|
||||
},
|
||||
prompt,
|
||||
confirmText,
|
||||
@@ -169,41 +169,32 @@
|
||||
|
||||
toastManager.success($t('resolved_all_duplicates'));
|
||||
page.url.searchParams.delete('index');
|
||||
await goto(`${AppRoute.DUPLICATES}`);
|
||||
await goto(Route.duplicatesUtility());
|
||||
},
|
||||
$t('bulk_keep_duplicates_confirmation', { values: { count: ids.length } }),
|
||||
$t('confirm'),
|
||||
);
|
||||
};
|
||||
|
||||
const handleFirst = async () => {
|
||||
await correctDuplicatesIndexAndGo(0);
|
||||
};
|
||||
const handlePrevious = async () => {
|
||||
await correctDuplicatesIndexAndGo(Math.max(duplicatesIndex - 1, 0));
|
||||
};
|
||||
const handleFirst = () => navigateToIndex(0);
|
||||
const handlePrevious = () => navigateToIndex(Math.max(duplicatesIndex - 1, 0));
|
||||
const handlePreviousShortcut = async () => {
|
||||
if ($showAssetViewer) {
|
||||
return;
|
||||
}
|
||||
await handlePrevious();
|
||||
};
|
||||
const handleNext = async () => {
|
||||
await correctDuplicatesIndexAndGo(Math.min(duplicatesIndex + 1, duplicates.length - 1));
|
||||
};
|
||||
const handleNext = async () => navigateToIndex(Math.min(duplicatesIndex + 1, duplicates.length - 1));
|
||||
const handleNextShortcut = async () => {
|
||||
if ($showAssetViewer) {
|
||||
return;
|
||||
}
|
||||
await handleNext();
|
||||
};
|
||||
const handleLast = async () => {
|
||||
await correctDuplicatesIndexAndGo(duplicates.length - 1);
|
||||
};
|
||||
const correctDuplicatesIndexAndGo = async (index: number) => {
|
||||
page.url.searchParams.set('index', correctDuplicatesIndex(index).toString());
|
||||
await goto(`${AppRoute.DUPLICATES}?${page.url.searchParams.toString()}`);
|
||||
};
|
||||
const handleLast = () => navigateToIndex(duplicates.length - 1);
|
||||
|
||||
const navigateToIndex = async (index: number) =>
|
||||
goto(Route.duplicatesUtility({ index: correctDuplicatesIndex(index) }));
|
||||
</script>
|
||||
|
||||
<svelte:document
|
||||
|
||||
@@ -1,8 +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 = (({ params }) => {
|
||||
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;
|
||||
|
||||
@@ -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 @@
|
||||
<WorkflowSummarySidebar trigger={selectedTrigger} filters={selectedFilters} actions={selectedActions} />
|
||||
</main>
|
||||
|
||||
<ControlAppBar onClose={() => goto(AppRoute.WORKFLOWS)} backIcon={mdiArrowLeft} tailwindClasses="fixed! top-0! w-full">
|
||||
<ControlAppBar onClose={() => goto(Route.workflows())} backIcon={mdiArrowLeft} tailwindClasses="fixed! top-0! w-full">
|
||||
{#snippet leading()}
|
||||
<Text>{data.meta.title}</Text>
|
||||
{/snippet}
|
||||
|
||||
@@ -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 }));
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import AuthPageLayout from '$lib/components/layouts/AuthPageLayout.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { Button, Heading } from '@immich/ui';
|
||||
import { t } from 'svelte-i18n';
|
||||
</script>
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="flex flex-col place-items-center text-center gap-12">
|
||||
<Heading size="large" color="primary" tag="h1">{$t('welcome_to_immich')}</Heading>
|
||||
<div>
|
||||
<Button href={AppRoute.AUTH_REGISTER} size="medium" shape="round">
|
||||
<Button href={Route.register()} size="medium" shape="round">
|
||||
<span class="px-2 font-semibold">{$t('getting_started')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 @@
|
||||
<TableCell class={classes.column4}>{videos.toLocaleString($locale)}</TableCell>
|
||||
<TableCell class={classes.column5}>{diskUsage} {diskUsageUnit}</TableCell>
|
||||
<TableCell class={classes.column6}>
|
||||
<Button size="small" onclick={() => handleViewLibrary(library)}>{$t('view')}</Button>
|
||||
<Button size="small" href={Route.viewLibrary(library)}>{$t('view')}</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{/each}
|
||||
@@ -106,7 +106,7 @@
|
||||
<EmptyPlaceholder
|
||||
fullWidth
|
||||
text={$t('no_libraries_message')}
|
||||
onClick={() => goto(AppRoute.ADMIN_LIBRARIES_NEW)}
|
||||
onClick={() => goto(Route.newLibrary())}
|
||||
class="mt-10 mx-auto"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { handleCreateLibrary } from '$lib/services/library.service';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { Field, FormModal, HelperText, Select } from '@immich/ui';
|
||||
@@ -18,13 +18,13 @@
|
||||
const users = $state(data.allUsers);
|
||||
|
||||
const onClose = async () => {
|
||||
await goto(AppRoute.ADMIN_LIBRARIES);
|
||||
await goto(Route.libraries());
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
const library = await handleCreateLibrary({ ownerId });
|
||||
if (library) {
|
||||
await goto(`${AppRoute.ADMIN_LIBRARIES}/${library.id}`, { replaceState: true });
|
||||
await goto(Route.viewLibrary(library), { replaceState: true });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -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 @@
|
||||
<CommandPaletteDefaultProvider name={$t('library')} actions={[Edit, Delete, AddFolder, AddExclusionPattern, Scan]} />
|
||||
|
||||
<AdminPageLayout
|
||||
breadcrumbs={[{ title: $t('external_libraries'), href: AppRoute.ADMIN_LIBRARIES }, { title: library.name }]}
|
||||
breadcrumbs={[{ title: $t('external_libraries'), href: Route.libraries() }, { title: library.name }]}
|
||||
actions={[Scan, Edit, Delete]}
|
||||
>
|
||||
<Container size="large" center>
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { handleUpdateLibrary } from '$lib/services/library.service';
|
||||
import { Field, FormModal, Input } from '@immich/ui';
|
||||
import { mdiRenameOutline } from '@mdi/js';
|
||||
@@ -17,7 +17,7 @@
|
||||
let name = $state(library.name);
|
||||
|
||||
const onClose = async () => {
|
||||
await goto(`${AppRoute.ADMIN_LIBRARIES}/${library.id}`);
|
||||
await goto(Route.viewLibrary(library));
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import AdminPageLayout from '$lib/components/layouts/AdminPageLayout.svelte';
|
||||
import OnEvents from '$lib/components/OnEvents.svelte';
|
||||
import QueueGraph from '$lib/components/QueueGraph.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { queueManager } from '$lib/managers/queue-manager.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { asQueueItem, getQueueActions } from '$lib/services/queue.service';
|
||||
import { type QueueResponseDto } from '@immich/sdk';
|
||||
import {
|
||||
@@ -46,7 +46,7 @@
|
||||
<OnEvents {onQueueUpdate} />
|
||||
|
||||
<AdminPageLayout
|
||||
breadcrumbs={[{ title: $t('admin.queues'), href: AppRoute.ADMIN_QUEUES }, { title: item.title }]}
|
||||
breadcrumbs={[{ title: $t('admin.queues'), href: Route.queues() }, { title: item.title }]}
|
||||
actions={[Pause, Resume, Empty, MenuItemType.Divider, RemoveFailedJobs]}
|
||||
>
|
||||
<div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { fromQueueSlug } from '$lib/services/queue.service';
|
||||
import { fromQueueSlug, Route } from '$lib/route';
|
||||
import { authenticate, requestServerInfo } from '$lib/utils/auth';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
import { getQueue, getQueueJobs, QueueJobStatus } from '@immich/sdk';
|
||||
@@ -12,7 +11,7 @@ export const load = (async ({ params, url }) => {
|
||||
|
||||
const name = fromQueueSlug(params.name);
|
||||
if (!name) {
|
||||
redirect(307, AppRoute.ADMIN_QUEUES);
|
||||
redirect(307, Route.queues());
|
||||
}
|
||||
|
||||
const [queue, failedJobs] = await Promise.all([
|
||||
|
||||
@@ -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_USERS)) satisfies PageLoad;
|
||||
export const load = (() => redirect(307, Route.users())) satisfies PageLoad;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { handleCreateUserAdmin } from '$lib/services/user-admin.service';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
import { ByteUnit, convertToBytes } from '$lib/utils/byte-units';
|
||||
@@ -31,7 +31,7 @@
|
||||
const valid = $derived(!passwordMismatch && !isCreatingUser);
|
||||
|
||||
const onClose = async () => {
|
||||
await goto(AppRoute.ADMIN_USERS);
|
||||
await goto(Route.users());
|
||||
};
|
||||
|
||||
const onSubmit = async (event: Event) => {
|
||||
@@ -54,7 +54,7 @@
|
||||
});
|
||||
|
||||
if (user) {
|
||||
await goto(`${AppRoute.ADMIN_USERS}/${user.id}`, { replaceState: true });
|
||||
await goto(Route.viewUser(user), { replaceState: true });
|
||||
}
|
||||
|
||||
isCreatingUser = false;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
|
||||
import DeviceCard from '$lib/components/user-settings-page/device-card.svelte';
|
||||
import FeatureSetting from '$lib/components/users/FeatureSetting.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { getUserAdminActions } from '$lib/services/user-admin.service';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { createDateFormatter, findLocale } from '$lib/utils';
|
||||
@@ -87,7 +87,7 @@
|
||||
|
||||
const onUserAdminDeleted = async ({ id }: { id: string }) => {
|
||||
if (id === user.id) {
|
||||
await goto(AppRoute.ADMIN_USERS);
|
||||
await goto(Route.users());
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -102,7 +102,7 @@
|
||||
<CommandPaletteDefaultProvider name={$t('user')} actions={[ResetPassword, ResetPinCode, Update, Delete, Restore]} />
|
||||
|
||||
<AdminPageLayout
|
||||
breadcrumbs={[{ title: $t('admin.user_management'), href: AppRoute.ADMIN_USERS }, { title: user.name }]}
|
||||
breadcrumbs={[{ title: $t('admin.user_management'), href: Route.users() }, { title: user.name }]}
|
||||
actions={[ResetPassword, ResetPinCode, Update, Restore, MenuItemType.Divider, Delete]}
|
||||
>
|
||||
<div>
|
||||
|
||||
@@ -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([
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { handleUpdateUserAdmin } from '$lib/services/user-admin.service';
|
||||
import { user as authUser } from '$lib/stores/user.store';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
@@ -37,7 +37,7 @@
|
||||
);
|
||||
|
||||
const onClose = async () => {
|
||||
await goto(`${AppRoute.ADMIN_USERS}/${user.id}`);
|
||||
await goto(Route.viewUser(user));
|
||||
};
|
||||
|
||||
const onSubmit = async (event: Event) => {
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
<Text size="small" class="mt-2" color="muted">
|
||||
{$t('admin.note_apply_storage_label_previous_assets')}
|
||||
<Link href={AppRoute.ADMIN_QUEUES}>
|
||||
<Link href={Route.queues()}>
|
||||
{$t('admin.storage_template_migration_job')}
|
||||
</Link>
|
||||
</Text>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { authenticate } from '$lib/utils/auth';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
@@ -9,7 +9,7 @@ import type { PageLoad } from './$types';
|
||||
export const load = (async ({ url }) => {
|
||||
await authenticate(url);
|
||||
if (!get(user).shouldChangePassword) {
|
||||
redirect(307, AppRoute.PHOTOS);
|
||||
redirect(307, Route.photos());
|
||||
}
|
||||
|
||||
const $t = await getFormatter();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import AuthPageLayout from '$lib/components/layouts/AuthPageLayout.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||
import { serverConfigManager } from '$lib/managers/server-config-manager.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { oauth } from '$lib/utils';
|
||||
import { getServerErrorMessage, handleError } from '$lib/utils/handle-error';
|
||||
import { login, type LoginResponseDto } from '@immich/sdk';
|
||||
@@ -33,8 +33,8 @@
|
||||
eventManager.emit('AuthLogin', user);
|
||||
};
|
||||
|
||||
const onFirstLogin = () => goto(AppRoute.AUTH_CHANGE_PASSWORD);
|
||||
const onOnboarding = () => goto(AppRoute.AUTH_ONBOARDING);
|
||||
const onFirstLogin = () => goto(Route.changePassword());
|
||||
const onOnboarding = () => goto(Route.onboarding());
|
||||
|
||||
onMount(async () => {
|
||||
if (!featureFlagsManager.value.oauth) {
|
||||
@@ -66,7 +66,7 @@
|
||||
(featureFlagsManager.value.oauthAutoLaunch && !oauth.isAutoLaunchDisabled(globalThis.location)) ||
|
||||
oauth.isAutoLaunchEnabled(globalThis.location)
|
||||
) {
|
||||
await goto(`${AppRoute.AUTH_LOGIN}?autoLaunch=0`, { replaceState: true });
|
||||
await goto(Route.login({ autoLaunch: 0 }), { replaceState: true });
|
||||
await oauth.authorize(globalThis.location);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 { redirect } from '@sveltejs/kit';
|
||||
import type { PageLoad } from './$types';
|
||||
@@ -9,7 +9,7 @@ export const load = (async ({ parent, url }) => {
|
||||
|
||||
if (!serverConfigManager.value.isInitialized) {
|
||||
// Admin not registered
|
||||
redirect(307, AppRoute.AUTH_REGISTER);
|
||||
redirect(307, Route.register());
|
||||
}
|
||||
|
||||
const $t = await getFormatter();
|
||||
@@ -17,6 +17,6 @@ export const load = (async ({ parent, url }) => {
|
||||
meta: {
|
||||
title: $t('login'),
|
||||
},
|
||||
continueUrl: url.searchParams.get('continue') || AppRoute.PHOTOS,
|
||||
continueUrl: url.searchParams.get('continue') || Route.photos(),
|
||||
};
|
||||
}) satisfies PageLoad;
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
import OnboardingStorageTemplate from '$lib/components/onboarding-page/onboarding-storage-template.svelte';
|
||||
import OnboardingTheme from '$lib/components/onboarding-page/onboarding-theme.svelte';
|
||||
import OnboardingUserPrivacy from '$lib/components/onboarding-page/onboarding-user-privacy.svelte';
|
||||
import { AppRoute, QueryParameter } from '$lib/constants';
|
||||
import { serverConfigManager } from '$lib/managers/server-config-manager.svelte';
|
||||
import { systemConfigManager } from '$lib/managers/system-config-manager.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { OnboardingRole } from '$lib/types';
|
||||
import { setUserOnboarding, updateAdminOnboarding } from '@immich/sdk';
|
||||
@@ -137,11 +137,9 @@
|
||||
onboardingDto: { isOnboarded: true },
|
||||
});
|
||||
|
||||
await goto(AppRoute.PHOTOS);
|
||||
await goto(Route.photos());
|
||||
} else {
|
||||
await goto(
|
||||
`${AppRoute.AUTH_ONBOARDING}?${QueryParameter.ONBOARDING_STEP}=${onboardingSteps[nextStepIndex].name}`,
|
||||
);
|
||||
await goto(Route.onboarding({ step: onboardingSteps[nextStepIndex].name }));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -150,9 +148,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
await goto(
|
||||
`${AppRoute.AUTH_ONBOARDING}?${QueryParameter.ONBOARDING_STEP}=${onboardingSteps[previousStepIndex].name}`,
|
||||
);
|
||||
await goto(Route.onboarding({ step: onboardingSteps[previousStepIndex].name }));
|
||||
};
|
||||
|
||||
const OnboardingStep = $derived(onboardingSteps[index].component);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import AuthPageLayout from '$lib/components/layouts/AuthPageLayout.svelte';
|
||||
import PinCodeCreateForm from '$lib/components/user-settings-page/PinCodeCreateForm.svelte';
|
||||
import PincodeInput from '$lib/components/user-settings-page/PinCodeInput.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { unlockAuthSession } from '@immich/sdk';
|
||||
import { Button, Icon } from '@immich/ui';
|
||||
@@ -65,7 +65,7 @@
|
||||
onFilled={handleUnlockSession}
|
||||
/>
|
||||
|
||||
<Button type="button" color="secondary" onclick={() => goto(AppRoute.PHOTOS)}>{$t('cancel')}</Button>
|
||||
<Button type="button" color="secondary" onclick={() => goto(Route.photos())}>{$t('cancel')}</Button>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
|
||||
@@ -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 { getAuthStatus } from '@immich/sdk';
|
||||
@@ -16,6 +16,6 @@ export const load = (async ({ url }) => {
|
||||
title: $t('pin_verification'),
|
||||
},
|
||||
hasPinCode: !!pinCode,
|
||||
continueUrl: url.searchParams.get('continue') || AppRoute.LOCKED,
|
||||
continueUrl: url.searchParams.get('continue') || Route.locked(),
|
||||
};
|
||||
}) satisfies PageLoad;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import AuthPageLayout from '$lib/components/layouts/AuthPageLayout.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { serverConfigManager } from '$lib/managers/server-config-manager.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { signUpAdmin } from '@immich/sdk';
|
||||
import { Alert, Button, Field, Input, PasswordInput, Text } from '@immich/ui';
|
||||
@@ -38,7 +38,7 @@
|
||||
try {
|
||||
await signUpAdmin({ signUpDto: { email, password, name } });
|
||||
await serverConfigManager.loadServerConfig();
|
||||
await goto(AppRoute.AUTH_LOGIN);
|
||||
await goto(Route.login());
|
||||
} catch (error) {
|
||||
handleError(error, $t('errors.unable_to_create_admin_account'));
|
||||
errorMessage = $t('errors.unable_to_create_admin_account');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 { redirect } from '@sveltejs/kit';
|
||||
import type { PageLoad } from './$types';
|
||||
@@ -8,7 +8,7 @@ export const load = (async ({ parent }) => {
|
||||
await parent();
|
||||
if (serverConfigManager.value.isInitialized) {
|
||||
// Admin has been registered, redirect to login
|
||||
redirect(307, AppRoute.AUTH_LOGIN);
|
||||
redirect(307, Route.login());
|
||||
}
|
||||
|
||||
const $t = await getFormatter();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { AppRoute, OpenQueryParam } from '$lib/constants';
|
||||
import { Route } from '$lib/route';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
@@ -14,17 +15,17 @@ export const load = (({ url }) => {
|
||||
const target = queryParams.get('target') as LinkTarget;
|
||||
switch (target) {
|
||||
case LinkTarget.HOME: {
|
||||
return redirect(307, AppRoute.PHOTOS);
|
||||
return redirect(307, Route.photos());
|
||||
}
|
||||
|
||||
case LinkTarget.UNSUBSCRIBE: {
|
||||
return redirect(307, `${AppRoute.USER_SETTINGS}?isOpen=notifications`);
|
||||
return redirect(307, Route.userSettings({ isOpen: OpenQueryParam.NOTIFICATIONS }));
|
||||
}
|
||||
|
||||
case LinkTarget.VIEW_ASSET: {
|
||||
const id = queryParams.get('id');
|
||||
if (id) {
|
||||
return redirect(307, `${AppRoute.PHOTOS}/${id}`);
|
||||
return redirect(307, Route.viewAsset({ id }));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -49,5 +50,5 @@ export const load = (({ url }) => {
|
||||
}
|
||||
}
|
||||
|
||||
return redirect(307, AppRoute.PHOTOS);
|
||||
return redirect(307, Route.photos());
|
||||
}) satisfies PageLoad;
|
||||
|
||||
Reference in New Issue
Block a user