diff --git a/e2e/package.json b/e2e/package.json index 3dd18192a8..0272fa57b2 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -26,7 +26,7 @@ "devDependencies": { "@eslint/js": "^10.0.0", "@faker-js/faker": "^10.1.0", - "@futo-org/backups-orchestrator-ui": "0.22.1", + "@futo-org/backups-orchestrator-ui": "0.28.0", "@immich/cli": "workspace:*", "@immich/e2e-auth-server": "workspace:*", "@immich/sdk": "workspace:*", diff --git a/e2e/src/specs/maintenance/web/yucca-backups.e2e-spec.ts b/e2e/src/specs/maintenance/web/yucca-backups.e2e-spec.ts index 54ebef7913..fc5ada8afc 100644 --- a/e2e/src/specs/maintenance/web/yucca-backups.e2e-spec.ts +++ b/e2e/src/specs/maintenance/web/yucca-backups.e2e-spec.ts @@ -60,7 +60,7 @@ test.describe('Yucca Backups', () => { test.setTimeout(30_000); await utils.setAuthCookies(context, admin.accessToken); - await page.goto('/backups'); + await page.goto('/admin/backups'); const dialog = page.getByRole('dialog'); await expect(dialog.filter({ hasText: 'Backup options' })).toBeVisible(); @@ -81,7 +81,7 @@ test.describe('Yucca Backups', () => { test.setTimeout(60_000); await utils.setAuthCookies(context, admin.accessToken); - await page.goto('/backups/repositories'); + await page.goto('/admin/backups/repositories'); const backupNow = page.getByRole('button', { name: 'Backup Now' }); await expect(backupNow).toBeVisible(); diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index bb4fbaa0e2..c72754de50 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -19608,6 +19608,9 @@ "name": { "type": "string" }, + "paused": { + "type": "boolean" + }, "retentionPolicy": { "allOf": [ { @@ -20639,12 +20642,20 @@ "name": { "type": "string" }, + "siteCode": { + "nullable": true, + "type": "string" + }, "snapshots": { "items": { "$ref": "#/components/schemas/SnapshotDto" }, "type": "array" }, + "storageClusterCode": { + "nullable": true, + "type": "string" + }, "worm": { "type": "boolean" } @@ -20653,7 +20664,9 @@ "id", "metrics", "name", + "siteCode", "snapshots", + "storageClusterCode", "worm" ], "type": "object" @@ -21001,6 +21014,14 @@ "name": { "type": "string" }, + "siteCode": { + "nullable": true, + "type": "string" + }, + "storageClusterCode": { + "nullable": true, + "type": "string" + }, "worm": { "type": "boolean" } @@ -21009,6 +21030,8 @@ "id", "metrics", "name", + "siteCode", + "storageClusterCode", "worm" ], "type": "object" @@ -23798,6 +23821,10 @@ }, "type": "array" }, + "site": { + "description": "Internal site code from environment metadata", + "type": "string" + }, "worm": { "type": "boolean" } @@ -23943,6 +23970,9 @@ ], "nullable": true, "type": "object" + }, + "worm": { + "type": "boolean" } }, "type": "object" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6059701734..58958cbc8c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -112,8 +112,8 @@ importers: specifier: ^10.1.0 version: 10.5.0 '@futo-org/backups-orchestrator-ui': - specifier: 0.22.1 - version: 0.22.1(svelte@5.56.5(@typescript-eslint/types@8.64.0)) + specifier: 0.28.0 + version: 0.28.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0)) '@immich/cli': specifier: workspace:* version: link:../packages/cli @@ -404,8 +404,8 @@ importers: specifier: 2.0.0-rc13 version: 2.0.0-rc13 '@futo-org/backups-orchestrator-api': - specifier: 0.22.1 - version: 0.22.1(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(@nestjs/platform-socket.io@11.1.28)(@nestjs/schedule@6.1.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28))(@nestjs/websockets@11.1.28)(reflect-metadata@0.2.2) + specifier: 0.28.0 + version: 0.28.0(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(@nestjs/platform-socket.io@11.1.28)(@nestjs/schedule@6.1.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28))(@nestjs/swagger@11.4.5(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(@typescript/typescript6@6.0.2)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2))(@nestjs/websockets@11.1.28)(reflect-metadata@0.2.2) '@immich/plugin-sdk': specifier: workspace:* version: link:../packages/plugin-sdk @@ -787,7 +787,7 @@ importers: version: 1.5.9(@swc/core@1.15.43(@swc/helpers@0.5.23))(rollup@4.62.0) vite-tsconfig-paths: specifier: ^6.0.0 - version: 6.1.1(@typescript/typescript6@6.0.2)(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@1.21.7)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)) + version: 6.1.1(@typescript/typescript6@6.0.2)(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)) vitest: specifier: ^3.0.0 version: 3.2.7(@types/debug@4.1.13)(@types/node@24.13.3)(happy-dom@20.10.6)(jiti@1.21.7)(jsdom@26.1.0(canvas@3.2.3))(lightningcss@1.33.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0) @@ -798,8 +798,8 @@ importers: specifier: ^3.0.0 version: 3.5.15 '@futo-org/backups-orchestrator-ui': - specifier: 0.22.1 - version: 0.22.1(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0)) + specifier: 0.28.0 + version: 0.28.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0)) '@immich/justified-layout-wasm': specifier: ^0.4.3 version: 0.4.3 @@ -807,8 +807,8 @@ importers: specifier: workspace:* version: link:../packages/sdk '@immich/ui': - specifier: ^0.83.0 - version: 0.83.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0)) + specifier: ^0.85.0 + version: 0.85.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0)) '@mapbox/mapbox-gl-rtl-text': specifier: 0.4.0 version: 0.4.0 @@ -2907,20 +2907,21 @@ packages: resolution: {integrity: sha512-YTVITFGN0/24PxzXrwqCgnyd7njDuzp5ZvaCx5nq/jg55kUYd94Nj8UTchBdBofi/L0nwRfjGOg0E41d2u9T1w==} engines: {node: '>=6'} - '@futo-org/backups-api-client@0.22.1': - resolution: {integrity: sha512-8w1kLyV2gPADGMjrpLvK1IIo7SQLz0TQZ/KoGojnT3Txzj7Im2CPlKsjXM/f9CrYo2czFIy2iWImq/Yi0iOyGw==} + '@futo-org/backups-api-client@0.28.0': + resolution: {integrity: sha512-YWu1LJpYa3cmJTXnEN8GuVbPTyEKjP1x2QMyYvpMwG+X0Mje2t4mlTwXUOhnBo3tp7PN/GG4v6lBxOTGohGllA==} - '@futo-org/backups-orchestrator-api@0.22.1': - resolution: {integrity: sha512-+/3z+uUkx8oQMHv4PlRWiAWhp33YExJjhQeVEVYgwb5kkltJMIEcXamckWxr7r/t5eRCXqbvGvqr67Bu7XD78w==} + '@futo-org/backups-orchestrator-api@0.28.0': + resolution: {integrity: sha512-Zrk7LtOBDVauLX2kBGnVc+2+tC2cT4Rh6psiiM/evZJXYlMF3NUljIGWPKCLPmkTYctl5zYVRZ43LLRVWryDNQ==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 '@nestjs/platform-socket.io': ^11.0.0 '@nestjs/schedule': ^6.0.0 + '@nestjs/swagger': ^11.0.0 '@nestjs/websockets': ^11.0.0 - '@futo-org/backups-orchestrator-ui@0.22.1': - resolution: {integrity: sha512-8wmjcVSQBKzKT/64sVu2Ih6ro34px+hLCuGZSArewCRolbguSfKsY6m8rAqcBnhCYmVoE6G0zxqLPHWLZqV91w==} + '@futo-org/backups-orchestrator-ui@0.28.0': + resolution: {integrity: sha512-f1ZvypMrbo84oXSsQ39G+bbYbhs4VIMXRQJVztvq7eXESwPGk5GA3DNArhhssDQe1uxnmeWRuE+T9iInSGBW1g==} peerDependencies: svelte: ^5.0.0 @@ -3140,18 +3141,8 @@ packages: resolution: {integrity: sha512-O1SJ+BbeFVsUTF4af1MfagJZM+lPgLjI8lQ3SZNjpo8SGJReSbUl2ii03OKuGni/G0yp2GnRLpOTNSHYGtVrcg==} hasBin: true - '@immich/svelte-markdown-preprocess@0.1.0': - resolution: {integrity: sha512-jgSOJEGLPKEXQCNRI4r4YUayeM2b0ZYLdzgKGl891jZBhOQIetlY7rU44kPpV1AA3/8wGDwNFKduIQZZ/qJYzg==} - peerDependencies: - svelte: ^5.0.0 - - '@immich/ui@0.59.0': - resolution: {integrity: sha512-7yxvyhhd99T0AHhjMakp7c/U4n0jGAmRO5xpncsRASRvqZve/LAibjr6N5FJc5IAd222DROTMLn6imsxVfqfvg==} - peerDependencies: - svelte: ^5.0.0 - - '@immich/ui@0.83.0': - resolution: {integrity: sha512-Xh3R3yhn8/Qyq8lGWIiVmturA+dHXtmW/h++AGb2UAwS/58qu7ssocO/HWIamaSpkgjPGotlWpPIpUJq1zh9FQ==} + '@immich/ui@0.85.0': + resolution: {integrity: sha512-KCAEtVGexZ1G+nuT25bv1QS6Rc2wOlLymp4qDBZVqMxu3o3RWpUzafRHvZt5g4FnlAgfHZdXAIHVVrhJzkrlDA==} peerDependencies: '@sveltejs/kit': ^2.13.0 svelte: ^5.0.0 @@ -6872,6 +6863,7 @@ packages: cron-parser@4.9.0: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} + deprecated: v4 is no longer maintained, upgrade to v5 cron-validate@1.5.3: resolution: {integrity: sha512-jcu8g/3wZL8OBr4MkEcbeIdLpM8pp5Y6UoOlRktcJG3WjgpifijR0s26Yac7ywR0gC2ABtevOsz5mlD3l3gzwA==} @@ -8108,6 +8100,10 @@ packages: resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} engines: {node: '>=18'} + fuse.js@7.5.0: + resolution: {integrity: sha512-sQtrEfA+ez/3G0cCZecF70oqpCRttCexYUG4mUrtWL49ULUzUyxokt5kyqwtKzj1270RaKih+hcP3qLcumccow==} + engines: {node: '>=10'} + gauge@3.0.2: resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} engines: {node: '>=10'} @@ -15974,19 +15970,20 @@ snapshots: dependencies: '@fortawesome/fontawesome-common-types': 7.2.0 - '@futo-org/backups-api-client@0.22.1': + '@futo-org/backups-api-client@0.28.0': dependencies: '@oazapfts/runtime': 1.2.0 - '@futo-org/backups-orchestrator-api@0.22.1(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(@nestjs/platform-socket.io@11.1.28)(@nestjs/schedule@6.1.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28))(@nestjs/websockets@11.1.28)(reflect-metadata@0.2.2)': + '@futo-org/backups-orchestrator-api@0.28.0(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(@nestjs/platform-socket.io@11.1.28)(@nestjs/schedule@6.1.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28))(@nestjs/swagger@11.4.5(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(@typescript/typescript6@6.0.2)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2))(@nestjs/websockets@11.1.28)(reflect-metadata@0.2.2)': dependencies: - '@futo-org/backups-api-client': 0.22.1 + '@futo-org/backups-api-client': 0.28.0 '@futo-org/restic-wrapper': 1.3.1 '@nestjs/common': 11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.28)(@nestjs/websockets@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/event-emitter': 3.1.0(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28) '@nestjs/platform-socket.io': 11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.28)(rxjs@7.8.2) '@nestjs/schedule': 6.1.3(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28) + '@nestjs/swagger': 11.4.5(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(@typescript/typescript6@6.0.2)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) '@nestjs/websockets': 11.1.28(@nestjs/common@11.1.28(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.28)(@nestjs/platform-socket.io@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2) better-sqlite3: 12.9.0 class-validator: 0.14.4 @@ -16001,35 +15998,17 @@ snapshots: rxjs: 7.8.2 socket.io: 4.8.3 tail: 2.2.6 + zod: 4.3.6 transitivePeerDependencies: - bufferutil - reflect-metadata - supports-color - utf-8-validate - '@futo-org/backups-orchestrator-ui@0.22.1(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0))': + '@futo-org/backups-orchestrator-ui@0.28.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0))': dependencies: - '@futo-org/backups-api-client': 0.22.1 - '@immich/ui': 0.59.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0)) - '@mdi/js': 7.4.47 - '@oazapfts/runtime': 1.2.0 - '@tanstack/svelte-query': 6.1.28(svelte@5.56.5(@typescript-eslint/types@8.64.0)) - cron-validate: 1.5.3 - cronstrue: 3.14.0 - lodash.debounce: 4.0.8 - luxon: 3.7.2 - socket.io-client: 4.8.3 - svelte: 5.56.5(@typescript-eslint/types@8.64.0) - transitivePeerDependencies: - - '@sveltejs/kit' - - bufferutil - - supports-color - - utf-8-validate - - '@futo-org/backups-orchestrator-ui@0.22.1(svelte@5.56.5(@typescript-eslint/types@8.64.0))': - dependencies: - '@futo-org/backups-api-client': 0.22.1 - '@immich/ui': 0.59.0(svelte@5.56.5(@typescript-eslint/types@8.64.0)) + '@futo-org/backups-api-client': 0.28.0 + '@immich/ui': 0.85.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0)) '@mdi/js': 7.4.47 '@oazapfts/runtime': 1.2.0 '@tanstack/svelte-query': 6.1.28(svelte@5.56.5(@typescript-eslint/types@8.64.0)) @@ -16211,48 +16190,13 @@ snapshots: pg-connection-string: 2.14.0 postgres: 3.4.9 - '@immich/svelte-markdown-preprocess@0.1.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))': - dependencies: - svelte: 5.56.5(@typescript-eslint/types@8.64.0) - - '@immich/ui@0.59.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0))': - dependencies: - '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.56.5(@typescript-eslint/types@8.64.0)) - '@internationalized/date': 3.12.2 - '@mdi/js': 7.4.47 - bits-ui: 2.18.1(@internationalized/date@3.12.2)(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0)) - luxon: 3.7.2 - simple-icons: 16.26.0 - svelte: 5.56.5(@typescript-eslint/types@8.64.0) - svelte-highlight: 7.11.0 - tailwind-merge: 3.6.0 - tailwind-variants: 3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.2) - tailwindcss: 4.3.2 - transitivePeerDependencies: - - '@sveltejs/kit' - - '@immich/ui@0.59.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))': - dependencies: - '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.56.5(@typescript-eslint/types@8.64.0)) - '@internationalized/date': 3.12.2 - '@mdi/js': 7.4.47 - bits-ui: 2.18.1(@internationalized/date@3.12.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0)) - luxon: 3.7.2 - simple-icons: 16.26.0 - svelte: 5.56.5(@typescript-eslint/types@8.64.0) - svelte-highlight: 7.11.0 - tailwind-merge: 3.6.0 - tailwind-variants: 3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.2) - tailwindcss: 4.3.2 - transitivePeerDependencies: - - '@sveltejs/kit' - - '@immich/ui@0.83.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0))': + '@immich/ui@0.85.0(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0))': dependencies: '@internationalized/date': 3.12.2 '@mdi/js': 7.4.47 '@sveltejs/kit': 2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)) bits-ui: 2.18.1(@internationalized/date@3.12.2)(@sveltejs/kit@2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(svelte@5.56.5(@typescript-eslint/types@8.64.0)) + fuse.js: 7.5.0 luxon: 3.7.2 simple-icons: 16.26.0 svelte: 5.56.5(@typescript-eslint/types@8.64.0) @@ -19569,19 +19513,6 @@ snapshots: transitivePeerDependencies: - '@sveltejs/kit' - bits-ui@2.18.1(@internationalized/date@3.12.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0)): - dependencies: - '@floating-ui/core': 1.7.5 - '@floating-ui/dom': 1.7.6 - '@internationalized/date': 3.12.2 - esm-env: 1.2.2 - runed: 0.35.1(svelte@5.56.5(@typescript-eslint/types@8.64.0)) - svelte: 5.56.5(@typescript-eslint/types@8.64.0) - svelte-toolbelt: 0.10.6(svelte@5.56.5(@typescript-eslint/types@8.64.0)) - tabbable: 6.5.0 - transitivePeerDependencies: - - '@sveltejs/kit' - bl@4.1.0: dependencies: buffer: 5.7.1 @@ -21744,6 +21675,8 @@ snapshots: function-timeout@1.0.2: {} + fuse.js@7.5.0: {} + gauge@3.0.2: dependencies: aproba: 2.1.0 @@ -25569,13 +25502,6 @@ snapshots: optionalDependencies: '@sveltejs/kit': 2.69.3(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)))(@typescript/typescript6@6.0.2)(svelte@5.56.5(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)) - runed@0.35.1(svelte@5.56.5(@typescript-eslint/types@8.64.0)): - dependencies: - dequal: 2.0.3 - esm-env: 1.2.2 - lz-string: 1.5.0 - svelte: 5.56.5(@typescript-eslint/types@8.64.0) - rw@1.3.3: {} rxjs@7.8.1: @@ -26279,15 +26205,6 @@ snapshots: transitivePeerDependencies: - '@sveltejs/kit' - svelte-toolbelt@0.10.6(svelte@5.56.5(@typescript-eslint/types@8.64.0)): - dependencies: - clsx: 2.1.1 - runed: 0.35.1(svelte@5.56.5(@typescript-eslint/types@8.64.0)) - style-to-object: 1.0.14 - svelte: 5.56.5(@typescript-eslint/types@8.64.0) - transitivePeerDependencies: - - '@sveltejs/kit' - svelte@5.56.5(@typescript-eslint/types@8.64.0): dependencies: '@jridgewell/remapping': 2.3.5 @@ -27058,12 +26975,12 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@6.1.1(@typescript/typescript6@6.0.2)(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@1.21.7)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)): + vite-tsconfig-paths@6.1.1(@typescript/typescript6@6.0.2)(vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(@typescript/typescript6@6.0.2) - vite: 8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@1.21.7)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0) transitivePeerDependencies: - supports-color - typescript @@ -27086,23 +27003,6 @@ snapshots: tsx: 4.23.1 yaml: 2.9.0 - vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@1.21.7)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0): - dependencies: - lightningcss: 1.33.0 - picomatch: 4.0.5 - postcss: 8.5.19 - rolldown: 1.1.5 - tinyglobby: 0.2.17 - optionalDependencies: - '@types/node': 24.13.3 - esbuild: 0.28.1 - fsevents: 2.3.3 - jiti: 1.21.7 - sass: 1.101.0 - terser: 5.49.0 - tsx: 4.23.1 - yaml: 2.9.0 - vite@8.1.5(@types/node@24.13.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.101.0)(terser@5.49.0)(tsx@4.23.1)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 diff --git a/server/package.json b/server/package.json index 38cd405e2b..32e2d3a15c 100644 --- a/server/package.json +++ b/server/package.json @@ -37,7 +37,7 @@ }, "dependencies": { "@extism/extism": "2.0.0-rc13", - "@futo-org/backups-orchestrator-api": "0.22.1", + "@futo-org/backups-orchestrator-api": "0.28.0", "@immich/plugin-sdk": "workspace:*", "@immich/sql-tools": "^0.5.1", "@nestjs/bullmq": "^11.0.1", diff --git a/web/package.json b/web/package.json index cbd427272f..13bd883f6b 100644 --- a/web/package.json +++ b/web/package.json @@ -25,10 +25,10 @@ }, "dependencies": { "@formatjs/icu-messageformat-parser": "^3.0.0", - "@futo-org/backups-orchestrator-ui": "0.22.1", + "@futo-org/backups-orchestrator-ui": "0.28.0", "@immich/justified-layout-wasm": "^0.4.3", "@immich/sdk": "workspace:*", - "@immich/ui": "^0.83.0", + "@immich/ui": "^0.85.0", "@mapbox/mapbox-gl-rtl-text": "0.4.0", "@mdi/js": "^7.4.47", "@noble/hashes": "^2.2.0", diff --git a/web/src/lib/components/layouts/AdminPageLayout.svelte b/web/src/lib/components/layouts/AdminPageLayout.svelte index 7d2003f225..5c97857528 100644 --- a/web/src/lib/components/layouts/AdminPageLayout.svelte +++ b/web/src/lib/components/layouts/AdminPageLayout.svelte @@ -2,16 +2,25 @@ import BreadcrumbActionPage from '$lib/components/BreadcrumbActionPage.svelte'; import NavigationBar from '$lib/components/shared-components/navigation-bar/NavigationBar.svelte'; import BottomInfo from '$lib/components/shared-components/side-bar/BottomInfo.svelte'; + import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte'; import { Route } from '$lib/route'; import { sidebarStore } from '$lib/stores/sidebar.svelte'; import type { HeaderButtonActionItem } from '$lib/types'; import { AppShell, AppShellHeader, AppShellSidebar, MenuItemType, NavbarItem, type BreadcrumbItem } from '@immich/ui'; - import { mdiAccountMultipleOutline, mdiBookshelf, mdiCog, mdiServer, mdiTrayFull, mdiWrench } from '@mdi/js'; + import { + mdiAccountMultipleOutline, + mdiBookshelf, + mdiCloudUploadOutline, + mdiCog, + mdiServer, + mdiTrayFull, + mdiWrench, + } from '@mdi/js'; import type { Snippet } from 'svelte'; import { t } from 'svelte-i18n'; type Props = { - breadcrumbs: BreadcrumbItem[]; + breadcrumbs?: BreadcrumbItem[]; actions?: Array; children?: Snippet; }; @@ -28,6 +37,9 @@ class="flex h-full flex-col justify-between gap-2 border-none shadow-none" >
+ {#if featureFlagsManager.value.backups} + + {/if} @@ -41,7 +53,13 @@
- - {@render children?.()} - + {#if breadcrumbs} + + {@render children?.()} + + {:else} +
+ {@render children?.()} +
+ {/if} diff --git a/web/src/lib/components/shared-components/side-bar/UserSidebar.svelte b/web/src/lib/components/shared-components/side-bar/UserSidebar.svelte index 31247ed0cf..a01b4533fc 100644 --- a/web/src/lib/components/shared-components/side-bar/UserSidebar.svelte +++ b/web/src/lib/components/shared-components/side-bar/UserSidebar.svelte @@ -14,7 +14,6 @@ mdiAccountOutline, mdiArchiveArrowDown, mdiArchiveArrowDownOutline, - mdiBackupRestore, mdiFolderOutline, mdiHeart, mdiHeartOutline, @@ -97,10 +96,6 @@ {/if} - {#if featureFlagsManager.value.backups && authManager.user.isAdmin} - - {/if} - `/workflows/${id}`, // backups - backups: () => '/backups', + backups: () => '/admin/backups', // queues queues: () => '/admin/queues', diff --git a/web/src/routes/(user)/backups/+page.svelte b/web/src/routes/(user)/backups/+page.svelte deleted file mode 100644 index 799f5e2c62..0000000000 --- a/web/src/routes/(user)/backups/+page.svelte +++ /dev/null @@ -1,31 +0,0 @@ - - - - {data.meta.title} - - - - - goto('/')} /> - - diff --git a/web/src/routes/admin/backups/+page.svelte b/web/src/routes/admin/backups/+page.svelte new file mode 100644 index 0000000000..ab7bf55090 --- /dev/null +++ b/web/src/routes/admin/backups/+page.svelte @@ -0,0 +1,42 @@ + + + + + + + diff --git a/web/src/routes/(user)/backups/+page.ts b/web/src/routes/admin/backups/+page.ts similarity index 83% rename from web/src/routes/(user)/backups/+page.ts rename to web/src/routes/admin/backups/+page.ts index d42f20a32f..18e4c39375 100644 --- a/web/src/routes/(user)/backups/+page.ts +++ b/web/src/routes/admin/backups/+page.ts @@ -2,7 +2,7 @@ import { authenticate } from '$lib/utils/auth'; import type { PageLoad } from './$types'; export const load = (async ({ url }) => { - await authenticate(url); + await authenticate(url, { admin: true }); return { meta: { diff --git a/web/src/routes/maintenance/+page.svelte b/web/src/routes/maintenance/+page.svelte index b58ede7e84..52a4be17c1 100644 --- a/web/src/routes/maintenance/+page.svelte +++ b/web/src/routes/maintenance/+page.svelte @@ -7,7 +7,7 @@ import { maintenanceStore } from '$lib/stores/maintenance.store'; import { MaintenanceAction } from '@immich/sdk'; import { Button, Heading, Link, ProgressBar, Scrollable, Text } from '@immich/ui'; - import { YuccaContext, ViewLogModal } from '@futo-org/backups-orchestrator-ui'; + import { YuccaContext, ViewStatusModal } from '@futo-org/backups-orchestrator-ui'; import { t } from 'svelte-i18n'; import type { PageData } from './$types'; @@ -44,7 +44,7 @@ ); - + {$t('maintenance_task_rollback')} {/if} {/if} - {:else if $status?.action === MaintenanceAction.Rollback} - void 0} /> + {:else if $status?.action === MaintenanceAction.Rollback && $status.yuccaLogId} + void 0} /> {:else if $status?.action === MaintenanceAction.SelectDatabaseRestore && $auth} {:else}