diff --git a/web/src/lib/components/user-settings-page/user-settings-list.svelte b/web/src/lib/components/user-settings-page/user-settings-list.svelte index e3392ac077..66eae1280b 100644 --- a/web/src/lib/components/user-settings-page/user-settings-list.svelte +++ b/web/src/lib/components/user-settings-page/user-settings-list.svelte @@ -10,7 +10,7 @@ import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { user } from '$lib/stores/user.store'; import { oauth } from '$lib/utils'; - import { type ApiKeyResponseDto, type SessionResponseDto } from '@immich/sdk'; + import { getApiKeys, type ApiKeyResponseDto, type SessionResponseDto } from '@immich/sdk'; import { mdiAccountGroupOutline, mdiAccountOutline, @@ -36,13 +36,19 @@ import PartnerSettings from './partner-settings.svelte'; import UserAPIKeyList from './user-api-key-list.svelte'; import UserProfileSettings from './user-profile-settings.svelte'; + import { onMount } from 'svelte'; interface Props { - keys?: ApiKeyResponseDto[]; sessions?: SessionResponseDto[]; } - let { keys = $bindable([]), sessions = $bindable([]) }: Props = $props(); + let { sessions = $bindable([]) }: Props = $props(); + + let keys: ApiKeyResponseDto[] = $state([]); + + onMount(async () => { + keys = await getApiKeys(); + }) let oauthOpen = oauth.isCallback(globalThis.location) || diff --git a/web/src/lib/constants.ts b/web/src/lib/constants.ts index 389ebbefab..059d6ffb65 100644 --- a/web/src/lib/constants.ts +++ b/web/src/lib/constants.ts @@ -62,6 +62,7 @@ export enum SessionStorageKey { // TODO split into user settings vs system settings export enum OpenQueryParam { + API_KEYS = 'api-keys', OAUTH = 'oauth', JOB = 'job', STORAGE_TEMPLATE = 'storage-template', diff --git a/web/src/lib/route.ts b/web/src/lib/route.ts index 5a59ec704c..42ab1e22cc 100644 --- a/web/src/lib/route.ts +++ b/web/src/lib/route.ts @@ -116,6 +116,7 @@ export const Route = { // settings userSettings: (params?: { isOpen?: OpenQueryParam }) => '/user-settings' + asQueryString(params), + newApiKey: (params?: { permissions?: string }) => '/user-settings/new-api-key' + asQueryString(params), // system systemSettings: (params?: { isOpen?: OpenQueryParam }) => '/admin/system-settings' + asQueryString(params), diff --git a/web/src/lib/services/api-key.service.ts b/web/src/lib/services/api-key.service.ts index dec333c0bc..d5890907c8 100644 --- a/web/src/lib/services/api-key.service.ts +++ b/web/src/lib/services/api-key.service.ts @@ -1,6 +1,7 @@ +import { goto } from '$app/navigation'; import { eventManager } from '$lib/managers/event-manager.svelte'; -import ApiKeyCreateModal from '$lib/modals/ApiKeyCreateModal.svelte'; import ApiKeyUpdateModal from '$lib/modals/ApiKeyUpdateModal.svelte'; +import { Route } from '$lib/route'; import { handleError } from '$lib/utils/handle-error'; import { getFormatter } from '$lib/utils/i18n'; import { @@ -19,7 +20,7 @@ export const getApiKeysActions = ($t: MessageFormatter) => { const Create: ActionItem = { title: $t('new_api_key'), icon: mdiPlus, - onAction: () => modalManager.show(ApiKeyCreateModal, {}), + onAction: () => goto(Route.newApiKey()), }; return { Create }; diff --git a/web/src/routes/(user)/user-settings/+layout.svelte b/web/src/routes/(user)/user-settings/+layout.svelte new file mode 100644 index 0000000000..096047a885 --- /dev/null +++ b/web/src/routes/(user)/user-settings/+layout.svelte @@ -0,0 +1,26 @@ + + + + + + + {@render children?.()} + + diff --git a/web/src/routes/(user)/user-settings/+page.ts b/web/src/routes/(user)/user-settings/+layout.ts similarity index 79% rename from web/src/routes/(user)/user-settings/+page.ts rename to web/src/routes/(user)/user-settings/+layout.ts index bf36eeefb5..5731277f9d 100644 --- a/web/src/routes/(user)/user-settings/+page.ts +++ b/web/src/routes/(user)/user-settings/+layout.ts @@ -1,17 +1,15 @@ import { authenticate } from '$lib/utils/auth'; import { getFormatter } from '$lib/utils/i18n'; -import { getApiKeys, getSessions } from '@immich/sdk'; +import { getSessions } from '@immich/sdk'; import type { PageLoad } from './$types'; export const load = (async ({ url }) => { await authenticate(url); - const keys = await getApiKeys(); const sessions = await getSessions(); const $t = await getFormatter(); return { - keys, sessions, meta: { title: $t('settings'), diff --git a/web/src/routes/(user)/user-settings/+page.svelte b/web/src/routes/(user)/user-settings/+page.svelte index bf4f5b00f1..e69de29bb2 100644 --- a/web/src/routes/(user)/user-settings/+page.svelte +++ b/web/src/routes/(user)/user-settings/+page.svelte @@ -1,22 +0,0 @@ - - - - - - - diff --git a/web/src/routes/(user)/user-settings/new-api-key/+page.svelte b/web/src/routes/(user)/user-settings/new-api-key/+page.svelte new file mode 100644 index 0000000000..cb8766ce2d --- /dev/null +++ b/web/src/routes/(user)/user-settings/new-api-key/+page.svelte @@ -0,0 +1,55 @@ + + +{#if !secret} + +
+ + + +
+ +
+{:else} + +{/if} diff --git a/web/src/routes/(user)/user-settings/new-api-key/+page.ts b/web/src/routes/(user)/user-settings/new-api-key/+page.ts new file mode 100644 index 0000000000..7d9569bbe0 --- /dev/null +++ b/web/src/routes/(user)/user-settings/new-api-key/+page.ts @@ -0,0 +1,14 @@ +import { authenticate } from '$lib/utils/auth'; +import { getFormatter } from '$lib/utils/i18n'; +import type { PageLoad } from './$types'; + +export const load = (async ({ url }) => { + await authenticate(url); + const $t = await getFormatter(); + + return { + meta: { + title: $t('settings'), + }, + }; +}) satisfies PageLoad;