diff --git a/e2e/package.json b/e2e/package.json
index 3eed01b368..2fe3230dd7 100644
--- a/e2e/package.json
+++ b/e2e/package.json
@@ -44,7 +44,7 @@
"exiftool-vendored": "^35.0.0",
"globals": "^17.0.0",
"luxon": "^3.4.4",
- "orchestration-ui": "0.1.68",
+ "orchestration-ui": "0.1.69",
"pg": "^8.11.3",
"pngjs": "^7.0.0",
"prettier": "^3.7.4",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index cc0c8b5323..3af3390e01 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -253,8 +253,8 @@ importers:
specifier: ^3.4.4
version: 3.7.2
orchestration-ui:
- specifier: 0.1.68
- version: 0.1.68(svelte@5.55.1)
+ specifier: 0.1.69
+ version: 0.1.69(svelte@5.55.1)
pg:
specifier: ^8.11.3
version: 8.20.0
@@ -524,8 +524,8 @@ importers:
specifier: ^6.3.3
version: 6.8.2
orchestration-api:
- specifier: 0.1.68
- version: 0.1.68(@nestjs/platform-express@11.1.17)(class-transformer@0.5.1)(reflect-metadata@0.2.2)
+ specifier: 0.1.69
+ version: 0.1.69(@nestjs/platform-express@11.1.17)(class-transformer@0.5.1)(reflect-metadata@0.2.2)
pg:
specifier: ^8.11.3
version: 8.20.0
@@ -819,8 +819,8 @@ importers:
specifier: ^5.6.2
version: 5.21.0
orchestration-ui:
- specifier: 0.1.68
- version: 0.1.68(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)
+ specifier: 0.1.69
+ version: 0.1.69(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)
pmtiles:
specifier: ^4.3.0
version: 4.4.0
@@ -9687,11 +9687,11 @@ packages:
resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==}
engines: {node: '>=18'}
- orchestration-api@0.1.68:
- resolution: {integrity: sha512-AU0fBmsR+0ykyxnp22fjheF4Q6SWHyEw6/mk0OJos7xrZlxSJnb+DzzXjSiNm4fCyfODTCkSTWfHRnsPbxqQgA==}
+ orchestration-api@0.1.69:
+ resolution: {integrity: sha512-e178p+yfWV26RHNIKrGY8cnl0LgtbEal0BJhTdRTDrJy+bLjDw+MqzaVMYzMjCkAECML37dwAZjTR/qIwRfSwA==}
- orchestration-ui@0.1.68:
- resolution: {integrity: sha512-DFf7zYlWpvIxdfOtKiN+nhkpzKGXpGRLwls6erSuc1ZvAiZW6bc2+5lLktjBWi+ZRfl166Wkbb4c6a3eIiP2Dg==}
+ orchestration-ui@0.1.69:
+ resolution: {integrity: sha512-l7e8Xgf24rD1KblsdtcODBIk2UY1b/hSwry1tHEB/mpkZ+MUu4feXswa1+aSztP6WIP5RXk8CH4PHS/z5MFJmg==}
peerDependencies:
svelte: ^5.0.0
@@ -12651,8 +12651,8 @@ packages:
resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==}
engines: {node: '>=18'}
- yucca-api-client@0.1.68:
- resolution: {integrity: sha512-1FCFPa4dZ3wr5n+rpb0+rfCm4u9JSko4nXe3b/zYd/XWHzvLZteEYF3W8iO1LevJHgquEo9ZFkH8h/RU5TFKIg==}
+ yucca-api-client@0.1.69:
+ resolution: {integrity: sha512-GXRnvpTi7p8X+6R3E0ypBY+j7q5MrQQgH6bSi4ppB/h729VD6aAkwXLSK64i29Ge4jfyrQ4HymgQSwFd7avc8g==}
yup@1.7.1:
resolution: {integrity: sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==}
@@ -23027,7 +23027,7 @@ snapshots:
string-width: 7.2.0
strip-ansi: 7.2.0
- orchestration-api@0.1.68(@nestjs/platform-express@11.1.17)(class-transformer@0.5.1)(reflect-metadata@0.2.2):
+ orchestration-api@0.1.69(@nestjs/platform-express@11.1.17)(class-transformer@0.5.1)(reflect-metadata@0.2.2):
dependencies:
'@futo-org/restic-wrapper': 1.2.0
'@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
@@ -23049,7 +23049,7 @@ snapshots:
rxjs: 7.8.2
socket.io: 4.8.3
tail: 2.2.6
- yucca-api-client: 0.1.68
+ yucca-api-client: 0.1.69
transitivePeerDependencies:
- '@nestjs/microservices'
- '@nestjs/platform-express'
@@ -23059,7 +23059,7 @@ snapshots:
- supports-color
- utf-8-validate
- orchestration-ui@0.1.68(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1):
+ orchestration-ui@0.1.69(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1):
dependencies:
'@immich/ui': 0.59.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)
'@mdi/js': 7.4.47
@@ -23071,14 +23071,14 @@ snapshots:
luxon: 3.7.2
socket.io-client: 4.8.3
svelte: 5.55.1
- yucca-api-client: 0.1.68
+ yucca-api-client: 0.1.69
transitivePeerDependencies:
- '@sveltejs/kit'
- bufferutil
- supports-color
- utf-8-validate
- orchestration-ui@0.1.68(svelte@5.55.1):
+ orchestration-ui@0.1.69(svelte@5.55.1):
dependencies:
'@immich/ui': 0.59.0(svelte@5.55.1)
'@mdi/js': 7.4.47
@@ -23090,7 +23090,7 @@ snapshots:
luxon: 3.7.2
socket.io-client: 4.8.3
svelte: 5.55.1
- yucca-api-client: 0.1.68
+ yucca-api-client: 0.1.69
transitivePeerDependencies:
- '@sveltejs/kit'
- bufferutil
@@ -26613,7 +26613,7 @@ snapshots:
yoctocolors@2.1.2: {}
- yucca-api-client@0.1.68:
+ yucca-api-client@0.1.69:
dependencies:
'@oazapfts/runtime': 1.2.0
diff --git a/server/package.json b/server/package.json
index 5d7d503657..f8f624c581 100644
--- a/server/package.json
+++ b/server/package.json
@@ -99,7 +99,7 @@
"nestjs-zod": "^5.3.0",
"nodemailer": "^8.0.0",
"openid-client": "^6.3.3",
- "orchestration-api": "0.1.68",
+ "orchestration-api": "0.1.69",
"pg": "^8.11.3",
"pg-connection-string": "^2.9.1",
"picomatch": "^4.0.2",
diff --git a/server/src/app.module.ts b/server/src/app.module.ts
index 9d33fb3f0a..719650bcaa 100644
--- a/server/src/app.module.ts
+++ b/server/src/app.module.ts
@@ -10,7 +10,7 @@ import { OrchestrationApiModule } from 'orchestration-api/dist';
import { commandsAndQuestions } from 'src/commands';
import { IWorker } from 'src/constants';
import { controllers } from 'src/controllers';
-import { ImmichEnvironment, ImmichWorker } from 'src/enum';
+import { ImmichWorker } from 'src/enum';
import { MaintenanceAuthGuard } from 'src/maintenance/maintenance-auth.guard';
import { MaintenanceHealthRepository } from 'src/maintenance/maintenance-health.repository';
import { MaintenanceWebsocketRepository } from 'src/maintenance/maintenance-websocket.repository';
@@ -60,9 +60,9 @@ const apiMiddleware = [
];
const configRepository = new ConfigRepository();
-const { bull, cls, database, environment, otel } = configRepository.getEnv();
-const isYuccaDevelopmentMode =
- environment === ImmichEnvironment.Development || environment === ImmichEnvironment.Testing;
+const { bull, cls, database, otel } = configRepository.getEnv();
+// TODO-DEV
+const isYuccaDevelopmentMode = true;
const commonImports = [
ClsModule.forRoot(cls.config),
diff --git a/web/package.json b/web/package.json
index aa0aaa4176..8044cf98e1 100644
--- a/web/package.json
+++ b/web/package.json
@@ -51,7 +51,7 @@
"lodash-es": "^4.17.21",
"luxon": "^3.4.4",
"maplibre-gl": "^5.6.2",
- "orchestration-ui": "0.1.68",
+ "orchestration-ui": "0.1.69",
"pmtiles": "^4.3.0",
"qrcode": "^1.5.4",
"simple-icons": "^16.0.0",
diff --git a/web/src/lib/components/shared-components/navigation-bar/navigation-bar.svelte b/web/src/lib/components/shared-components/navigation-bar/navigation-bar.svelte
index 4ec153ad23..4a169d4127 100644
--- a/web/src/lib/components/shared-components/navigation-bar/navigation-bar.svelte
+++ b/web/src/lib/components/shared-components/navigation-bar/navigation-bar.svelte
@@ -12,11 +12,22 @@
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
import { Route } from '$lib/route';
import { getGlobalActions } from '$lib/services/app.service';
+ import { handleSetMaintenanceMode } from '$lib/services/maintenance.service';
import { mediaQueryManager } from '$lib/stores/media-query-manager.svelte';
import { notificationManager } from '$lib/stores/notification-manager.svelte';
import { sidebarStore } from '$lib/stores/sidebar.svelte';
+ import { MaintenanceAction } from '@immich/sdk';
import { ActionButton, Button, IconButton, Logo } from '@immich/ui';
- import { mdiBellBadge, mdiBellOutline, mdiMagnify, mdiMenu, mdiTrayArrowUp } from '@mdi/js';
+ import {
+ mdiBellBadge,
+ mdiBellOutline,
+ mdiDeleteSweep,
+ mdiMagnify,
+ mdiMenu,
+ mdiProgressWrench,
+ mdiTrayArrowUp,
+ } from '@mdi/js';
+ import { sdk } from 'orchestration-ui';
import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
import ThemeButton from '../theme-button.svelte';
@@ -102,6 +113,55 @@
/>
{/if}
+
+ {#if authManager.user.isAdmin}
+
+