From 998d82643cd628d4920d2e2768e48c6d0bf75438 Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 8 May 2026 12:30:04 +0100 Subject: [PATCH] chore: new UI --- e2e/package.json | 2 +- open-api/immich-openapi-specs.json | 166 +++++++++++++++--- pnpm-lock.yaml | 57 +++--- server/package.json | 2 +- web/package.json | 2 +- web/src/routes/(user)/backups/+page.svelte | 25 +++ web/src/routes/{ => (user)}/backups/+page.ts | 5 +- web/src/routes/backups/+layout.svelte | 44 ----- web/src/routes/backups/+layout.ts | 6 - web/src/routes/backups/+page.svelte | 13 -- web/src/routes/backups/config/+page.svelte | 5 - .../routes/backups/repositories/+page.svelte | 5 - web/src/routes/backups/schedules/+page.svelte | 5 - 13 files changed, 208 insertions(+), 129 deletions(-) create mode 100644 web/src/routes/(user)/backups/+page.svelte rename web/src/routes/{ => (user)}/backups/+page.ts (51%) delete mode 100644 web/src/routes/backups/+layout.svelte delete mode 100644 web/src/routes/backups/+layout.ts delete mode 100644 web/src/routes/backups/+page.svelte delete mode 100644 web/src/routes/backups/config/+page.svelte delete mode 100644 web/src/routes/backups/repositories/+page.svelte delete mode 100644 web/src/routes/backups/schedules/+page.svelte diff --git a/e2e/package.json b/e2e/package.json index 7025b58fdf..3eed01b368 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.63", + "orchestration-ui": "0.1.68", "pg": "^8.11.3", "pngjs": "^7.0.0", "prettier": "^3.7.4", diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 103fd87a74..e6940864ac 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -15329,35 +15329,19 @@ "x-immich-state": "Alpha" } }, - "/yucca/auth/oidc/callback": { + "/yucca/auth/oidc/device": { "get": { - "operationId": "oidcCallback", + "operationId": "oidcDeviceFlow", "parameters": [], "responses": { "200": { - "description": "" - } - }, - "tags": [ - "Auth" - ] - } - }, - "/yucca/auth/oidc/login": { - "get": { - "operationId": "oidcAuthorize", - "parameters": [ - { - "name": "next", - "required": true, - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceFlowResponseDto" + } + } + }, "description": "" } }, @@ -15508,6 +15492,36 @@ } }, "/yucca/logs/{id}": { + "get": { + "operationId": "getRun", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "RunHistory" + ] + } + }, + "/yucca/logs/{id}/stream": { "get": { "operationId": "logStreamSse", "parameters": [ @@ -15701,6 +15715,27 @@ } }, "/yucca/repository/{id}": { + "delete": { + "operationId": "deleteRepository", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Repository" + ] + }, "patch": { "operationId": "updateRepository", "parameters": [ @@ -18768,6 +18803,21 @@ }, "type": "object" }, + "DeviceFlowResponseDto": { + "properties": { + "userCode": { + "type": "string" + }, + "verificationUri": { + "type": "string" + } + }, + "required": [ + "userCode", + "verificationUri" + ], + "type": "object" + }, "DownloadArchiveDto": { "properties": { "assetIds": { @@ -22706,6 +22756,9 @@ "logFilePath": { "type": "string" }, + "repositoryId": { + "type": "string" + }, "start": { "type": "string" }, @@ -22715,14 +22768,23 @@ "$ref": "#/components/schemas/RunStatus" } ] + }, + "type": { + "allOf": [ + { + "$ref": "#/components/schemas/RunType" + } + ] } }, "required": [ "end", "id", "logFilePath", + "repositoryId", "start", - "status" + "status", + "type" ], "type": "object" }, @@ -22740,6 +22802,17 @@ ], "type": "object" }, + "RunResponseDto": { + "properties": { + "run": { + "$ref": "#/components/schemas/RunDto" + } + }, + "required": [ + "run" + ], + "type": "object" + }, "RunStatus": { "enum": [ "incomplete", @@ -22748,6 +22821,13 @@ ], "type": "string" }, + "RunType": { + "enum": [ + "backup", + "restore" + ], + "type": "string" + }, "RunningTaskDto": { "properties": { "logId": { @@ -24221,6 +24301,9 @@ }, "type": "array" }, + "summary": { + "$ref": "#/components/schemas/SnapshotSummaryDto" + }, "time": { "type": "string" } @@ -24232,6 +24315,37 @@ ], "type": "object" }, + "SnapshotSummaryDto": { + "properties": { + "dataAdded": { + "type": "number" + }, + "filesChanged": { + "type": "number" + }, + "filesNew": { + "type": "number" + }, + "filesUnmodified": { + "type": "number" + }, + "totalBytes": { + "type": "number" + }, + "totalFiles": { + "type": "number" + } + }, + "required": [ + "dataAdded", + "filesChanged", + "filesNew", + "filesUnmodified", + "totalBytes", + "totalFiles" + ], + "type": "object" + }, "SourceType": { "description": "Face detection source type", "enum": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98e30da402..cc0c8b5323 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.63 - version: 0.1.63(svelte@5.55.1) + specifier: 0.1.68 + version: 0.1.68(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.63 - version: 0.1.63(@nestjs/platform-express@11.1.17)(class-transformer@0.5.1)(reflect-metadata@0.2.2) + specifier: 0.1.68 + version: 0.1.68(@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.63 - version: 0.1.63(@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.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) pmtiles: specifier: ^4.3.0 version: 4.4.0 @@ -6511,6 +6511,10 @@ packages: resolution: {integrity: sha512-fkdfq+b+AHI4cKdhZlppHveI/mgz2qpiYxcm+t5E5TsxX7QrLS1VE0+7GENEk9z0EeGPcpSciGv6ez24duWhwQ==} engines: {node: '>=18.x'} + cronstrue@3.14.0: + resolution: {integrity: sha512-XnW4vuK/jPJjmTyDWiej1Zq36Od7ITwxaV2O1pzHZuyMVvdy7NAvyvIBzybt+idqSpfqYuoDG7uf/ocGtJVWxA==} + hasBin: true + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -7441,6 +7445,10 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + eventsource-client@1.2.0: + resolution: {integrity: sha512-kDI75RSzO3TwyG/K9w1ap8XwqSPcwi6jaMkNulfVeZmSeUM49U8kUzk1s+vKNt0tGrXgK47i+620Yasn1ccFiw==} + engines: {node: '>=18.0.0'} + eventsource-parser@3.0.6: resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} engines: {node: '>=18.0.0'} @@ -9679,11 +9687,11 @@ packages: resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} engines: {node: '>=18'} - orchestration-api@0.1.63: - resolution: {integrity: sha512-WoQedhYvKI7P6/TaxSBJD+K/LrnXZ+ImGLit+VFy2zaXhRLI83q2W6JJP0BE65py0fkpq+6HV4qWdTmJLX34wQ==} + orchestration-api@0.1.68: + resolution: {integrity: sha512-AU0fBmsR+0ykyxnp22fjheF4Q6SWHyEw6/mk0OJos7xrZlxSJnb+DzzXjSiNm4fCyfODTCkSTWfHRnsPbxqQgA==} - orchestration-ui@0.1.63: - resolution: {integrity: sha512-lOlv2OhWF9b4y8mhEPrgs0fmcPJmYOhGAh19jNW/x8LaGfHu2XmmfZvGhj4bntg4VyYUI9xq0Qa/sUfyMtnHjw==} + orchestration-ui@0.1.68: + resolution: {integrity: sha512-DFf7zYlWpvIxdfOtKiN+nhkpzKGXpGRLwls6erSuc1ZvAiZW6bc2+5lLktjBWi+ZRfl166Wkbb4c6a3eIiP2Dg==} peerDependencies: svelte: ^5.0.0 @@ -12643,8 +12651,8 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} - yucca-api-client@0.1.63: - resolution: {integrity: sha512-AZaqQs0bTp99m0FSHohkq+KjmuhSqiL6TxCJ3PT6u73P0CA+bgzFTHQPYFpv2PnB9YVkh7ZvbOLitCVsVyUdeQ==} + yucca-api-client@0.1.68: + resolution: {integrity: sha512-1FCFPa4dZ3wr5n+rpb0+rfCm4u9JSko4nXe3b/zYd/XWHzvLZteEYF3W8iO1LevJHgquEo9ZFkH8h/RU5TFKIg==} yup@1.7.1: resolution: {integrity: sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==} @@ -19127,6 +19135,8 @@ snapshots: '@types/luxon': 3.7.1 luxon: 3.7.2 + cronstrue@3.14.0: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -20219,6 +20229,10 @@ snapshots: events@3.3.0: {} + eventsource-client@1.2.0: + dependencies: + eventsource-parser: 3.0.6 + eventsource-parser@3.0.6: {} execa@5.1.1: @@ -23013,7 +23027,7 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.2.0 - orchestration-api@0.1.63(@nestjs/platform-express@11.1.17)(class-transformer@0.5.1)(reflect-metadata@0.2.2): + orchestration-api@0.1.68(@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) @@ -23027,6 +23041,7 @@ snapshots: cookie: 1.1.1 cron: 4.4.0 event-iterator: 2.0.0 + eventsource-client: 1.2.0 express: 5.2.1 kysely: 0.28.2 nestjs-kysely: 3.1.2(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(kysely@0.28.2)(reflect-metadata@0.2.2) @@ -23034,7 +23049,7 @@ snapshots: rxjs: 7.8.2 socket.io: 4.8.3 tail: 2.2.6 - yucca-api-client: 0.1.63 + yucca-api-client: 0.1.68 transitivePeerDependencies: - '@nestjs/microservices' - '@nestjs/platform-express' @@ -23044,38 +23059,38 @@ snapshots: - supports-color - utf-8-validate - orchestration-ui@0.1.63(@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.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): 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 '@oazapfts/runtime': 1.2.0 '@tanstack/svelte-query': 6.1.9(svelte@5.55.1) cron-validate: 1.5.3 - d3: 7.9.0 + cronstrue: 3.14.0 lodash.debounce: 4.0.8 luxon: 3.7.2 socket.io-client: 4.8.3 svelte: 5.55.1 - yucca-api-client: 0.1.63 + yucca-api-client: 0.1.68 transitivePeerDependencies: - '@sveltejs/kit' - bufferutil - supports-color - utf-8-validate - orchestration-ui@0.1.63(svelte@5.55.1): + orchestration-ui@0.1.68(svelte@5.55.1): dependencies: '@immich/ui': 0.59.0(svelte@5.55.1) '@mdi/js': 7.4.47 '@oazapfts/runtime': 1.2.0 '@tanstack/svelte-query': 6.1.9(svelte@5.55.1) cron-validate: 1.5.3 - d3: 7.9.0 + cronstrue: 3.14.0 lodash.debounce: 4.0.8 luxon: 3.7.2 socket.io-client: 4.8.3 svelte: 5.55.1 - yucca-api-client: 0.1.63 + yucca-api-client: 0.1.68 transitivePeerDependencies: - '@sveltejs/kit' - bufferutil @@ -26598,7 +26613,7 @@ snapshots: yoctocolors@2.1.2: {} - yucca-api-client@0.1.63: + yucca-api-client@0.1.68: dependencies: '@oazapfts/runtime': 1.2.0 diff --git a/server/package.json b/server/package.json index dd7f26b444..5d7d503657 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.63", + "orchestration-api": "0.1.68", "pg": "^8.11.3", "pg-connection-string": "^2.9.1", "picomatch": "^4.0.2", diff --git a/web/package.json b/web/package.json index 5ea310d859..aa0aaa4176 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.63", + "orchestration-ui": "0.1.68", "pmtiles": "^4.3.0", "qrcode": "^1.5.4", "simple-icons": "^16.0.0", diff --git a/web/src/routes/(user)/backups/+page.svelte b/web/src/routes/(user)/backups/+page.svelte new file mode 100644 index 0000000000..38dbd8656b --- /dev/null +++ b/web/src/routes/(user)/backups/+page.svelte @@ -0,0 +1,25 @@ + + + + {data.meta.title} + + + + + goto('/')} /> + + diff --git a/web/src/routes/backups/+page.ts b/web/src/routes/(user)/backups/+page.ts similarity index 51% rename from web/src/routes/backups/+page.ts rename to web/src/routes/(user)/backups/+page.ts index d67e3156ba..d42f20a32f 100644 --- a/web/src/routes/backups/+page.ts +++ b/web/src/routes/(user)/backups/+page.ts @@ -1,6 +1,9 @@ +import { authenticate } from '$lib/utils/auth'; import type { PageLoad } from './$types'; -export const load = (() => { +export const load = (async ({ url }) => { + await authenticate(url); + return { meta: { title: 'Backups', diff --git a/web/src/routes/backups/+layout.svelte b/web/src/routes/backups/+layout.svelte deleted file mode 100644 index a674c1c520..0000000000 --- a/web/src/routes/backups/+layout.svelte +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - -
- page.url.pathname === '/backups'} - /> - - - -
-
- - -
- goto('/')}> - {@render children()} - -
-
-
diff --git a/web/src/routes/backups/+layout.ts b/web/src/routes/backups/+layout.ts deleted file mode 100644 index 6248c5818c..0000000000 --- a/web/src/routes/backups/+layout.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { authenticate } from '$lib/utils/auth'; -import type { LayoutLoad } from './$types'; - -export const load = (async ({ url }) => { - await authenticate(url); -}) satisfies LayoutLoad; diff --git a/web/src/routes/backups/+page.svelte b/web/src/routes/backups/+page.svelte deleted file mode 100644 index 24e92ff727..0000000000 --- a/web/src/routes/backups/+page.svelte +++ /dev/null @@ -1,13 +0,0 @@ - - - { - if (target === 'backups') goto(Route.backupsRepositories()); - else if (target === 'schedules') goto(Route.backupsSchedules()); - else if (target === 'config') goto(Route.backupsConfig()); - }} -/> diff --git a/web/src/routes/backups/config/+page.svelte b/web/src/routes/backups/config/+page.svelte deleted file mode 100644 index 7fd70540b3..0000000000 --- a/web/src/routes/backups/config/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/web/src/routes/backups/repositories/+page.svelte b/web/src/routes/backups/repositories/+page.svelte deleted file mode 100644 index 17b00f04c0..0000000000 --- a/web/src/routes/backups/repositories/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/web/src/routes/backups/schedules/+page.svelte b/web/src/routes/backups/schedules/+page.svelte deleted file mode 100644 index c068380dc9..0000000000 --- a/web/src/routes/backups/schedules/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - -