From e3ad569cc2ad404a0a6542d6d8dc7d6827ac73ef Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:59:18 +0000 Subject: [PATCH 01/60] chore(deps): update pnpm to v10.6.1 (#2521) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cf333d06d..0f7dadffb 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.8" }, - "packageManager": "pnpm@10.5.2", + "packageManager": "pnpm@10.6.1", "engines": { "node": ">=22.14.0" }, From 65f00f19deacb4b68a1debc3821da230813d449c Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Fri, 7 Mar 2025 21:25:24 +0100 Subject: [PATCH 02/60] chore(issue-template): add missing homarr version 1.10.0 --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index fde418afc..14be5a9d8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -31,6 +31,7 @@ body: label: Version description: What version of Homarr are you running? options: + - 1.10.0 - 1.9.0 - 1.8.0 - 1.7.0 From d410af34029a43e6e11cd766f55c634b00eb8fa2 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Fri, 7 Mar 2025 21:27:29 +0100 Subject: [PATCH 03/60] fix(import): autofix missing sizes of items with grid-algorithm (#2522) --- .../import/collections/board-collection.ts | 14 ++- .../src/mappers/map-column-count.ts | 11 ++- .../src/move-widgets-and-apps-merge.ts | 4 +- .../old-import/src/prepare/prepare-items.ts | 96 ++++++++++++++++++- packages/old-schema/src/index.ts | 2 +- packages/old-schema/src/tile.ts | 2 + 6 files changed, 115 insertions(+), 14 deletions(-) diff --git a/packages/old-import/src/import/collections/board-collection.ts b/packages/old-import/src/import/collections/board-collection.ts index 671ac10c9..18475ea53 100644 --- a/packages/old-import/src/import/collections/board-collection.ts +++ b/packages/old-import/src/import/collections/board-collection.ts @@ -81,7 +81,7 @@ export const createBoardInsertCollection = ( ...boardSizes.map((size) => ({ id: layoutMapping[size], boardId: mappedBoard.id, - columnCount: mapColumnCount(board.config, size), + columnCount: mapColumnCount(board.config.settings.customization.gridstack, size), breakpoint: mapBreakpoint(size), name: getBoardSizeName(size), })), @@ -94,7 +94,17 @@ export const createBoardInsertCollection = ( } logger.debug(`Added sections to board insert collection count=${insertCollection.sections.length}`); - const preparedItems = prepareItems({ apps, widgets }, appsMap, preparedSections, layoutMapping, mappedBoard.id); + const preparedItems = prepareItems( + { + apps, + widgets, + settings: board.config.settings, + }, + appsMap, + preparedSections, + layoutMapping, + mappedBoard.id, + ); preparedItems.forEach(({ layouts, ...item }) => { insertCollection.items.push(item); insertCollection.itemLayouts.push(...layouts); diff --git a/packages/old-import/src/mappers/map-column-count.ts b/packages/old-import/src/mappers/map-column-count.ts index 5aedc26cf..1cf457573 100644 --- a/packages/old-import/src/mappers/map-column-count.ts +++ b/packages/old-import/src/mappers/map-column-count.ts @@ -1,13 +1,16 @@ import type { BoardSize, OldmarrConfig } from "@homarr/old-schema"; -export const mapColumnCount = (old: OldmarrConfig, screenSize: BoardSize) => { +export const mapColumnCount = ( + gridstackSettings: OldmarrConfig["settings"]["customization"]["gridstack"], + screenSize: BoardSize, +) => { switch (screenSize) { case "lg": - return old.settings.customization.gridstack.columnCountLarge; + return gridstackSettings.columnCountLarge; case "md": - return old.settings.customization.gridstack.columnCountMedium; + return gridstackSettings.columnCountMedium; case "sm": - return old.settings.customization.gridstack.columnCountSmall; + return gridstackSettings.columnCountSmall; default: return 10; } diff --git a/packages/old-import/src/move-widgets-and-apps-merge.ts b/packages/old-import/src/move-widgets-and-apps-merge.ts index 2cb773a9f..ac3989172 100644 --- a/packages/old-import/src/move-widgets-and-apps-merge.ts +++ b/packages/old-import/src/move-widgets-and-apps-merge.ts @@ -135,7 +135,7 @@ const moveWidgetsAndAppsInLeftSidebar = ( offset: number, screenSize: BoardSize, ) => { - const columnCount = mapColumnCount(old, screenSize); + const columnCount = mapColumnCount(old.settings.customization.gridstack, screenSize); let requiredHeight = updateItems({ // This should work as the reference of the items did not change, only the array reference did items: [...old.widgets, ...old.apps], @@ -211,7 +211,7 @@ const moveWidgetsAndAppsInRightSidebar = ( offset: number, screenSize: BoardSize, ) => { - const columnCount = mapColumnCount(old, screenSize); + const columnCount = mapColumnCount(old.settings.customization.gridstack, screenSize); const xOffsetDelta = Math.max(columnCount - 2, 0); const requiredHeight = updateItems({ // This should work as the reference of the items did not change, only the array reference did diff --git a/packages/old-import/src/prepare/prepare-items.ts b/packages/old-import/src/prepare/prepare-items.ts index f9c9d55d4..bbb96f171 100644 --- a/packages/old-import/src/prepare/prepare-items.ts +++ b/packages/old-import/src/prepare/prepare-items.ts @@ -1,15 +1,101 @@ -import type { BoardSize, OldmarrConfig } from "@homarr/old-schema"; +import { logger } from "@homarr/log"; +import type { BoardSize, OldmarrApp, OldmarrConfig, OldmarrWidget, SizedShape } from "@homarr/old-schema"; +import { boardSizes } from "@homarr/old-schema"; +import type { GridAlgorithmItem } from "../../../api/src/router/board/grid-algorithm"; +import { generateResponsiveGridFor } from "../../../api/src/router/board/grid-algorithm"; +import { mapColumnCount } from "../mappers/map-column-count"; import { mapApp, mapWidget } from "../mappers/map-item"; export const prepareItems = ( - { apps, widgets }: Pick, + { apps, widgets, settings }: Pick, appsMap: Map, sectionMap: Map, layoutMap: Record, boardId: string, -) => - widgets +) => { + let localApps = apps; + let localWidgets = widgets; + + const incompleteSizes = boardSizes.filter((size) => + widgets + .map((widget) => widget.shape) + .concat(apps.map((app) => app.shape)) + .some((shape) => !shape[size]), + ); + + if (incompleteSizes.length > 0) { + logger.warn( + `Found items with incomplete sizes board=${boardId} count=${incompleteSizes.length} sizes=${incompleteSizes.join(", ")}\nHomarr will automatically generate missing sizes`, + ); + + incompleteSizes.forEach((size) => { + const columnCount = mapColumnCount(settings.customization.gridstack, size); + const previousSize = !incompleteSizes.includes("lg") ? "lg" : incompleteSizes.includes("sm") ? "md" : "sm"; + const previousWidth = mapColumnCount(settings.customization.gridstack, previousSize); + logger.info(`Generating missing size boardId=${boardId} from=${previousSize} to=${size}`); + + const items = widgets + .map((item) => mapItemForGridAlgorithm(item, previousSize)) + .concat(apps.map((item) => mapItemForGridAlgorithm(item, previousSize))); + + const distinctSectionIds = [...new Set(items.map((item) => item.sectionId))]; + distinctSectionIds.forEach((sectionId) => { + const { items: newItems } = generateResponsiveGridFor({ items, previousWidth, width: columnCount, sectionId }); + + localApps = localApps.map((app) => { + const item = newItems.find((item) => item.id === app.id); + if (!item) return app; + + return { + ...app, + shape: { + ...app.shape, + [size]: mapShapeFromGridAlgorithm(item), + }, + }; + }); + + localWidgets = localWidgets.map((widget) => { + const item = newItems.find((item) => item.id === widget.id); + if (!item) return widget; + + return { + ...widget, + shape: { + ...widget.shape, + [size]: mapShapeFromGridAlgorithm(item), + }, + }; + }); + }); + }); + } + + return localWidgets .map((widget) => mapWidget(widget, appsMap, sectionMap, layoutMap, boardId)) - .concat(apps.map((app) => mapApp(app, appsMap, sectionMap, layoutMap, boardId))) + .concat(localApps.map((app) => mapApp(app, appsMap, sectionMap, layoutMap, boardId))) .filter((widget) => widget !== null); +}; + +const mapItemForGridAlgorithm = (item: OldmarrApp | OldmarrWidget, size: BoardSize): GridAlgorithmItem => ({ + width: item.shape[size]?.size.width ?? 1, + height: item.shape[size]?.size.height ?? 1, + xOffset: item.shape[size]?.location.x ?? 0, + yOffset: item.shape[size]?.location.y ?? 0, + sectionId: item.area.type === "sidebar" ? item.area.properties.location : item.area.properties.id, + id: item.id, + type: "item", +}); + +const mapShapeFromGridAlgorithm = (item: GridAlgorithmItem) => + ({ + location: { + x: item.xOffset, + y: item.yOffset, + }, + size: { + width: item.width, + height: item.height, + }, + }) satisfies SizedShape; diff --git a/packages/old-schema/src/index.ts b/packages/old-schema/src/index.ts index 40528c09d..e79beb270 100644 --- a/packages/old-schema/src/index.ts +++ b/packages/old-schema/src/index.ts @@ -4,4 +4,4 @@ export type { OldmarrApp, OldmarrIntegrationType } from "./app"; export type { OldmarrWidget, OldmarrWidgetKind } from "./widget"; export { oldmarrWidgetKinds } from "./widget"; export { boardSizes, getBoardSizeName } from "./tile"; -export type { BoardSize } from "./tile"; +export type { BoardSize, SizedShape } from "./tile"; diff --git a/packages/old-schema/src/tile.ts b/packages/old-schema/src/tile.ts index 2331fbdbe..fc0740765 100644 --- a/packages/old-schema/src/tile.ts +++ b/packages/old-schema/src/tile.ts @@ -56,6 +56,8 @@ export const tileBaseSchema = z.object({ shape: shapeSchema, }); +export type SizedShape = z.infer; + export const boardSizes = objectKeys(shapeSchema._def.shape()); export type BoardSize = (typeof boardSizes)[number]; From 4a7ccda362a7f7f9a75767b4ee9fe84d8180682e Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 21:43:30 +0000 Subject: [PATCH 04/60] chore(deps): update dependency eslint to ^9.22.0 (#2530) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- apps/nextjs/package.json | 2 +- apps/tasks/package.json | 2 +- apps/websocket/package.json | 2 +- packages/analytics/package.json | 2 +- packages/api/package.json | 2 +- packages/auth/package.json | 2 +- packages/boards/package.json | 2 +- packages/certificates/package.json | 2 +- packages/cli/package.json | 2 +- packages/common/package.json | 2 +- packages/cron-job-runner/package.json | 2 +- packages/cron-job-status/package.json | 2 +- packages/cron-jobs-core/package.json | 2 +- packages/cron-jobs/package.json | 2 +- packages/db/package.json | 2 +- packages/definitions/package.json | 2 +- packages/docker/package.json | 2 +- packages/env/package.json | 2 +- packages/form/package.json | 2 +- packages/forms-collection/package.json | 2 +- packages/icons/package.json | 2 +- packages/integrations/package.json | 2 +- packages/log/package.json | 2 +- packages/modals-collection/package.json | 2 +- packages/modals/package.json | 2 +- packages/notifications/package.json | 2 +- packages/old-import/package.json | 2 +- packages/old-schema/package.json | 2 +- packages/ping/package.json | 2 +- packages/redis/package.json | 2 +- packages/request-handler/package.json | 2 +- packages/server-settings/package.json | 2 +- packages/settings/package.json | 2 +- packages/spotlight/package.json | 2 +- packages/translation/package.json | 2 +- packages/ui/package.json | 2 +- packages/validation/package.json | 2 +- packages/widgets/package.json | 2 +- pnpm-lock.yaml | 281 ++++++++++++------------ tooling/eslint/package.json | 2 +- 40 files changed, 183 insertions(+), 176 deletions(-) diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index cb7669807..270cd46bf 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -98,7 +98,7 @@ "@types/react-dom": "19.0.4", "@types/swagger-ui-react": "^5.18.0", "concurrently": "^9.1.2", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "node-loader": "^2.1.0", "prettier": "^3.5.3", "typescript": "^5.8.2" diff --git a/apps/tasks/package.json b/apps/tasks/package.json index 3dfb74472..9711f82eb 100644 --- a/apps/tasks/package.json +++ b/apps/tasks/package.json @@ -46,7 +46,7 @@ "@homarr/tsconfig": "workspace:^0.1.0", "@types/node": "^22.13.9", "dotenv-cli": "^8.0.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "prettier": "^3.5.3", "tsx": "4.19.3", "typescript": "^5.8.2" diff --git a/apps/websocket/package.json b/apps/websocket/package.json index 77e9443a8..fa870e18a 100644 --- a/apps/websocket/package.json +++ b/apps/websocket/package.json @@ -34,7 +34,7 @@ "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", "@types/ws": "^8.18.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "prettier": "^3.5.3", "typescript": "^5.8.2" } diff --git a/packages/analytics/package.json b/packages/analytics/package.json index b6b339c9c..57a2d7689 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -32,7 +32,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/api/package.json b/packages/api/package.json index 943b15024..7081da960 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -56,7 +56,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "prettier": "^3.5.3", "typescript": "^5.8.2" } diff --git a/packages/auth/package.json b/packages/auth/package.json index 73a6210c9..02bb7a58c 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -48,7 +48,7 @@ "@homarr/tsconfig": "workspace:^0.1.0", "@types/bcrypt": "5.0.2", "@types/cookies": "0.9.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "prettier": "^3.5.3", "typescript": "^5.8.2" } diff --git a/packages/boards/package.json b/packages/boards/package.json index ba39d8e39..7766e0295 100644 --- a/packages/boards/package.json +++ b/packages/boards/package.json @@ -32,7 +32,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/certificates/package.json b/packages/certificates/package.json index 1e81cfe26..56a257b3b 100644 --- a/packages/certificates/package.json +++ b/packages/certificates/package.json @@ -29,7 +29,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/cli/package.json b/packages/cli/package.json index 6c9201081..c1ec8720d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -33,7 +33,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/common/package.json b/packages/common/package.json index 89793d33a..fe5cafdc3 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -40,7 +40,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/cron-job-runner/package.json b/packages/cron-job-runner/package.json index f2aab14c1..b0dd2ab14 100644 --- a/packages/cron-job-runner/package.json +++ b/packages/cron-job-runner/package.json @@ -30,7 +30,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/cron-job-status/package.json b/packages/cron-job-status/package.json index 549ad16cb..87e6a80ad 100644 --- a/packages/cron-job-status/package.json +++ b/packages/cron-job-status/package.json @@ -29,7 +29,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/cron-jobs-core/package.json b/packages/cron-jobs-core/package.json index cb9791368..9bb87eb63 100644 --- a/packages/cron-jobs-core/package.json +++ b/packages/cron-jobs-core/package.json @@ -32,7 +32,7 @@ "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", "@types/node-cron": "^3.0.11", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/cron-jobs/package.json b/packages/cron-jobs/package.json index eeb2eeb4a..0e9abe18f 100644 --- a/packages/cron-jobs/package.json +++ b/packages/cron-jobs/package.json @@ -44,7 +44,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/db/package.json b/packages/db/package.json index 80e57f99b..f5a5e95b4 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -60,7 +60,7 @@ "@homarr/tsconfig": "workspace:^0.1.0", "@types/better-sqlite3": "7.6.12", "dotenv-cli": "^8.0.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "prettier": "^3.5.3", "tsx": "4.19.3", "typescript": "^5.8.2" diff --git a/packages/definitions/package.json b/packages/definitions/package.json index 6ea5961fc..eff08c7fa 100644 --- a/packages/definitions/package.json +++ b/packages/definitions/package.json @@ -29,7 +29,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/docker/package.json b/packages/docker/package.json index b3631cbcf..b3b6b2456 100644 --- a/packages/docker/package.json +++ b/packages/docker/package.json @@ -32,7 +32,7 @@ "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", "@types/dockerode": "^3.3.35", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/env/package.json b/packages/env/package.json index 998352fa7..a78aefcef 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -30,7 +30,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/form/package.json b/packages/form/package.json index 2ee644486..4102762fb 100644 --- a/packages/form/package.json +++ b/packages/form/package.json @@ -33,7 +33,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/forms-collection/package.json b/packages/forms-collection/package.json index ba4b7cdb7..afa2b4b28 100644 --- a/packages/forms-collection/package.json +++ b/packages/forms-collection/package.json @@ -37,7 +37,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/icons/package.json b/packages/icons/package.json index e41eeda98..7d4a3179c 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -31,7 +31,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/integrations/package.json b/packages/integrations/package.json index e93291dce..f8d4a1adf 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -46,7 +46,7 @@ "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", "@types/xml2js": "^0.4.14", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/log/package.json b/packages/log/package.json index 3c4c4ce3e..0c00104cf 100644 --- a/packages/log/package.json +++ b/packages/log/package.json @@ -33,7 +33,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/modals-collection/package.json b/packages/modals-collection/package.json index efd920c1f..c091d0b3e 100644 --- a/packages/modals-collection/package.json +++ b/packages/modals-collection/package.json @@ -45,7 +45,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/modals/package.json b/packages/modals/package.json index e19d89f50..9600a8eb4 100644 --- a/packages/modals/package.json +++ b/packages/modals/package.json @@ -32,7 +32,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/notifications/package.json b/packages/notifications/package.json index 0fed421d5..8c833a52a 100644 --- a/packages/notifications/package.json +++ b/packages/notifications/package.json @@ -31,7 +31,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/old-import/package.json b/packages/old-import/package.json index 90ec49ec1..1e0ca26da 100644 --- a/packages/old-import/package.json +++ b/packages/old-import/package.json @@ -52,7 +52,7 @@ "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", "@types/adm-zip": "0.5.7", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/old-schema/package.json b/packages/old-schema/package.json index 1f6732ef0..af380ad2d 100644 --- a/packages/old-schema/package.json +++ b/packages/old-schema/package.json @@ -29,7 +29,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/ping/package.json b/packages/ping/package.json index 2e6f4e64a..18444e58c 100644 --- a/packages/ping/package.json +++ b/packages/ping/package.json @@ -31,7 +31,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/redis/package.json b/packages/redis/package.json index e77630db6..957a497b8 100644 --- a/packages/redis/package.json +++ b/packages/redis/package.json @@ -33,7 +33,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/request-handler/package.json b/packages/request-handler/package.json index 6599b177d..56d96d47b 100644 --- a/packages/request-handler/package.json +++ b/packages/request-handler/package.json @@ -38,7 +38,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/server-settings/package.json b/packages/server-settings/package.json index a7599cb52..ecab641a5 100644 --- a/packages/server-settings/package.json +++ b/packages/server-settings/package.json @@ -29,7 +29,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/settings/package.json b/packages/settings/package.json index 502c42c0f..35f9b10d8 100644 --- a/packages/settings/package.json +++ b/packages/settings/package.json @@ -34,7 +34,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/spotlight/package.json b/packages/spotlight/package.json index e789f24e4..80ea1ca6c 100644 --- a/packages/spotlight/package.json +++ b/packages/spotlight/package.json @@ -47,7 +47,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/translation/package.json b/packages/translation/package.json index 4038fd24e..45c65045d 100644 --- a/packages/translation/package.json +++ b/packages/translation/package.json @@ -41,7 +41,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/ui/package.json b/packages/ui/package.json index 1b90534e4..38f031e95 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -43,7 +43,7 @@ "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", "@types/css-modules": "^1.0.5", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/validation/package.json b/packages/validation/package.json index 737a8a6fa..c7e438637 100644 --- a/packages/validation/package.json +++ b/packages/validation/package.json @@ -32,7 +32,7 @@ "@homarr/eslint-config": "workspace:^0.2.0", "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 872827e17..ec7450a0a 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -76,7 +76,7 @@ "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", "@types/video.js": "^7.3.58", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ff6f275e0..e98f2aad3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -327,8 +327,8 @@ importers: specifier: ^9.1.2 version: 9.1.2 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 node-loader: specifier: ^2.1.0 version: 2.1.0(webpack@5.94.0) @@ -415,8 +415,8 @@ importers: specifier: ^8.0.0 version: 8.0.0 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 prettier: specifier: ^3.5.3 version: 3.5.3 @@ -476,8 +476,8 @@ importers: specifier: ^8.18.0 version: 8.18.0 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 prettier: specifier: ^3.5.3 version: 3.5.3 @@ -513,8 +513,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -622,8 +622,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 prettier: specifier: ^3.5.3 version: 3.5.3 @@ -704,8 +704,8 @@ importers: specifier: 0.9.0 version: 0.9.0 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 prettier: specifier: ^3.5.3 version: 3.5.3 @@ -735,8 +735,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -760,8 +760,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -794,8 +794,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -837,8 +837,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -865,8 +865,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -887,8 +887,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -957,8 +957,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -985,8 +985,8 @@ importers: specifier: ^3.0.11 version: 3.0.11 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1055,8 +1055,8 @@ importers: specifier: ^8.0.0 version: 8.0.0 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 prettier: specifier: ^3.5.3 version: 3.5.3 @@ -1083,8 +1083,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1114,8 +1114,8 @@ importers: specifier: ^3.3.35 version: 3.3.35 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1139,8 +1139,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1173,8 +1173,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1222,8 +1222,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1250,8 +1250,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1320,8 +1320,8 @@ importers: specifier: ^0.4.14 version: 0.4.14 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1354,8 +1354,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1388,8 +1388,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1461,8 +1461,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1489,8 +1489,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1571,8 +1571,8 @@ importers: specifier: 0.5.7 version: 0.5.7 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1596,8 +1596,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1627,8 +1627,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1664,8 +1664,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1716,8 +1716,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1741,8 +1741,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1781,8 +1781,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1857,8 +1857,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1903,8 +1903,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1964,8 +1964,8 @@ importers: specifier: ^1.0.5 version: 1.0.5 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -1995,8 +1995,8 @@ importers: specifier: workspace:^0.1.0 version: link:../../tooling/typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -2155,8 +2155,8 @@ importers: specifier: ^7.3.58 version: 7.3.58 eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -2168,25 +2168,25 @@ importers: version: 15.1.7 eslint-config-prettier: specifier: ^10.1.1 - version: 10.1.1(eslint@9.21.0) + version: 10.1.1(eslint@9.22.0) eslint-config-turbo: specifier: ^2.4.4 - version: 2.4.4(eslint@9.21.0)(turbo@2.4.4) + version: 2.4.4(eslint@9.22.0)(turbo@2.4.4) eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0)(typescript@5.8.2))(eslint@9.21.0) + version: 2.31.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0) eslint-plugin-jsx-a11y: specifier: ^6.10.2 - version: 6.10.2(eslint@9.21.0) + version: 6.10.2(eslint@9.22.0) eslint-plugin-react: specifier: ^7.37.4 - version: 7.37.4(eslint@9.21.0) + version: 7.37.4(eslint@9.22.0) eslint-plugin-react-hooks: specifier: ^5.2.0 - version: 5.2.0(eslint@9.21.0) + version: 5.2.0(eslint@9.22.0) typescript-eslint: specifier: ^8.26.0 - version: 8.26.0(eslint@9.21.0)(typescript@5.8.2) + version: 8.26.0(eslint@9.22.0)(typescript@5.8.2) devDependencies: '@homarr/prettier-config': specifier: workspace:^0.1.0 @@ -2195,8 +2195,8 @@ importers: specifier: workspace:^0.1.0 version: link:../typescript eslint: - specifier: ^9.21.0 - version: 9.21.0 + specifier: ^9.22.0 + version: 9.22.0 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -3199,6 +3199,10 @@ packages: resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-helpers@0.1.0': + resolution: {integrity: sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.12.0': resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3207,8 +3211,8 @@ packages: resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.21.0': - resolution: {integrity: sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==} + '@eslint/js@9.22.0': + resolution: {integrity: sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -6251,8 +6255,8 @@ packages: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} - eslint-scope@8.2.0: - resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: @@ -6263,8 +6267,8 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.21.0: - resolution: {integrity: sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==} + eslint@9.22.0: + resolution: {integrity: sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -10883,9 +10887,9 @@ snapshots: '@esbuild/win32-x64@0.25.0': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.21.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@9.22.0)': dependencies: - eslint: 9.21.0 + eslint: 9.22.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -10898,6 +10902,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/config-helpers@0.1.0': {} + '@eslint/core@0.12.0': dependencies: '@types/json-schema': 7.0.15 @@ -10916,7 +10922,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.21.0': {} + '@eslint/js@9.22.0': {} '@eslint/object-schema@2.1.6': {} @@ -12872,15 +12878,15 @@ snapshots: dependencies: '@types/node': 22.13.9 - '@typescript-eslint/eslint-plugin@8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0)(typescript@5.8.2))(eslint@9.21.0)(typescript@5.8.2)': + '@typescript-eslint/eslint-plugin@8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.26.0(eslint@9.21.0)(typescript@5.8.2) + '@typescript-eslint/parser': 8.26.0(eslint@9.22.0)(typescript@5.8.2) '@typescript-eslint/scope-manager': 8.26.0 - '@typescript-eslint/type-utils': 8.26.0(eslint@9.21.0)(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.0(eslint@9.21.0)(typescript@5.8.2) + '@typescript-eslint/type-utils': 8.26.0(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/utils': 8.26.0(eslint@9.22.0)(typescript@5.8.2) '@typescript-eslint/visitor-keys': 8.26.0 - eslint: 9.21.0 + eslint: 9.22.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -12889,14 +12895,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.26.0(eslint@9.21.0)(typescript@5.8.2)': + '@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2)': dependencies: '@typescript-eslint/scope-manager': 8.26.0 '@typescript-eslint/types': 8.26.0 '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.2) '@typescript-eslint/visitor-keys': 8.26.0 debug: 4.4.0 - eslint: 9.21.0 + eslint: 9.22.0 typescript: 5.8.2 transitivePeerDependencies: - supports-color @@ -12906,12 +12912,12 @@ snapshots: '@typescript-eslint/types': 8.26.0 '@typescript-eslint/visitor-keys': 8.26.0 - '@typescript-eslint/type-utils@8.26.0(eslint@9.21.0)(typescript@5.8.2)': + '@typescript-eslint/type-utils@8.26.0(eslint@9.22.0)(typescript@5.8.2)': dependencies: '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.0(eslint@9.21.0)(typescript@5.8.2) + '@typescript-eslint/utils': 8.26.0(eslint@9.22.0)(typescript@5.8.2) debug: 4.4.0 - eslint: 9.21.0 + eslint: 9.22.0 ts-api-utils: 2.0.1(typescript@5.8.2) typescript: 5.8.2 transitivePeerDependencies: @@ -12933,13 +12939,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.26.0(eslint@9.21.0)(typescript@5.8.2)': + '@typescript-eslint/utils@8.26.0(eslint@9.22.0)(typescript@5.8.2)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.21.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.22.0) '@typescript-eslint/scope-manager': 8.26.0 '@typescript-eslint/types': 8.26.0 '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.2) - eslint: 9.21.0 + eslint: 9.22.0 typescript: 5.8.2 transitivePeerDependencies: - supports-color @@ -14597,14 +14603,14 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-prettier@10.1.1(eslint@9.21.0): + eslint-config-prettier@10.1.1(eslint@9.22.0): dependencies: - eslint: 9.21.0 + eslint: 9.22.0 - eslint-config-turbo@2.4.4(eslint@9.21.0)(turbo@2.4.4): + eslint-config-turbo@2.4.4(eslint@9.22.0)(turbo@2.4.4): dependencies: - eslint: 9.21.0 - eslint-plugin-turbo: 2.4.4(eslint@9.21.0)(turbo@2.4.4) + eslint: 9.22.0 + eslint-plugin-turbo: 2.4.4(eslint@9.22.0)(turbo@2.4.4) turbo: 2.4.4 eslint-import-resolver-node@0.3.9: @@ -14615,17 +14621,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.21.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.22.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.26.0(eslint@9.21.0)(typescript@5.8.2) - eslint: 9.21.0 + '@typescript-eslint/parser': 8.26.0(eslint@9.22.0)(typescript@5.8.2) + eslint: 9.22.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0)(typescript@5.8.2))(eslint@9.21.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -14634,9 +14640,9 @@ snapshots: array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.21.0 + eslint: 9.22.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.21.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.22.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -14648,13 +14654,13 @@ snapshots: string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.26.0(eslint@9.21.0)(typescript@5.8.2) + '@typescript-eslint/parser': 8.26.0(eslint@9.22.0)(typescript@5.8.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.21.0): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.22.0): dependencies: aria-query: 5.3.2 array-includes: 3.1.8 @@ -14664,7 +14670,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.21.0 + eslint: 9.22.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -14673,11 +14679,11 @@ snapshots: safe-regex-test: 1.0.3 string.prototype.includes: 2.0.1 - eslint-plugin-react-hooks@5.2.0(eslint@9.21.0): + eslint-plugin-react-hooks@5.2.0(eslint@9.22.0): dependencies: - eslint: 9.21.0 + eslint: 9.22.0 - eslint-plugin-react@7.37.4(eslint@9.21.0): + eslint-plugin-react@7.37.4(eslint@9.22.0): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -14685,7 +14691,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.21.0 + eslint: 9.22.0 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -14699,10 +14705,10 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.4.4(eslint@9.21.0)(turbo@2.4.4): + eslint-plugin-turbo@2.4.4(eslint@9.22.0)(turbo@2.4.4): dependencies: dotenv: 16.0.3 - eslint: 9.21.0 + eslint: 9.22.0 turbo: 2.4.4 eslint-scope@5.1.1: @@ -14710,7 +14716,7 @@ snapshots: esrecurse: 4.3.0 estraverse: 4.3.0 - eslint-scope@8.2.0: + eslint-scope@8.3.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 @@ -14719,14 +14725,15 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.21.0: + eslint@9.22.0: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.21.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.22.0) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.19.2 + '@eslint/config-helpers': 0.1.0 '@eslint/core': 0.12.0 '@eslint/eslintrc': 3.3.0 - '@eslint/js': 9.21.0 + '@eslint/js': 9.22.0 '@eslint/plugin-kit': 0.2.7 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 @@ -14738,7 +14745,7 @@ snapshots: cross-spawn: 7.0.6 debug: 4.4.0 escape-string-regexp: 4.0.0 - eslint-scope: 8.2.0 + eslint-scope: 8.3.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 esquery: 1.6.0 @@ -18448,12 +18455,12 @@ snapshots: dependencies: ts-toolbelt: 9.6.0 - typescript-eslint@8.26.0(eslint@9.21.0)(typescript@5.8.2): + typescript-eslint@8.26.0(eslint@9.22.0)(typescript@5.8.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.21.0)(typescript@5.8.2))(eslint@9.21.0)(typescript@5.8.2) - '@typescript-eslint/parser': 8.26.0(eslint@9.21.0)(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.0(eslint@9.21.0)(typescript@5.8.2) - eslint: 9.21.0 + '@typescript-eslint/eslint-plugin': 8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/parser': 8.26.0(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/utils': 8.26.0(eslint@9.22.0)(typescript@5.8.2) + eslint: 9.22.0 typescript: 5.8.2 transitivePeerDependencies: - supports-color diff --git a/tooling/eslint/package.json b/tooling/eslint/package.json index 6212eb19a..68863a94c 100644 --- a/tooling/eslint/package.json +++ b/tooling/eslint/package.json @@ -29,7 +29,7 @@ "devDependencies": { "@homarr/prettier-config": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0", - "eslint": "^9.21.0", + "eslint": "^9.22.0", "typescript": "^5.8.2" } } From b3464b3340cf57b4f85da0dd2e1bd8e754f1bec8 Mon Sep 17 00:00:00 2001 From: Jack Weller <97435840+jackwellerreal@users.noreply.github.com> Date: Sat, 8 Mar 2025 07:56:16 +1000 Subject: [PATCH 05/60] feat(widgets): add border color option to advanced-options (#2512) * feat: add border color option for all widgets * fix: broken lockfile * fix: typecheck issue --------- Co-authored-by: Meier Lukas --- .../src/app/[locale]/widgets/[kind]/_content.tsx | 1 + .../components/board/items/actions/create-item.ts | 1 + .../items/actions/test/duplicate-item.spec.ts | 2 +- .../board/items/actions/test/mocks/item-mock.ts | 1 + .../src/components/board/items/item-content.tsx | 1 + packages/translation/src/lang/en.json | 3 +++ packages/validation/src/shared.ts | 1 + .../src/modals/widget-advanced-options-modal.tsx | 15 ++++++++++++++- packages/widgets/src/modals/widget-edit-modal.tsx | 1 + 9 files changed, 24 insertions(+), 2 deletions(-) diff --git a/apps/nextjs/src/app/[locale]/widgets/[kind]/_content.tsx b/apps/nextjs/src/app/[locale]/widgets/[kind]/_content.tsx index d31f42e9e..362236300 100644 --- a/apps/nextjs/src/app/[locale]/widgets/[kind]/_content.tsx +++ b/apps/nextjs/src/app/[locale]/widgets/[kind]/_content.tsx @@ -49,6 +49,7 @@ export const WidgetPreviewPageContent = ({ kind, integrationData }: WidgetPrevie integrationIds: [], advancedOptions: { customCssClasses: [], + borderColor: "", }, }); diff --git a/apps/nextjs/src/components/board/items/actions/create-item.ts b/apps/nextjs/src/components/board/items/actions/create-item.ts index 6525718f9..d29d407b5 100644 --- a/apps/nextjs/src/components/board/items/actions/create-item.ts +++ b/apps/nextjs/src/components/board/items/actions/create-item.ts @@ -29,6 +29,7 @@ export const createItemCallback = integrationIds: [], advancedOptions: { customCssClasses: [], + borderColor: "", }, } satisfies Modify< Item, diff --git a/apps/nextjs/src/components/board/items/actions/test/duplicate-item.spec.ts b/apps/nextjs/src/components/board/items/actions/test/duplicate-item.spec.ts index 7bb2fb7ad..88ccd781b 100644 --- a/apps/nextjs/src/components/board/items/actions/test/duplicate-item.spec.ts +++ b/apps/nextjs/src/components/board/items/actions/test/duplicate-item.spec.ts @@ -20,7 +20,7 @@ describe("item actions duplicate-item", () => { kind: itemKind, integrationIds: ["1"], options: { address: "localhost" }, - advancedOptions: { customCssClasses: ["test"] }, + advancedOptions: { customCssClasses: ["test"], borderColor: "#ff0000" }, }) .addLayout({ layoutId, sectionId: currentSectionId, ...currentItemSize }) .build(); diff --git a/apps/nextjs/src/components/board/items/actions/test/mocks/item-mock.ts b/apps/nextjs/src/components/board/items/actions/test/mocks/item-mock.ts index f7533bd56..71b84918e 100644 --- a/apps/nextjs/src/components/board/items/actions/test/mocks/item-mock.ts +++ b/apps/nextjs/src/components/board/items/actions/test/mocks/item-mock.ts @@ -14,6 +14,7 @@ export class ItemMockBuilder { integrationIds: [], advancedOptions: { customCssClasses: [], + borderColor: "", }, ...item, } satisfies Item; diff --git a/apps/nextjs/src/components/board/items/item-content.tsx b/apps/nextjs/src/components/board/items/item-content.tsx index b486a20cf..709d52182 100644 --- a/apps/nextjs/src/components/board/items/item-content.tsx +++ b/apps/nextjs/src/components/board/items/item-content.tsx @@ -40,6 +40,7 @@ export const BoardItemContent = ({ item }: BoardItemContentProps) => { "--opacity": board.opacity / 100, containerType: "size", overflow: item.kind === "iframe" ? "hidden" : undefined, + "--border-color": item.advancedOptions.borderColor !== "" ? item.advancedOptions.borderColor : undefined, }, }} p={0} diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 72ed28ddc..d7d9f8697 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1070,6 +1070,9 @@ }, "customCssClasses": { "label": "Custom css classes" + }, + "borderColor": { + "label": "Border color" } } }, diff --git a/packages/validation/src/shared.ts b/packages/validation/src/shared.ts index 0080254c0..733d3edef 100644 --- a/packages/validation/src/shared.ts +++ b/packages/validation/src/shared.ts @@ -15,6 +15,7 @@ export type BoardItemIntegration = z.infer; export const itemAdvancedOptionsSchema = z.object({ customCssClasses: z.array(z.string()).default([]), + borderColor: z.string().default(""), }); export type BoardItemAdvancedOptions = z.infer; diff --git a/packages/widgets/src/modals/widget-advanced-options-modal.tsx b/packages/widgets/src/modals/widget-advanced-options-modal.tsx index 674bc8f9c..f957b100a 100644 --- a/packages/widgets/src/modals/widget-advanced-options-modal.tsx +++ b/packages/widgets/src/modals/widget-advanced-options-modal.tsx @@ -1,6 +1,6 @@ "use client"; -import { Button, Group, Stack } from "@mantine/core"; +import { Button, CloseButton, ColorInput, Group, Stack, useMantineTheme } from "@mantine/core"; import { useForm } from "@homarr/form"; import { createModal } from "@homarr/modals"; @@ -15,6 +15,7 @@ interface InnerProps { export const WidgetAdvancedOptionsModal = createModal(({ actions, innerProps }) => { const t = useI18n(); + const theme = useMantineTheme(); const form = useForm({ initialValues: innerProps.advancedOptions, }); @@ -30,6 +31,18 @@ export const WidgetAdvancedOptionsModal = createModal(({ actions, in label={t("item.edit.field.customCssClasses.label")} {...form.getInputProps("customCssClasses")} /> + color[6])} + rightSection={ + form.setFieldValue("borderColor", "")} + style={{ display: form.getInputProps("borderColor").value ? undefined : "none" }} + /> + } + {...form.getInputProps("borderColor")} + /> )} - + ))} - + - + ); } @@ -283,6 +298,7 @@ interface ControlsCardProps { open: () => void; t: TranslationFunction; hasIconColor: boolean; + rootWidth: number; } const ControlsCard: React.FC = ({ @@ -293,6 +309,7 @@ const ControlsCard: React.FC = ({ open, t, hasIconColor, + rootWidth, }) => { const isConnected = useIntegrationConnected(data.integration.updatedAt, { timeout: 30000 }); const isEnabled = data.summary.status ? data.summary.status === "enabled" : undefined; @@ -302,95 +319,161 @@ const ControlsCard: React.FC = ({ const board = useRequiredBoard(); const iconUrl = integrationDefs[data.integration.kind].iconUrl; + const layout = rootWidth < 256 ? "sm" : "md"; return ( - - - - - - {data.integration.name} - - - toggleDns(data.integration.id)} - > - - ) - } - > - {t( - `widget.dnsHoleControls.controls.${ - !isConnected - ? "disconnected" - : typeof isEnabled === "undefined" - ? "processing" - : isEnabled - ? "enabled" - : "disabled" - }`, - )} - - + + + {layout === "md" && ( + + )} + + + + {layout === "sm" && ( + + )} + + {data.integration.name} + + + + {layout === "sm" && ( + + {!isEnabled ? ( + toggleDns(data.integration.id)} + disabled={!controlEnabled} + size="sm" + color="green" + variant="light" + > + + + ) : ( + toggleDns(data.integration.id)} + disabled={!controlEnabled} + size="sm" + color="red" + variant="light" + > + + + )} + { + setSelectedIntegrationIds([data.integration.id]); + open(); + }} + size="sm" + color="yellow" + variant="light" + > + + + + )} + {layout === "md" && ( + toggleDns(data.integration.id)} + > + + ) + } + > + {t( + `widget.dnsHoleControls.controls.${ + !isConnected + ? "disconnected" + : typeof isEnabled === "undefined" + ? "processing" + : isEnabled + ? "enabled" + : "disabled" + }`, + )} + + + )} + + {layout === "md" && ( + { + setSelectedIntegrationIds([data.integration.id]); + open(); + }} + > + + + )} - { - setSelectedIntegrationIds([data.integration.id]); - open(); - }} - > - - - - + + ); }; diff --git a/packages/widgets/src/widgets-common.css b/packages/widgets/src/widgets-common.css index 02e57f750..5bcacd11f 100644 --- a/packages/widgets/src/widgets-common.css +++ b/packages/widgets/src/widgets-common.css @@ -62,14 +62,3 @@ .text-flash { animation: glow 1s ease-in-out; } - -/*To apply to any ScrollArea that we want to flex. Same weird workaround as before*/ -.flexed-scroll-area { - height: 100%; - .mantine-ScrollArea-viewport { - & div[style="min-width: 100%; display: table;"] { - display: flex !important; - height: 100%; - } - } -} From fb800a00084833e785deecdb3b6fde4e35ddf7b8 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sat, 8 Mar 2025 20:54:48 +0100 Subject: [PATCH 11/60] fix(app): improve responsive styles (#2537) --- packages/widgets/src/app/component.tsx | 6 ++++-- packages/widgets/src/app/ping/ping-dot.tsx | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/widgets/src/app/component.tsx b/packages/widgets/src/app/component.tsx index 34a8dafb6..a89532063 100644 --- a/packages/widgets/src/app/component.tsx +++ b/packages/widgets/src/app/component.tsx @@ -18,7 +18,7 @@ import classes from "./app.module.css"; import { PingDot } from "./ping/ping-dot"; import { PingIndicator } from "./ping/ping-indicator"; -export default function AppWidget({ options, isEditMode }: WidgetComponentProps<"app">) { +export default function AppWidget({ options, isEditMode, height, width }: WidgetComponentProps<"app">) { const t = useI18n(); const settings = useSettings(); const board = useRequiredBoard(); @@ -56,6 +56,8 @@ export default function AppWidget({ options, isEditMode }: WidgetComponentProps< [app, options.openInNewTab], ); + const tinyText = height < 100 || width < 100; + return ( {options.showTitle && ( - + {app.name} )} diff --git a/packages/widgets/src/app/ping/ping-dot.tsx b/packages/widgets/src/app/ping/ping-dot.tsx index d728e8678..b559adc5d 100644 --- a/packages/widgets/src/app/ping/ping-dot.tsx +++ b/packages/widgets/src/app/ping/ping-dot.tsx @@ -15,17 +15,17 @@ export const PingDot = ({ color, tooltip, ...props }: PingDotProps) => { return ( - + {pingIconsEnabled ? ( - + ) : ( )} From 1db9c3c6925f0baae963c5f079037c2bcd1cee44 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sat, 8 Mar 2025 20:55:03 +0100 Subject: [PATCH 12/60] fix(calendar): improve responsive styles (#2538) * fix(calendar): improve responsive styles * fix: remove temporary events * fix: deepsource issue --- .../widgets/src/calendar/calendar-event-list.tsx | 2 +- packages/widgets/src/calendar/calender-day.tsx | 16 ++++++++++------ packages/widgets/src/calendar/component.tsx | 4 ++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/widgets/src/calendar/calendar-event-list.tsx b/packages/widgets/src/calendar/calendar-event-list.tsx index 22eaa8660..1c2c9283f 100644 --- a/packages/widgets/src/calendar/calendar-event-list.tsx +++ b/packages/widgets/src/calendar/calendar-event-list.tsx @@ -30,7 +30,7 @@ export const CalendarEventList = ({ events }: CalendarEventListProps) => { {date.getDate()} - {rootHeight >= 350 && } + - + {/* Popover has some offset on the left side, padding is removed because of scrollarea paddings */} + @@ -72,14 +73,17 @@ export const CalendarDay = ({ date, events, disabled, rootHeight, rootWidth }: C interface NotificationIndicatorProps { events: CalendarEvent[]; + rootHeight: number; } -const NotificationIndicator = ({ events }: NotificationIndicatorProps) => { +const NotificationIndicator = ({ events, rootHeight }: NotificationIndicatorProps) => { + const isSmall = rootHeight < 256; const notificationEvents = [...new Set(events.map((event) => event.links[0]?.notificationColor))].filter(String); + /* position bottom is lower when small to not be on top of number*/ return ( - + {notificationEvents.map((notificationEvent) => { - return ; + return ; })} ); diff --git a/packages/widgets/src/calendar/component.tsx b/packages/widgets/src/calendar/component.tsx index d05bbc7d8..9447459a2 100644 --- a/packages/widgets/src/calendar/component.tsx +++ b/packages/widgets/src/calendar/component.tsx @@ -105,8 +105,8 @@ const CalendarBase = ({ isEditMode, events, month, setMonth, options }: Calendar }, day: { borderRadius: actualItemRadius, - width: width < 350 ? 20 : 50, - height: height < 350 ? 20 : 50, + width: "100%", + height: "100%", }, month: { height: "100%", From fd5b1b0c082ee440c6c5137629ef1ec4eead23eb Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sat, 8 Mar 2025 20:55:15 +0100 Subject: [PATCH 13/60] fix(date-time): improve responsive styles (#2539) --- packages/widgets/src/clock/component.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/widgets/src/clock/component.tsx b/packages/widgets/src/clock/component.tsx index 32cf45549..417585162 100644 --- a/packages/widgets/src/clock/component.tsx +++ b/packages/widgets/src/clock/component.tsx @@ -13,28 +13,31 @@ dayjs.extend(advancedFormat); dayjs.extend(utc); dayjs.extend(timezones); -export default function ClockWidget({ options }: WidgetComponentProps<"clock">) { +export default function ClockWidget({ options, width }: WidgetComponentProps<"clock">) { const secondsFormat = options.showSeconds ? ":ss" : ""; - const timeFormat = options.is24HourFormat ? `HH:mm${secondsFormat}` : `h:mm${secondsFormat} A`; + const timeFormat = options.is24HourFormat ? `HH:mm${secondsFormat}` : `hh:mm${secondsFormat} A`; const dateFormat = options.dateFormat; const customTimeFormat = options.customTimeFormat; const customDateFormat = options.customDateFormat; const timezone = options.useCustomTimezone ? options.timezone : Intl.DateTimeFormat().resolvedOptions().timeZone; const time = useCurrentTime(options); + + const sizing = width < 128 ? "xs" : width < 196 ? "sm" : "md"; + return ( - + {options.customTitleToggle && ( - + {options.customTitle} )} - + <Title className="clock-time-text" fw={700} order={sizing === "md" ? 2 : sizing === "sm" ? 4 : 6} lh="1"> {options.customTimeFormat ? dayjs(time).tz(timezone).format(customTimeFormat) : dayjs(time).tz(timezone).format(timeFormat)} {options.showDate && ( - + {options.customDateFormat ? dayjs(time).tz(timezone).format(customDateFormat) : dayjs(time).tz(timezone).format(dateFormat)} From 0b07f227ee72988fe1cbd37a9a6a8751b942a087 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sat, 8 Mar 2025 20:55:25 +0100 Subject: [PATCH 14/60] fix(smart-home): improve responsive styles (#2540) --- .../src/smart-home/entity-state/component.tsx | 6 ++++-- .../smart-home/execute-automation/component.tsx | 15 ++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/widgets/src/smart-home/entity-state/component.tsx b/packages/widgets/src/smart-home/entity-state/component.tsx index ece090c56..587978a42 100644 --- a/packages/widgets/src/smart-home/entity-state/component.tsx +++ b/packages/widgets/src/smart-home/entity-state/component.tsx @@ -13,6 +13,7 @@ export default function SmartHomeEntityStateWidget({ options, integrationIds, isEditMode, + width, }: WidgetComponentProps<"smartHome-entityState">) { // It will always have at least one integration as otherwise the NoIntegrationSelectedError would be thrown in item-content.tsx // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -71,6 +72,7 @@ export default function SmartHomeEntityStateWidget({ ], [handleClick, options.clickable, options.displayName, options.entityId], ); + const isTiny = width < 128; return (
- + {options.displayName} - + {entityState} {attribute} diff --git a/packages/widgets/src/smart-home/execute-automation/component.tsx b/packages/widgets/src/smart-home/execute-automation/component.tsx index 7834b08f9..45bb8ce15 100644 --- a/packages/widgets/src/smart-home/execute-automation/component.tsx +++ b/packages/widgets/src/smart-home/execute-automation/component.tsx @@ -1,7 +1,7 @@ "use client"; import React from "react"; -import { ActionIcon, Center, LoadingOverlay, Overlay, Stack, Text, UnstyledButton } from "@mantine/core"; +import { Center, LoadingOverlay, Overlay, Stack, Text, ThemeIcon, UnstyledButton } from "@mantine/core"; import { useDisclosure, useTimeout } from "@mantine/hooks"; import { IconAutomation, IconCheck } from "@tabler/icons-react"; @@ -15,6 +15,7 @@ export default function SmartHomeTriggerAutomationWidget({ options, integrationIds, isEditMode, + width, }: WidgetComponentProps<"smartHome-executeAutomation">) { const [isShowSuccess, { open: showSuccess, close: closeSuccess }] = useDisclosure(); const { start } = useTimeout(() => { @@ -59,6 +60,8 @@ export default function SmartHomeTriggerAutomationWidget({ [handleClick, options.automationId, options.displayName], ); + const isTiny = width < 128; + return (
- + - +
)}
- - {options.displayName} + + + {options.displayName} +
From 2e62a61f4d20241fb77065faa00b14d427d4f4e0 Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Sat, 8 Mar 2025 22:13:45 +0000 Subject: [PATCH 15/60] feat: add nextcloud integration (#2501) --- apps/nextjs/public/images/apps/nextcloud.svg | 1 + packages/definitions/src/integration.ts | 6 ++ packages/integrations/package.json | 2 + packages/integrations/src/base/creator.ts | 2 + packages/integrations/src/index.ts | 1 + .../src/nextcloud/nextcloud.integration.ts | 97 +++++++++++++++++++ .../src/calendar/calendar-event-list.tsx | 8 +- pnpm-lock.yaml | 81 +++++++++++++++- 8 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 apps/nextjs/public/images/apps/nextcloud.svg create mode 100644 packages/integrations/src/nextcloud/nextcloud.integration.ts diff --git a/apps/nextjs/public/images/apps/nextcloud.svg b/apps/nextjs/public/images/apps/nextcloud.svg new file mode 100644 index 000000000..841b9d987 --- /dev/null +++ b/apps/nextjs/public/images/apps/nextcloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/definitions/src/integration.ts b/packages/definitions/src/integration.ts index e4bda472a..ab2097f73 100644 --- a/packages/definitions/src/integration.ts +++ b/packages/definitions/src/integration.ts @@ -151,6 +151,12 @@ export const integrationDefs = { category: ["healthMonitoring"], iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/proxmox.svg", }, + nextcloud: { + name: "Nextcloud", + secretKinds: [["username", "password"]], + category: ["calendar"], + iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/nextcloud.svg", + }, } as const satisfies Record; export const integrationKinds = objectKeys(integrationDefs) as AtLeastOneOf; diff --git a/packages/integrations/package.json b/packages/integrations/package.json index f8d4a1adf..677a0f27d 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -36,7 +36,9 @@ "@homarr/translation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0", "@jellyfin/sdk": "^0.11.0", + "node-ical": "^0.20.1", "proxmox-api": "1.1.1", + "tsdav": "^2.1.3", "undici": "7.4.0", "xml2js": "^0.6.2", "zod": "^3.24.2" diff --git a/packages/integrations/src/base/creator.ts b/packages/integrations/src/base/creator.ts index 21df2a7e9..7664e86bc 100644 --- a/packages/integrations/src/base/creator.ts +++ b/packages/integrations/src/base/creator.ts @@ -19,6 +19,7 @@ import { RadarrIntegration } from "../media-organizer/radarr/radarr-integration" import { ReadarrIntegration } from "../media-organizer/readarr/readarr-integration"; import { SonarrIntegration } from "../media-organizer/sonarr/sonarr-integration"; import { TdarrIntegration } from "../media-transcoding/tdarr-integration"; +import { NextcloudIntegration } from "../nextcloud/nextcloud.integration"; import { OpenMediaVaultIntegration } from "../openmediavault/openmediavault-integration"; import { OverseerrIntegration } from "../overseerr/overseerr-integration"; import { createPiHoleIntegrationAsync } from "../pi-hole/pi-hole-integration-factory"; @@ -86,6 +87,7 @@ export const integrationCreators = { tdarr: TdarrIntegration, proxmox: ProxmoxIntegration, emby: EmbyIntegration, + nextcloud: NextcloudIntegration, } satisfies Record Promise]>; type IntegrationInstanceOfKind = { diff --git a/packages/integrations/src/index.ts b/packages/integrations/src/index.ts index 8a52261c3..23f24b712 100644 --- a/packages/integrations/src/index.ts +++ b/packages/integrations/src/index.ts @@ -19,6 +19,7 @@ export { PlexIntegration } from "./plex/plex-integration"; export { ProwlarrIntegration } from "./prowlarr/prowlarr-integration"; export { LidarrIntegration } from "./media-organizer/lidarr/lidarr-integration"; export { ReadarrIntegration } from "./media-organizer/readarr/readarr-integration"; +export { NextcloudIntegration } from "./nextcloud/nextcloud.integration"; // Types export type { IntegrationInput } from "./base/integration"; diff --git a/packages/integrations/src/nextcloud/nextcloud.integration.ts b/packages/integrations/src/nextcloud/nextcloud.integration.ts new file mode 100644 index 000000000..7f6268a6d --- /dev/null +++ b/packages/integrations/src/nextcloud/nextcloud.integration.ts @@ -0,0 +1,97 @@ +import dayjs from "dayjs"; +import objectSupport from "dayjs/plugin/objectSupport"; +import utc from "dayjs/plugin/utc"; +import * as ical from "node-ical"; +import { DAVClient } from "tsdav"; + +import { logger } from "@homarr/log"; + +import { Integration } from "../base/integration"; +import type { CalendarEvent } from "../calendar-types"; + +dayjs.extend(utc); +dayjs.extend(objectSupport); + +export class NextcloudIntegration extends Integration { + public async testConnectionAsync(): Promise { + const client = this.createCalendarClient(); + await client.login(); + } + + public async getCalendarEventsAsync(start: Date, end: Date): Promise { + const client = this.createCalendarClient(); + await client.login(); + + const calendars = await client.fetchCalendars(); + // Parameters must be in ISO-8601, See https://tsdav.vercel.app/docs/caldav/fetchCalendarObjects#arguments + const calendarEvents = ( + await Promise.all( + calendars.map( + async (calendar) => + await client.fetchCalendarObjects({ + calendar, + timeRange: { start: start.toISOString(), end: end.toISOString() }, + }), + ), + ) + ).flat(); + + return calendarEvents.map((event): CalendarEvent => { + // @ts-expect-error the typescript definitions for this package are wrong + // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access + const icalData = ical.default.parseICS(event.data) as ical.CalendarResponse; + const veventObject = Object.values(icalData).find((data) => data.type === "VEVENT"); + + if (!veventObject) { + throw new Error(`Invalid event data object: ${JSON.stringify(event.data)}. Unable to process the calendar.`); + } + + logger.debug(`Converting VEVENT event to ${event.etag} from Nextcloud: ${JSON.stringify(veventObject)}`); + + const date = dayjs.utc({ + days: veventObject.start.getDay(), + month: veventObject.start.getMonth(), + year: veventObject.start.getFullYear(), + hours: veventObject.start.getHours(), + minutes: veventObject.start.getMinutes(), + seconds: veventObject.start.getSeconds(), + }); + + const eventUrlWithoutHost = new URL(event.url).pathname; + const dateInMillis = veventObject.start.valueOf(); + + const url = this.url( + `/apps/calendar/timeGridWeek/now/edit/sidebar/${Buffer.from(eventUrlWithoutHost).toString("base64url")}/${dateInMillis / 1000}`, + ); + + return { + name: veventObject.summary, + date: date.toDate(), + subName: "", + description: veventObject.description, + links: [ + { + href: url.toString(), + name: "Nextcloud", + logo: "/images/apps/nextcloud.svg", + color: undefined, + notificationColor: "#ff8600", + isDark: true, + }, + ], + }; + }); + } + + private createCalendarClient() { + return new DAVClient({ + serverUrl: this.integration.url, + credentials: { + username: this.getSecretValue("username"), + password: this.getSecretValue("password"), + }, + authMethod: "Basic", + defaultAccountType: "caldav", + }); + } +} diff --git a/packages/widgets/src/calendar/calendar-event-list.tsx b/packages/widgets/src/calendar/calendar-event-list.tsx index 1c2c9283f..2b661ab72 100644 --- a/packages/widgets/src/calendar/calendar-event-list.tsx +++ b/packages/widgets/src/calendar/calendar-event-list.tsx @@ -41,7 +41,13 @@ export const CalendarEventList = ({ events }: CalendarEventListProps) => { {events.map((event, eventIndex) => ( - + {event.mediaInformation?.type === "tv" && ( = 0.6.0'} @@ -5649,6 +5658,9 @@ packages: engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} hasBin: true + cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + cross-fetch@4.1.0: resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} @@ -7631,6 +7643,12 @@ packages: engines: {node: '>=10'} hasBin: true + moment-timezone@0.5.47: + resolution: {integrity: sha512-UbNt/JAWS0m/NJOebR0QMRHBk0hu03r5dx9GK8Cs0AS3I81yDcOc9k+DytPItgVvBP7J6Mf6U2n3BPAacAV9oA==} + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + mpd-parser@1.3.1: resolution: {integrity: sha512-1FuyEWI5k2HcmhS1HkKnUAQV7yFPfXPht2DnRRGtoiiAAW+ESTbtEXIDpRkwdU+XyrQuwrIym7UkoPKsZ0SyFw==} hasBin: true @@ -7815,6 +7833,9 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true + node-ical@0.20.1: + resolution: {integrity: sha512-NrXgzDJd6XcyX9kDMJVA3xYCZmntY7ghA2BOdBeYr3iu8tydHOAb+68jPQhF9V2CRQ0/386X05XhmLzQUN0+Hw==} + node-loader@2.1.0: resolution: {integrity: sha512-OwjPkyh8+7jW8DMd/iq71uU1Sspufr/C2+c3t0p08J3CrM9ApZ4U53xuisNrDXOHyGi5OYHgtfmmh+aK9zJA6g==} engines: {node: '>= 10.13.0'} @@ -8795,6 +8816,9 @@ packages: rrdom@0.1.7: resolution: {integrity: sha512-ZLd8f14z9pUy2Hk9y636cNv5Y2BMnNEY99wxzW9tD2BLDfe1xFxtLjB4q/xCBYo6HRe0wofzKzjm4JojmpBfFw==} + rrule@2.8.1: + resolution: {integrity: sha512-hM3dHSBMeaJ0Ktp7W38BJZ7O1zOgaFEsn41PDk+yHoEtfLV+PoJt9E9xAlZiWgf/iqEqionN0ebHFZIDAp+iGw==} + rrweb-cssom@0.8.0: resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} @@ -9517,6 +9541,10 @@ packages: tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tsdav@2.1.3: + resolution: {integrity: sha512-TwPBYZKLlbJNtmfg5QzeGqRnOYZ4CCuII3D528+Vv8K/les0PmyB7sT7gf967a6SduJKxCVovWZ+Ei3O+cCAlg==} + engines: {node: '>=10'} + tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -10129,6 +10157,10 @@ packages: xml-but-prettier@1.0.1: resolution: {integrity: sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==} + xml-js@1.6.11: + resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + hasBin: true + xml-name-validator@5.0.0: resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} engines: {node: '>=18'} @@ -11220,7 +11252,7 @@ snapshots: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - '@mantine/notifications@7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@mantine/notifications@7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@mantine/core': 7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@mantine/hooks': 7.17.1(react@19.0.0) @@ -11229,7 +11261,7 @@ snapshots: react-dom: 19.0.0(react@19.0.0) react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@mantine/spotlight@7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@mantine/spotlight@7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@mantine/core': 7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@mantine/hooks': 7.17.1(react@19.0.0) @@ -13468,6 +13500,8 @@ snapshots: streamx: 2.20.1 optional: true + base-64@1.0.0: {} + base64-arraybuffer@1.0.2: {} base64-js@1.5.1: {} @@ -13929,6 +13963,12 @@ snapshots: dependencies: cross-spawn: 7.0.3 + cross-fetch@4.0.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + cross-fetch@4.1.0: dependencies: node-fetch: 2.7.0 @@ -16173,6 +16213,12 @@ snapshots: mkdirp@1.0.4: {} + moment-timezone@0.5.47: + dependencies: + moment: 2.30.1 + + moment@2.30.1: {} + mpd-parser@1.3.1: dependencies: '@babel/runtime': 7.25.6 @@ -16338,6 +16384,15 @@ snapshots: node-gyp-build@4.8.4: optional: true + node-ical@0.20.1: + dependencies: + axios: 1.7.7 + moment-timezone: 0.5.47 + rrule: 2.8.1 + uuid: 10.0.0 + transitivePeerDependencies: + - debug + node-loader@2.1.0(webpack@5.94.0): dependencies: loader-utils: 2.0.4 @@ -17386,6 +17441,10 @@ snapshots: dependencies: rrweb-snapshot: 2.0.0-alpha.4 + rrule@2.8.1: + dependencies: + tslib: 2.8.1 + rrweb-cssom@0.8.0: {} rrweb-player@1.0.0-alpha.4: @@ -18313,6 +18372,16 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tsdav@2.1.3: + dependencies: + base-64: 1.0.0 + cross-fetch: 4.0.0 + debug: 4.4.0 + xml-js: 1.6.11 + transitivePeerDependencies: + - encoding + - supports-color + tslib@1.14.1: {} tslib@2.7.0: {} @@ -18981,6 +19050,10 @@ snapshots: dependencies: repeat-string: 1.6.1 + xml-js@1.6.11: + dependencies: + sax: 1.4.1 + xml-name-validator@5.0.0: {} xml2js@0.6.2: From 4472c04967f0a3799507785b02f96a84c9626465 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sat, 8 Mar 2025 23:46:43 +0100 Subject: [PATCH 16/60] fix(indexer-manager): improve responsive styles (#2541) --- .../widgets/src/indexer-manager/component.tsx | 87 +++++++++++++------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/packages/widgets/src/indexer-manager/component.tsx b/packages/widgets/src/indexer-manager/component.tsx index 12aed440a..e406ffa8a 100644 --- a/packages/widgets/src/indexer-manager/component.tsx +++ b/packages/widgets/src/indexer-manager/component.tsx @@ -1,6 +1,6 @@ "use client"; -import { Anchor, Button, Card, Container, Flex, Group, ScrollArea, Text } from "@mantine/core"; +import { ActionIcon, Anchor, Button, Card, Flex, Group, ScrollArea, Stack, Text } from "@mantine/core"; import { IconCircleCheck, IconCircleX, IconReportSearch, IconTestPipe } from "@tabler/icons-react"; import combineClasses from "clsx"; @@ -11,7 +11,12 @@ import { useI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../definition"; import classes from "./component.module.css"; -export default function IndexerManagerWidget({ options, integrationIds }: WidgetComponentProps<"indexerManager">) { +export default function IndexerManagerWidget({ + options, + integrationIds, + width, + height, +}: WidgetComponentProps<"indexerManager">) { const t = useI18n(); const [indexersData] = clientApi.widget.indexerManager.getIndexersStatus.useSuspenseQuery( { integrationIds }, @@ -40,37 +45,60 @@ export default function IndexerManagerWidget({ options, integrationIds }: Widget }, ); + const hasSmallWidth = width < 256; + const hasSmallHeight = height < 256; + return ( - - - + + + {t("widget.indexerManager.title")} - + {hasSmallHeight && ( + { + testAll({ integrationIds }); + }} + > + + + )} + - + {indexersData.map(({ integrationId, indexers }) => ( - + {indexers.map((indexer) => ( - + {indexer.name} @@ -78,35 +106,38 @@ export default function IndexerManagerWidget({ options, integrationIds }: Widget ) : ( )} ))} - +
))} - + {!hasSmallHeight && ( + + )} ); } From 9e48f438b4550f542130651ea7dccccc36b59da8 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sat, 8 Mar 2025 23:54:57 +0100 Subject: [PATCH 17/60] fix(media-request-list): improve responsive styles (#2543) --- .../src/media-requests/list/component.tsx | 201 +++++++++--------- 1 file changed, 106 insertions(+), 95 deletions(-) diff --git a/packages/widgets/src/media-requests/list/component.tsx b/packages/widgets/src/media-requests/list/component.tsx index 07248d203..58499ecd4 100644 --- a/packages/widgets/src/media-requests/list/component.tsx +++ b/packages/widgets/src/media-requests/list/component.tsx @@ -16,6 +16,7 @@ export default function MediaServerWidget({ integrationIds, isEditMode, options, + width, }: WidgetComponentProps<"mediaRequests-requestList">) { const t = useScopedI18n("widget.mediaRequests-requestList"); const [mediaRequests] = clientApi.widget.mediaRequests.getLatestRequests.useSuspenseQuery( @@ -59,19 +60,21 @@ export default function MediaServerWidget({ if (mediaRequests.length === 0) throw new NoIntegrationDataError(); + const isTiny = width < 256; + return ( - + {mediaRequests.map((mediaRequest) => ( - - - - - {mediaRequest.airDate?.getFullYear() ?? t("toBeDetermined")} - - - {getAvailabilityProperties(mediaRequest.availability, t).label} - + {!isTiny && ( + + )} + + + + + + {mediaRequest.airDate?.getFullYear() ?? t("toBeDetermined")} + + {!isTiny && ( + + {getAvailabilityProperties(mediaRequest.availability, t).label} + + )} + + + + + {(mediaRequest.requestedBy?.displayName ?? "") || "unknown"} + + + + + + {mediaRequest.name || "unknown"} + + {mediaRequest.status === MediaRequestStatus.PendingApproval ? ( + + + { + mutateRequestAnswer({ + integrationId: mediaRequest.integrationId, + requestId: mediaRequest.id, + answer: "approve", + }); + }} + > + + + + + { + mutateRequestAnswer({ + integrationId: mediaRequest.integrationId, + requestId: mediaRequest.id, + answer: "decline", + }); + }} + > + + + + + ) : ( + + )} - - {mediaRequest.name || "unknown"} - - - - - - {(mediaRequest.requestedBy?.displayName ?? "") || "unknown"} - - - {mediaRequest.status === MediaRequestStatus.PendingApproval ? ( - - - { - mutateRequestAnswer({ - integrationId: mediaRequest.integrationId, - requestId: mediaRequest.id, - answer: "approve", - }); - }} - > - - - - - { - mutateRequestAnswer({ - integrationId: mediaRequest.integrationId, - requestId: mediaRequest.id, - answer: "decline", - }); - }} - > - - - - - ) : ( - - )} - ))} From d9720ac596c6780284d3aa67c0b1141761b1c06d Mon Sep 17 00:00:00 2001 From: "homarr-crowdin[bot]" <190541745+homarr-crowdin[bot]@users.noreply.github.com> Date: Sun, 9 Mar 2025 00:42:54 +0000 Subject: [PATCH 18/60] chore(lang): updated translations from crowdin Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com> --- packages/translation/src/lang/ca.json | 6 ++++++ packages/translation/src/lang/cn.json | 6 ++++++ packages/translation/src/lang/cs.json | 6 ++++++ packages/translation/src/lang/da.json | 6 ++++++ packages/translation/src/lang/de.json | 6 ++++++ packages/translation/src/lang/el.json | 6 ++++++ packages/translation/src/lang/es.json | 6 ++++++ packages/translation/src/lang/et.json | 6 ++++++ packages/translation/src/lang/fr.json | 6 ++++++ packages/translation/src/lang/he.json | 6 ++++++ packages/translation/src/lang/hr.json | 6 ++++++ packages/translation/src/lang/hu.json | 6 ++++++ packages/translation/src/lang/it.json | 6 ++++++ packages/translation/src/lang/ja.json | 8 +++++++- packages/translation/src/lang/ko.json | 6 ++++++ packages/translation/src/lang/lt.json | 6 ++++++ packages/translation/src/lang/lv.json | 6 ++++++ packages/translation/src/lang/nl.json | 6 ++++++ packages/translation/src/lang/no.json | 6 ++++++ packages/translation/src/lang/pl.json | 6 ++++++ packages/translation/src/lang/pt.json | 6 ++++++ packages/translation/src/lang/ro.json | 6 ++++++ packages/translation/src/lang/ru.json | 6 ++++++ packages/translation/src/lang/sk.json | 6 ++++++ packages/translation/src/lang/sl.json | 6 ++++++ packages/translation/src/lang/sv.json | 6 ++++++ packages/translation/src/lang/tr.json | 12 +++++++++--- packages/translation/src/lang/uk.json | 6 ++++++ packages/translation/src/lang/vi.json | 6 ++++++ packages/translation/src/lang/zh.json | 6 ++++++ 30 files changed, 184 insertions(+), 4 deletions(-) diff --git a/packages/translation/src/lang/ca.json b/packages/translation/src/lang/ca.json index 76472b46b..7e1402759 100644 --- a/packages/translation/src/lang/ca.json +++ b/packages/translation/src/lang/ca.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/cn.json b/packages/translation/src/lang/cn.json index 19a6c035a..1c99f7207 100644 --- a/packages/translation/src/lang/cn.json +++ b/packages/translation/src/lang/cn.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "网格" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "隐藏图标" }, diff --git a/packages/translation/src/lang/cs.json b/packages/translation/src/lang/cs.json index 3d514ce9a..d53e222d0 100644 --- a/packages/translation/src/lang/cs.json +++ b/packages/translation/src/lang/cs.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/da.json b/packages/translation/src/lang/da.json index 6921a2407..422628c8a 100644 --- a/packages/translation/src/lang/da.json +++ b/packages/translation/src/lang/da.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Gitter" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "Skjul ikoner" }, diff --git a/packages/translation/src/lang/de.json b/packages/translation/src/lang/de.json index 3d63c36fd..cf1f486af 100644 --- a/packages/translation/src/lang/de.json +++ b/packages/translation/src/lang/de.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Raster" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "Symbole verbergen" }, diff --git a/packages/translation/src/lang/el.json b/packages/translation/src/lang/el.json index 0a459085f..e791e84e8 100644 --- a/packages/translation/src/lang/el.json +++ b/packages/translation/src/lang/el.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/es.json b/packages/translation/src/lang/es.json index f7a43df34..3dd2cdcf7 100644 --- a/packages/translation/src/lang/es.json +++ b/packages/translation/src/lang/es.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/et.json b/packages/translation/src/lang/et.json index c0fd6eab7..356bd4635 100644 --- a/packages/translation/src/lang/et.json +++ b/packages/translation/src/lang/et.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/fr.json b/packages/translation/src/lang/fr.json index d8f2356a3..0fcb6ef65 100644 --- a/packages/translation/src/lang/fr.json +++ b/packages/translation/src/lang/fr.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/he.json b/packages/translation/src/lang/he.json index 2393a28a2..669f44978 100644 --- a/packages/translation/src/lang/he.json +++ b/packages/translation/src/lang/he.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "רשת" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "הסתרת אייקונים" }, diff --git a/packages/translation/src/lang/hr.json b/packages/translation/src/lang/hr.json index bcb171837..417ce24a4 100644 --- a/packages/translation/src/lang/hr.json +++ b/packages/translation/src/lang/hr.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/hu.json b/packages/translation/src/lang/hu.json index 34b280f3c..07fdfd420 100644 --- a/packages/translation/src/lang/hu.json +++ b/packages/translation/src/lang/hu.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Rács" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/it.json b/packages/translation/src/lang/it.json index 84b28fd73..c0008e707 100644 --- a/packages/translation/src/lang/it.json +++ b/packages/translation/src/lang/it.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/ja.json b/packages/translation/src/lang/ja.json index 325bbdfdf..dfce0b80c 100644 --- a/packages/translation/src/lang/ja.json +++ b/packages/translation/src/lang/ja.json @@ -43,7 +43,7 @@ "entities": { "apps": "アプリ", "boards": "ボード", - "integrations": "", + "integrations": "インテグレーション", "credentialUsers": "" } }, @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/ko.json b/packages/translation/src/lang/ko.json index fbe2cb435..ec8243f9d 100644 --- a/packages/translation/src/lang/ko.json +++ b/packages/translation/src/lang/ko.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/lt.json b/packages/translation/src/lang/lt.json index 5cf2a245d..8cb718897 100644 --- a/packages/translation/src/lang/lt.json +++ b/packages/translation/src/lang/lt.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/lv.json b/packages/translation/src/lang/lv.json index a24f515a4..0943fdc9b 100644 --- a/packages/translation/src/lang/lv.json +++ b/packages/translation/src/lang/lv.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/nl.json b/packages/translation/src/lang/nl.json index 558f305ce..a17a839ee 100644 --- a/packages/translation/src/lang/nl.json +++ b/packages/translation/src/lang/nl.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Raster" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "Iconen verbergen" }, diff --git a/packages/translation/src/lang/no.json b/packages/translation/src/lang/no.json index 914ea33c0..67a0e116f 100644 --- a/packages/translation/src/lang/no.json +++ b/packages/translation/src/lang/no.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Rutenettet" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "Skjul ikoner" }, diff --git a/packages/translation/src/lang/pl.json b/packages/translation/src/lang/pl.json index 03fd332f5..ae3392882 100644 --- a/packages/translation/src/lang/pl.json +++ b/packages/translation/src/lang/pl.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Siatka" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "Ukryj ikony" }, diff --git a/packages/translation/src/lang/pt.json b/packages/translation/src/lang/pt.json index 1a40755ab..7c4c855ed 100644 --- a/packages/translation/src/lang/pt.json +++ b/packages/translation/src/lang/pt.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/ro.json b/packages/translation/src/lang/ro.json index 2295b60c6..1727513e9 100644 --- a/packages/translation/src/lang/ro.json +++ b/packages/translation/src/lang/ro.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/ru.json b/packages/translation/src/lang/ru.json index 153c533d1..c9c685aef 100644 --- a/packages/translation/src/lang/ru.json +++ b/packages/translation/src/lang/ru.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Сетка" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "Скрывать иконки" }, diff --git a/packages/translation/src/lang/sk.json b/packages/translation/src/lang/sk.json index a8e3f6723..b2e00afb9 100644 --- a/packages/translation/src/lang/sk.json +++ b/packages/translation/src/lang/sk.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Mriežka" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "Skryť ikony" }, diff --git a/packages/translation/src/lang/sl.json b/packages/translation/src/lang/sl.json index f5135bc6b..edc4ddb1a 100644 --- a/packages/translation/src/lang/sl.json +++ b/packages/translation/src/lang/sl.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/sv.json b/packages/translation/src/lang/sv.json index e70244e9e..1e9664a87 100644 --- a/packages/translation/src/lang/sv.json +++ b/packages/translation/src/lang/sv.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/tr.json b/packages/translation/src/lang/tr.json index 76832c090..7b2fa9275 100644 --- a/packages/translation/src/lang/tr.json +++ b/packages/translation/src/lang/tr.json @@ -1072,7 +1072,7 @@ "label": "Özel CSS Alanı" }, "borderColor": { - "label": "" + "label": "Kenarlık rengi" } } }, @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Izgara" + }, + "gridHorizontal": { + "label": "Yatay ızgara" } } }, + "hideTitle": { + "label": "Başlığı gizle" + }, "hideIcon": { "label": "Simgeleri gizle" }, @@ -2168,7 +2174,7 @@ "title": "Arkaplan" }, "appearance": { - "title": "Görünüş" + "title": "Görünüm" }, "customCss": { "title": "Özel Css" @@ -2609,7 +2615,7 @@ } }, "appearance": { - "title": "Görünüş", + "title": "Görünüm", "defaultColorScheme": { "label": "Öntanımlı Renk Düzeni", "options": { diff --git a/packages/translation/src/lang/uk.json b/packages/translation/src/lang/uk.json index 9b7e14e2d..1712a22ed 100644 --- a/packages/translation/src/lang/uk.json +++ b/packages/translation/src/lang/uk.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "Сітка" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/vi.json b/packages/translation/src/lang/vi.json index 682ab0bbc..60db5bd00 100644 --- a/packages/translation/src/lang/vi.json +++ b/packages/translation/src/lang/vi.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "" }, diff --git a/packages/translation/src/lang/zh.json b/packages/translation/src/lang/zh.json index 65bd3da31..4e282878a 100644 --- a/packages/translation/src/lang/zh.json +++ b/packages/translation/src/lang/zh.json @@ -1127,9 +1127,15 @@ }, "grid": { "label": "網格" + }, + "gridHorizontal": { + "label": "" } } }, + "hideTitle": { + "label": "" + }, "hideIcon": { "label": "隱藏 icons" }, From 82528dbd961b21682d71b104b22804391b6c7d08 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sun, 9 Mar 2025 14:20:04 +0100 Subject: [PATCH 19/60] fix(media-server): improve responsive styles (#2548) * fix(media-server): improve responsive styles * fix(media-server): translate table headers --- packages/translation/src/lang/en.json | 1 + .../widgets/src/media-server/component.tsx | 152 ++++++++++-------- 2 files changed, 88 insertions(+), 65 deletions(-) diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 7c664d97d..8a7cdd148 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1665,6 +1665,7 @@ "description": "Show the current streams on your media servers", "option": {}, "items": { + "currentlyPlaying": "Currently playing", "user": "User", "name": "Name", "id": "Id" diff --git a/packages/widgets/src/media-server/component.tsx b/packages/widgets/src/media-server/component.tsx index a52c0ee8f..146f7915f 100644 --- a/packages/widgets/src/media-server/component.tsx +++ b/packages/widgets/src/media-server/component.tsx @@ -1,8 +1,9 @@ "use client"; +import type { ReactNode } from "react"; import { useMemo } from "react"; -import { Avatar, Box, Flex, Group, Stack, Text, Title } from "@mantine/core"; -import { IconDeviceAudioTape, IconDeviceTv, IconMovie, IconVideo } from "@tabler/icons-react"; +import { Avatar, Flex, Group, Stack, Text, Title } from "@mantine/core"; +import { IconDeviceTv, IconHeadphones, IconMovie, IconVideo } from "@tabler/icons-react"; import type { MRT_ColumnDef } from "mantine-react-table"; import { MantineReactTable } from "mantine-react-table"; @@ -11,6 +12,7 @@ import { getIconUrl, integrationDefs } from "@homarr/definitions"; import type { StreamSession } from "@homarr/integrations"; import { createModal, useModalAction } from "@homarr/modals"; import { useScopedI18n } from "@homarr/translation/client"; +import type { TablerIcon } from "@homarr/ui"; import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; import type { WidgetComponentProps } from "../definition"; @@ -28,59 +30,51 @@ export default function MediaServerWidget({ integrationIds, isEditMode }: Widget ); const utils = clientApi.useUtils(); + const t = useScopedI18n("widget.mediaServer"); const columns = useMemo[]>( () => [ { accessorKey: "sessionName", - header: "Name", - mantineTableHeadCellProps: { - style: { - width: "30%", - }, - }, + header: t("items.name"), + Cell: ({ row }) => ( - + {row.original.sessionName} ), }, { accessorKey: "user.username", - header: "User", - mantineTableHeadCellProps: { - style: { - width: "25%", - }, - }, + header: t("items.user"), + Cell: ({ row }) => ( - - - {row.original.user.username} + + + {row.original.user.username} ), }, { accessorKey: "currentlyPlaying", // currentlyPlaying.name can be undefined which results in a warning. This is why we use currentlyPlaying instead of currentlyPlaying.name - header: "Currently playing", - mantineTableHeadCellProps: { - style: { - width: "45%", - }, - }, - Cell: ({ row }) => { - if (row.original.currentlyPlaying) { - return ( - - {row.original.currentlyPlaying.name} - - ); - } + header: t("items.currentlyPlaying"), - return null; + Cell: ({ row }) => { + if (!row.original.currentlyPlaying) return null; + + const Icon = mediaTypeIconMap[row.original.currentlyPlaying.type]; + + return ( + + + + {row.original.currentlyPlaying.name} + + + ); }, }, ], - [], + [t], ); clientApi.widget.mediaServer.subscribeToCurrentStreams.useSubscription( @@ -137,8 +131,18 @@ export default function MediaServerWidget({ integrationIds, isEditMode }: Widget enableDensityToggle: false, enableFilters: false, enableHiding: false, + enableColumnPinning: true, initialState: { density: "xs", + columnPinning: { + right: ["currentlyPlaying"], + }, + }, + mantineTableHeadProps: { + fz: "xs", + }, + mantineTableHeadCellProps: { + py: 4, }, mantinePaperProps: { flex: 1, @@ -158,20 +162,16 @@ export default function MediaServerWidget({ integrationIds, isEditMode }: Widget }, mantineTableBodyCellProps: ({ row }) => ({ onClick: () => { - openModal({ - item: row.original, - title: - row.original.currentlyPlaying?.type === "movie" ? ( - - ) : row.original.currentlyPlaying?.type === "tv" ? ( - - ) : row.original.currentlyPlaying?.type === "video" ? ( - - ) : ( - - ), - }); + openModal( + { + item: row.original, + }, + { + title: row.original.sessionName, + }, + ); }, + py: 4, }), }); @@ -210,42 +210,64 @@ export default function MediaServerWidget({ integrationIds, isEditMode }: Widget ); } -const itemInfoModal = createModal<{ item: StreamSession; title: React.ReactNode }>(({ innerProps }) => { +const itemInfoModal = createModal<{ item: StreamSession }>(({ innerProps }) => { const t = useScopedI18n("widget.mediaServer.items"); + const Icon = innerProps.item.currentlyPlaying ? mediaTypeIconMap[innerProps.item.currentlyPlaying.type] : null; return ( - {innerProps.title} - {innerProps.item.currentlyPlaying?.name} - - {innerProps.item.currentlyPlaying?.episodeName} - {innerProps.item.currentlyPlaying?.seasonName && ( - <> - {" - "} - {innerProps.item.currentlyPlaying.seasonName} - - )} - + {Icon && innerProps.item.currentlyPlaying !== null && ( + + + {innerProps.item.currentlyPlaying.name} + + )} + {innerProps.item.currentlyPlaying?.episodeName && ( + + {innerProps.item.currentlyPlaying.episodeName} + {innerProps.item.currentlyPlaying.seasonName && ( + <> + {" - "} + {innerProps.item.currentlyPlaying.seasonName} + + )} + + )} - - - + + {" "} + {innerProps.item.user.username} + + } + /> + {innerProps.item.sessionName}} /> + {innerProps.item.sessionId}} /> ); }).withOptions({ defaultTitle() { return ""; }, - size: "auto", + size: "lg", centered: true, }); -const NormalizedLine = ({ itemKey, value }: { itemKey: string; value: string }) => { +const NormalizedLine = ({ itemKey, value }: { itemKey: string; value: ReactNode }) => { return ( {itemKey}: - {value} + {value} ); }; + +const mediaTypeIconMap = { + movie: IconMovie, + tv: IconDeviceTv, + video: IconVideo, + audio: IconHeadphones, +} satisfies Record["type"], TablerIcon>; From d584ade8f4a788b284071cb9d17b6d8b606098c8 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sun, 9 Mar 2025 14:20:23 +0100 Subject: [PATCH 20/60] fix(media-request-stats): improve responsive styles (#2544) * fix(media-request-stats): improve responsive styles * fix(media-request-stats): put user to start --- .../src/media-requests/stats/component.tsx | 153 ++++++++---------- 1 file changed, 70 insertions(+), 83 deletions(-) diff --git a/packages/widgets/src/media-requests/stats/component.tsx b/packages/widgets/src/media-requests/stats/component.tsx index 59be66653..87e7da8aa 100644 --- a/packages/widgets/src/media-requests/stats/component.tsx +++ b/packages/widgets/src/media-requests/stats/component.tsx @@ -1,11 +1,9 @@ "use client"; -import { ActionIcon, Avatar, Card, Grid, Group, Space, Stack, Text, Tooltip } from "@mantine/core"; -import { useElementSize } from "@mantine/hooks"; +import { Avatar, Card, Grid, Group, Stack, Text, Tooltip } from "@mantine/core"; import type { Icon } from "@tabler/icons-react"; import { IconDeviceTv, - IconExternalLink, IconHourglass, IconLoaderQuarter, IconMovie, @@ -28,6 +26,7 @@ import classes from "./component.module.css"; export default function MediaServerWidget({ integrationIds, isEditMode, + width, }: WidgetComponentProps<"mediaRequests-requestStats">) { const t = useScopedI18n("widget.mediaRequests-requestStats"); const [requestStats] = clientApi.widget.mediaRequests.getStats.useSuspenseQuery( @@ -41,8 +40,6 @@ export default function MediaServerWidget({ }, ); - const { width, height, ref } = useElementSize(); - const board = useRequiredBoard(); if (requestStats.users.length === 0 && requestStats.stats.length === 0) throw new NoIntegrationDataError(); @@ -90,94 +87,84 @@ export default function MediaServerWidget({ }, ] satisfies { name: keyof RequestStats; icon: Icon; number: number }[]; + const isTiny = width < 256; + return ( - - {t("titles.stats.main")} - - - {data.map((stat) => ( - - - - - - - {stat.number} - - - - - - ))} - - - {t("titles.users.main")} - - - {requestStats.users.slice(0, Math.max(Math.floor((height / width) * 5), 1)).map((user) => ( - - - - + + + {t("titles.stats.main")} + + + {data.map((stat) => ( + + + + + + + {stat.number} + + + - - - {user.displayName} + + ))} + + + + + {t("titles.users.main")} ({t("titles.users.requests")}) + + + {requestStats.users.slice(0, 10).map((user) => ( + + + + + + + + {user.displayName} + + + + + {user.requestCount} - - {`${t("titles.users.requests")}: ${user.requestCount}`} - - - - - - - - - ))} + + + ))} + ); From 8f8d7884a9484aa8e73f4ff114e58df78a8bb470 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sun, 9 Mar 2025 14:22:12 +0100 Subject: [PATCH 21/60] fix(media-transcoding): improve responsive styles (#2550) * fix(media-transcoding): improve responsive styles * fix: typecheck issue --- packages/translation/src/lang/en.json | 8 +- .../src/media-transcoding/component.tsx | 108 +++++++------ .../media-transcoding/health-check-status.tsx | 4 +- .../widgets/src/media-transcoding/index.ts | 10 +- .../media-transcoding/panels/queue.panel.tsx | 54 ++++--- .../panels/statistics.panel.tsx | 147 +++++++----------- .../panels/workers.panel.tsx | 122 +++++++++------ 7 files changed, 224 insertions(+), 229 deletions(-) diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 8a7cdd148..e2dc60cef 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1890,10 +1890,10 @@ "statistics": { "empty": "Empty", "transcodes": "Transcodes", - "transcodesCount": "Transcodes: {value}", - "healthChecksCount": "Health checks: {value}", - "filesCount": "Files: {value}", - "savedSpace": "Saved space: {value}", + "transcodesCount": "Transcodes", + "healthChecksCount": "Health checks", + "filesCount": "Files", + "savedSpace": "Saved space", "healthChecks": "Health checks", "videoCodecs": "Codecs", "videoContainers": "Containers", diff --git a/packages/widgets/src/media-transcoding/component.tsx b/packages/widgets/src/media-transcoding/component.tsx index 10342ec6a..cad468681 100644 --- a/packages/widgets/src/media-transcoding/component.tsx +++ b/packages/widgets/src/media-transcoding/component.tsx @@ -2,20 +2,32 @@ import { useState } from "react"; import { Center, Divider, Group, Pagination, SegmentedControl, Stack, Text } from "@mantine/core"; +import type { TablerIcon } from "@tabler/icons-react"; import { IconClipboardList, IconCpu2, IconReportAnalytics } from "@tabler/icons-react"; import { clientApi } from "@homarr/api/client"; import { useI18n } from "@homarr/translation/client"; +import { views } from "."; import type { WidgetComponentProps } from "../definition"; import { HealthCheckStatus } from "./health-check-status"; import { QueuePanel } from "./panels/queue.panel"; import { StatisticsPanel } from "./panels/statistics.panel"; import { WorkersPanel } from "./panels/workers.panel"; -type Views = "workers" | "queue" | "statistics"; +type View = (typeof views)[number]; -export default function MediaTranscodingWidget({ integrationIds, options }: WidgetComponentProps<"mediaTranscoding">) { +const viewIcons = { + workers: IconCpu2, + queue: IconClipboardList, + statistics: IconReportAnalytics, +} satisfies Record; + +export default function MediaTranscodingWidget({ + integrationIds, + options, + width, +}: WidgetComponentProps<"mediaTranscoding">) { const [queuePage, setQueuePage] = useState(1); const queuePageSize = 10; const [transcodingData] = clientApi.widget.mediaTranscoding.getDataAsync.useSuspenseQuery( @@ -31,15 +43,16 @@ export default function MediaTranscodingWidget({ integrationIds, options }: Widg }, ); - const [view, setView] = useState(options.defaultView); + const [view, setView] = useState(options.defaultView); const totalQueuePages = Math.ceil((transcodingData.data.queue.totalCount || 1) / queuePageSize); const t = useI18n("widget.mediaTranscoding"); + const isTiny = width < 256; return ( {view === "workers" ? ( - + ) : view === "queue" ? ( ) : ( @@ -48,65 +61,48 @@ export default function MediaTranscodingWidget({ integrationIds, options }: Widg { + const Icon = viewIcons[value]; + return { label: ( -
- - - {t("tab.workers")} - +
+ + {!isTiny && ( + + {t(`tab.${value}`)} + + )}
), - value: "workers", - }, - { - label: ( -
- - - {t("tab.queue")} - -
- ), - value: "queue", - }, - { - label: ( -
- - - {t("tab.statistics")} - -
- ), - value: "statistics", - }, - ]} + value, + }; + })} value={view} - onChange={(value) => setView(value as Views)} + onChange={(value) => setView(value as View)} size="xs" /> - {view === "queue" && ( - <> - - - - - - - - - - {t("currentIndex", { - start: transcodingData.data.queue.startIndex + 1, - end: transcodingData.data.queue.endIndex + 1, - total: transcodingData.data.queue.totalCount, - })} - - - )} + + {view === "queue" && ( + <> + + + {!isTiny && } + + + {!isTiny && } + + + + {t("currentIndex", { + start: transcodingData.data.queue.startIndex + 1, + end: transcodingData.data.queue.endIndex + 1, + total: transcodingData.data.queue.totalCount, + })} + + + )} + diff --git a/packages/widgets/src/media-transcoding/health-check-status.tsx b/packages/widgets/src/media-transcoding/health-check-status.tsx index 6491f6289..d1b3f7df9 100644 --- a/packages/widgets/src/media-transcoding/health-check-status.tsx +++ b/packages/widgets/src/media-transcoding/health-check-status.tsx @@ -23,8 +23,8 @@ export function HealthCheckStatus(props: HealthCheckStatusProps) { return ( - - + + diff --git a/packages/widgets/src/media-transcoding/index.ts b/packages/widgets/src/media-transcoding/index.ts index 355f3d9d3..0c6239eea 100644 --- a/packages/widgets/src/media-transcoding/index.ts +++ b/packages/widgets/src/media-transcoding/index.ts @@ -1,20 +1,20 @@ import { IconTransform } from "@tabler/icons-react"; import { z } from "zod"; +import { capitalize } from "@homarr/common"; + import { createWidgetDefinition } from "../definition"; import { optionsBuilder } from "../options"; +export const views = ["workers", "queue", "statistics"] as const; + export const { componentLoader, definition } = createWidgetDefinition("mediaTranscoding", { icon: IconTransform, createOptions() { return optionsBuilder.from((factory) => ({ defaultView: factory.select({ defaultValue: "statistics", - options: [ - { label: "Workers", value: "workers" }, - { label: "Queue", value: "queue" }, - { label: "Statistics", value: "statistics" }, - ], + options: views.map((view) => ({ label: capitalize(view), value: view })), }), queuePageSize: factory.number({ defaultValue: 10, validate: z.number().min(1).max(30) }), })); diff --git a/packages/widgets/src/media-transcoding/panels/queue.panel.tsx b/packages/widgets/src/media-transcoding/panels/queue.panel.tsx index 9d4d6a680..45cc7581f 100644 --- a/packages/widgets/src/media-transcoding/panels/queue.panel.tsx +++ b/packages/widgets/src/media-transcoding/panels/queue.panel.tsx @@ -1,4 +1,4 @@ -import { Center, Group, ScrollArea, Table, Text, Title, Tooltip } from "@mantine/core"; +import { Center, Group, ScrollArea, Table, TableTd, TableTh, TableTr, Text, Title, Tooltip } from "@mantine/core"; import { IconHeartbeat, IconTransform } from "@tabler/icons-react"; import { humanFileSize } from "@homarr/common"; @@ -17,7 +17,7 @@ export function QueuePanel(props: QueuePanelProps) { if (queue.array.length === 0) { return (
- {t("empty")} + {t("empty")}
); } @@ -26,36 +26,42 @@ export function QueuePanel(props: QueuePanelProps) { - - - - + + + + {t("table.file")} + + + + + {t("table.size")} + + + {queue.array.map((item) => ( - - - - + + ))}
{t("table.file")}{t("table.size")}
- -
- {item.type === "transcode" ? ( - - - - ) : ( - - - - )} -
+ + + + {item.type === "transcode" ? ( + + + + ) : ( + + + + )} {item.filePath.split("\\").pop()?.split("/").pop() ?? item.filePath} -
+ + {humanFileSize(item.fileSize)} -
diff --git a/packages/widgets/src/media-transcoding/panels/statistics.panel.tsx b/packages/widgets/src/media-transcoding/panels/statistics.panel.tsx index 93da0c0ce..23ab97563 100644 --- a/packages/widgets/src/media-transcoding/panels/statistics.panel.tsx +++ b/packages/widgets/src/media-transcoding/panels/statistics.panel.tsx @@ -1,11 +1,12 @@ -import type react from "react"; import type { MantineColor, RingProgressProps } from "@mantine/core"; -import { Box, Center, Grid, Group, RingProgress, Stack, Text, Title, useMantineColorScheme } from "@mantine/core"; +import { Card, Center, Group, RingProgress, ScrollArea, Stack, Text, Title, Tooltip } from "@mantine/core"; import { IconDatabaseHeart, IconFileDescription, IconHeartbeat, IconTransform } from "@tabler/icons-react"; +import { useRequiredBoard } from "@homarr/boards/context"; import { humanFileSize } from "@homarr/common"; import type { TdarrPieSegment, TdarrStatistics } from "@homarr/integrations"; import { useI18n } from "@homarr/translation/client"; +import type { TablerIcon } from "@homarr/ui"; const PIE_COLORS: MantineColor[] = ["cyan", "grape", "gray", "orange", "pink"]; @@ -21,90 +22,54 @@ export function StatisticsPanel(props: StatisticsPanelProps) { if (!allLibs) { return (
- {t("empty")} + {t("empty")}
); } return ( - - - - - {t("transcodes")} - - - - } - label={t("transcodesCount", { - value: props.statistics.totalTranscodeCount, - })} - /> - - - } - label={t("healthChecksCount", { - value: props.statistics.totalHealthCheckCount, - })} - /> - - - } - label={t("filesCount", { - value: props.statistics.totalFileCount, - })} - /> - - - } - label={t("savedSpace", { - value: humanFileSize(Math.floor(allLibs.savedSpace)), - })} - /> - - - - - {t("healthChecks")} - + + + + + + - - - - {t("videoCodecs")} - - - - {t("videoContainers")} - - - - {t("videoResolutions")} - + + + + + + - +
); } +interface StatisticRingProgressProps { + items: TdarrPieSegment[]; + label: string; +} + +const StatisticRingProgress = ({ items, label }: StatisticRingProgressProps) => { + return ( + + + {label} + + + + ); +}; + function toRingProgressSections(segments: TdarrPieSegment[]): RingProgressProps["sections"] { const total = segments.reduce((prev, curr) => prev + curr.value, 0); return segments.map((segment, index) => ({ @@ -115,26 +80,22 @@ function toRingProgressSections(segments: TdarrPieSegment[]): RingProgressProps[ })); } -interface StatBoxProps { - icon: react.ReactNode; +interface StatisticItemProps { + icon: TablerIcon; + value: string | number; label: string; } -function StatBox(props: StatBoxProps) { - const { colorScheme } = useMantineColorScheme(); +function StatisticItem(props: StatisticItemProps) { + const board = useRequiredBoard(); return ( - ({ - padding: theme.spacing.xs, - border: "1px solid", - borderRadius: theme.radius.md, - borderColor: colorScheme === "dark" ? theme.colors.dark[5] : theme.colors.gray[1], - })} - > - - {props.icon} - {props.label} - - + + + + + {props.value} + + + ); } diff --git a/packages/widgets/src/media-transcoding/panels/workers.panel.tsx b/packages/widgets/src/media-transcoding/panels/workers.panel.tsx index 961ac5d7c..d1602c248 100644 --- a/packages/widgets/src/media-transcoding/panels/workers.panel.tsx +++ b/packages/widgets/src/media-transcoding/panels/workers.panel.tsx @@ -1,4 +1,16 @@ -import { Center, Group, Progress, ScrollArea, Table, Text, Title, Tooltip } from "@mantine/core"; +import { + Center, + Group, + Progress, + ScrollArea, + Table, + TableTd, + TableTh, + TableTr, + Text, + Title, + Tooltip, +} from "@mantine/core"; import { IconHeartbeat, IconTransform } from "@tabler/icons-react"; import type { TdarrWorker } from "@homarr/integrations"; @@ -6,6 +18,7 @@ import { useI18n } from "@homarr/translation/client"; interface WorkersPanelProps { workers: TdarrWorker[]; + isTiny: boolean; } export function WorkersPanel(props: WorkersPanelProps) { @@ -14,7 +27,7 @@ export function WorkersPanel(props: WorkersPanelProps) { if (props.workers.length === 0) { return (
- {t("empty")} + {t("empty")}
); } @@ -23,52 +36,71 @@ export function WorkersPanel(props: WorkersPanelProps) { - - - - - + + + + {t("table.file")} + + + + + {t("table.eta")} + + + + + {t("table.progress")} + + + - {props.workers.map((worker) => ( - - - - - - ))} + {Math.round(worker.percentage)}% + + + + ); + })}
{t("table.file")}{t("table.eta")}{t("table.progress")}
- -
- {worker.jobType === "transcode" ? ( - - - - ) : ( - - - + {props.workers.map((worker) => { + const fileName = worker.filePath.split("\\").pop()?.split("/").pop() ?? worker.filePath; + return ( + + + +
+ {worker.jobType === "transcode" ? ( + + + + ) : ( + + + + )} +
+ + {fileName} + +
+
+ + {worker.ETA.startsWith("0:") ? worker.ETA.substring(2) : worker.ETA} + + + + {!props.isTiny && ( + <> + {worker.step} + + )} -
- - {worker.filePath.split("\\").pop()?.split("/").pop() ?? worker.filePath} - -
-
- {worker.ETA.startsWith("0:") ? worker.ETA.substring(2) : worker.ETA} - - - {worker.step} - - {Math.round(worker.percentage)}% - -
From 2f80c096a7e25b1a223336644f40a56311e1c7a8 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sun, 9 Mar 2025 14:24:27 +0100 Subject: [PATCH 22/60] fix(minecraft-status): wrong api path for bedrock (#2551) --- .../request-handler/src/minecraft-server-status.ts | 2 +- .../src/minecraft/server-status/component.tsx | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/request-handler/src/minecraft-server-status.ts b/packages/request-handler/src/minecraft-server-status.ts index d2b98fcc3..22eaf7a38 100644 --- a/packages/request-handler/src/minecraft-server-status.ts +++ b/packages/request-handler/src/minecraft-server-status.ts @@ -9,7 +9,7 @@ export const minecraftServerStatusRequestHandler = createCachedWidgetRequestHand queryKey: "minecraftServerStatusApiResult", widgetKind: "minecraftServerStatus", async requestAsync(input: { domain: string; isBedrockServer: boolean }) { - const path = `/3/${input.isBedrockServer ? "bedrock/" : ""}${input.domain}`; + const path = `${input.isBedrockServer ? "/bedrock" : ""}/3/${input.domain}`; const response = await fetchWithTimeout(`https://api.mcsrvstat.us${path}`); return responseSchema.parse(await response.json()); diff --git a/packages/widgets/src/minecraft/server-status/component.tsx b/packages/widgets/src/minecraft/server-status/component.tsx index 5ae024714..0d24784f7 100644 --- a/packages/widgets/src/minecraft/server-status/component.tsx +++ b/packages/widgets/src/minecraft/server-status/component.tsx @@ -36,7 +36,7 @@ export default function MinecraftServerStatusWidget({ options }: WidgetComponent > - + {title} @@ -44,11 +44,13 @@ export default function MinecraftServerStatusWidget({ options }: WidgetComponent {data.online && ( <> - {`minecraft + {!options.isBedrockServer && ( + {`minecraft + )} From f6f0d7c72bd4b91949f957e5e28ff60e6c82d2a5 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Sun, 9 Mar 2025 14:26:31 +0100 Subject: [PATCH 23/60] feat(calendar): add show-unmonitored option (#2547) * feat(calendar): add show-unmonitored option * fix: typecheck issue --- packages/api/src/router/widgets/calendar.ts | 9 ++++++++- .../cron-jobs/src/jobs/integrations/media-organizer.ts | 1 + packages/old-import/src/widgets/options.ts | 1 + packages/request-handler/src/calendar.ts | 8 ++++++-- packages/translation/src/lang/en.json | 3 +++ packages/widgets/src/calendar/component.tsx | 1 + packages/widgets/src/calendar/index.ts | 3 +++ 7 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/api/src/router/widgets/calendar.ts b/packages/api/src/router/widgets/calendar.ts index a11c69d40..f8062d539 100644 --- a/packages/api/src/router/widgets/calendar.ts +++ b/packages/api/src/router/widgets/calendar.ts @@ -9,7 +9,14 @@ import { createTRPCRouter, publicProcedure } from "../../trpc"; export const calendarRouter = createTRPCRouter({ findAllEvents: publicProcedure - .input(z.object({ year: z.number(), month: z.number(), releaseType: z.array(z.enum(radarrReleaseTypes)) })) + .input( + z.object({ + year: z.number(), + month: z.number(), + releaseType: z.array(z.enum(radarrReleaseTypes)), + showUnmonitored: z.boolean(), + }), + ) .unstable_concat(createManyIntegrationMiddleware("query", ...getIntegrationKindsByCategory("calendar"))) .query(async ({ ctx, input }) => { const results = await Promise.all( diff --git a/packages/cron-jobs/src/jobs/integrations/media-organizer.ts b/packages/cron-jobs/src/jobs/integrations/media-organizer.ts index 1d7128e4d..a84696da9 100644 --- a/packages/cron-jobs/src/jobs/integrations/media-organizer.ts +++ b/packages/cron-jobs/src/jobs/integrations/media-organizer.ts @@ -25,6 +25,7 @@ export const mediaOrganizerJob = createCronJob("mediaOrganizer", EVERY_MINUTE).w year, month, releaseType: options.releaseType, + showUnmonitored: options.showUnmonitored, }); } diff --git a/packages/old-import/src/widgets/options.ts b/packages/old-import/src/widgets/options.ts index 31658ecd1..643ecb99d 100644 --- a/packages/old-import/src/widgets/options.ts +++ b/packages/old-import/src/widgets/options.ts @@ -47,6 +47,7 @@ const optionMapping: OptionMapping = { releaseType: (oldOptions) => [oldOptions.radarrReleaseType], filterFutureMonths: () => undefined, filterPastMonths: () => undefined, + showUnmonitored: ({ showUnmonitored }) => showUnmonitored, }, clock: { customTitle: (oldOptions) => oldOptions.customTitle, diff --git a/packages/request-handler/src/calendar.ts b/packages/request-handler/src/calendar.ts index f047d74df..55918eaaf 100644 --- a/packages/request-handler/src/calendar.ts +++ b/packages/request-handler/src/calendar.ts @@ -9,13 +9,17 @@ import { createCachedIntegrationRequestHandler } from "./lib/cached-integration- export const calendarMonthRequestHandler = createCachedIntegrationRequestHandler< CalendarEvent[], IntegrationKindByCategory<"calendar">, - { year: number; month: number; releaseType: RadarrReleaseType[] } + { year: number; month: number; releaseType: RadarrReleaseType[]; showUnmonitored: boolean } >({ async requestAsync(integration, input) { const integrationInstance = await createIntegrationAsync(integration); const startDate = dayjs().year(input.year).month(input.month).startOf("month"); const endDate = startDate.clone().endOf("month"); - return await integrationInstance.getCalendarEventsAsync(startDate.toDate(), endDate.toDate()); + return await integrationInstance.getCalendarEventsAsync( + startDate.toDate(), + endDate.toDate(), + input.showUnmonitored, + ); }, cacheDuration: dayjs.duration(1, "minute"), queryKey: "calendarMonth", diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index e2dc60cef..3565b0dbc 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "End at" + }, + "showUnmonitored": { + "label": "Show unmonitored" } } }, diff --git a/packages/widgets/src/calendar/component.tsx b/packages/widgets/src/calendar/component.tsx index 9447459a2..064067b30 100644 --- a/packages/widgets/src/calendar/component.tsx +++ b/packages/widgets/src/calendar/component.tsx @@ -39,6 +39,7 @@ const FetchCalendar = ({ month, setMonth, isEditMode, integrationIds, options }: month: month.getMonth(), year: month.getFullYear(), releaseType: options.releaseType, + showUnmonitored: options.showUnmonitored, }, { refetchOnMount: false, diff --git a/packages/widgets/src/calendar/index.ts b/packages/widgets/src/calendar/index.ts index 275b2d605..088bdf6ef 100644 --- a/packages/widgets/src/calendar/index.ts +++ b/packages/widgets/src/calendar/index.ts @@ -26,6 +26,9 @@ export const { definition, componentLoader } = createWidgetDefinition("calendar" validate: z.number().min(2).max(9999), defaultValue: 2, }), + showUnmonitored: factory.switch({ + defaultValue: false, + }), })); }, supportedIntegrations: getIntegrationKindsByCategory("calendar"), From f19aa29607640578f61d1842d4300cc0c0618896 Mon Sep 17 00:00:00 2001 From: oussama Dahmaz Date: Sun, 9 Mar 2025 17:46:15 +0100 Subject: [PATCH 24/60] feat(kubernetes): add kubernetes tool (#1929) Co-authored-by: oussama Dahmaz --- .env.example | 5 +- .../public/images/kubernetes/configmaps.svg | 141 +++++++++ .../public/images/kubernetes/ingresses.svg | 84 ++++++ .../public/images/kubernetes/namespaces.svg | 85 ++++++ .../nextjs/public/images/kubernetes/nodes.svg | 84 ++++++ apps/nextjs/public/images/kubernetes/pods.svg | 103 +++++++ .../public/images/kubernetes/secrets.svg | 128 +++++++++ .../public/images/kubernetes/services.svg | 117 ++++++++ .../public/images/kubernetes/volumes.svg | 97 +++++++ .../nextjs/src/app/[locale]/manage/layout.tsx | 9 +- .../app/[locale]/manage/tools/docker/page.tsx | 3 +- .../cluster-dashboard/cluster-dashboard.tsx | 76 +++++ .../kubernetes/cluster-dashboard/error.tsx | 27 ++ .../header-card/header-card.module.css | 31 ++ .../header-card/header-card.tsx | 44 +++ .../header-card/header-icon.tsx | 18 ++ .../resource-gauge/resource-gauge.module.css | 20 ++ .../resource-gauge/resource-gauge.tsx | 90 ++++++ .../resource-gauge/resource-icon.tsx | 21 ++ .../resource-tile/resource-tile.module.css | 10 + .../resource-tile/resource-tile.tsx | 37 +++ .../configmaps/configmaps-table.tsx | 74 +++++ .../tools/kubernetes/configmaps/page.tsx | 30 ++ .../kubernetes/ingresses/ingresses-table.tsx | 107 +++++++ .../tools/kubernetes/ingresses/page.tsx | 29 ++ .../namespaces/namespaces-table.tsx | 91 ++++++ .../tools/kubernetes/namespaces/page.tsx | 29 ++ .../tools/kubernetes/nodes/nodes-table.tsx | 132 +++++++++ .../manage/tools/kubernetes/nodes/page.tsx | 29 ++ .../[locale]/manage/tools/kubernetes/page.tsx | 21 ++ .../manage/tools/kubernetes/pods/page.tsx | 29 ++ .../tools/kubernetes/pods/pods-table.tsx | 82 ++++++ .../manage/tools/kubernetes/secrets/page.tsx | 29 ++ .../kubernetes/secrets/secrets-table.tsx | 77 +++++ .../manage/tools/kubernetes/services/page.tsx | 29 ++ .../kubernetes/services/services-table.tsx | 95 ++++++ .../manage/tools/kubernetes/volumes/page.tsx | 29 ++ .../kubernetes/volumes/volumes-table.tsx | 101 +++++++ development/development.docker-compose.yml | 18 +- packages/api/package.json | 1 + packages/api/src/env.ts | 15 + packages/api/src/middlewares/docker.ts | 17 ++ packages/api/src/middlewares/kubernetes.ts | 17 ++ packages/api/src/root.ts | 2 + .../api/src/router/docker/docker-router.ts | 127 ++++---- .../router/kubernetes/kubernetes-client.ts | 73 +++++ .../resource-parser/cpu-resource-parser.ts | 41 +++ .../resource-parser/memory-resource-parser.ts | 69 +++++ .../resource-parser/resource-parser.ts | 3 + .../src/router/kubernetes/router/cluster.ts | 196 +++++++++++++ .../router/kubernetes/router/configMaps.ts | 36 +++ .../src/router/kubernetes/router/ingresses.ts | 54 ++++ .../kubernetes/router/kubernetes-router.ts | 22 ++ .../router/kubernetes/router/namespaces.ts | 36 +++ .../api/src/router/kubernetes/router/nodes.ts | 68 +++++ .../api/src/router/kubernetes/router/pods.ts | 104 +++++++ .../src/router/kubernetes/router/secrets.ts | 36 +++ .../src/router/kubernetes/router/services.ts | 40 +++ .../src/router/kubernetes/router/volumes.ts | 42 +++ .../router/test/docker/docker-router.spec.ts | 6 + .../cpu-resource-parser.spec.ts | 56 ++++ .../memory-resource-parser.spec.ts | 61 ++++ packages/definitions/src/index.ts | 1 + packages/definitions/src/kubernetes.ts | 110 +++++++ packages/docker/src/env.ts | 3 + packages/translation/src/lang/en.json | 270 +++++++++++++++++- pnpm-lock.yaml | 197 ++++++++++++- 67 files changed, 3897 insertions(+), 67 deletions(-) create mode 100644 apps/nextjs/public/images/kubernetes/configmaps.svg create mode 100644 apps/nextjs/public/images/kubernetes/ingresses.svg create mode 100644 apps/nextjs/public/images/kubernetes/namespaces.svg create mode 100644 apps/nextjs/public/images/kubernetes/nodes.svg create mode 100644 apps/nextjs/public/images/kubernetes/pods.svg create mode 100644 apps/nextjs/public/images/kubernetes/secrets.svg create mode 100644 apps/nextjs/public/images/kubernetes/services.svg create mode 100644 apps/nextjs/public/images/kubernetes/volumes.svg create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/cluster-dashboard.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/error.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-icon.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge.module.css create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-icon.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.module.css create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx create mode 100644 packages/api/src/env.ts create mode 100644 packages/api/src/middlewares/docker.ts create mode 100644 packages/api/src/middlewares/kubernetes.ts create mode 100644 packages/api/src/router/kubernetes/kubernetes-client.ts create mode 100644 packages/api/src/router/kubernetes/resource-parser/cpu-resource-parser.ts create mode 100644 packages/api/src/router/kubernetes/resource-parser/memory-resource-parser.ts create mode 100644 packages/api/src/router/kubernetes/resource-parser/resource-parser.ts create mode 100644 packages/api/src/router/kubernetes/router/cluster.ts create mode 100644 packages/api/src/router/kubernetes/router/configMaps.ts create mode 100644 packages/api/src/router/kubernetes/router/ingresses.ts create mode 100644 packages/api/src/router/kubernetes/router/kubernetes-router.ts create mode 100644 packages/api/src/router/kubernetes/router/namespaces.ts create mode 100644 packages/api/src/router/kubernetes/router/nodes.ts create mode 100644 packages/api/src/router/kubernetes/router/pods.ts create mode 100644 packages/api/src/router/kubernetes/router/secrets.ts create mode 100644 packages/api/src/router/kubernetes/router/services.ts create mode 100644 packages/api/src/router/kubernetes/router/volumes.ts create mode 100644 packages/api/src/router/test/kubernetes/resource-parser/cpu-resource-parser.spec.ts create mode 100644 packages/api/src/router/test/kubernetes/resource-parser/memory-resource-parser.spec.ts create mode 100644 packages/definitions/src/kubernetes.ts diff --git a/.env.example b/.env.example index fbc491bae..ae3d1e38b 100644 --- a/.env.example +++ b/.env.example @@ -34,4 +34,7 @@ DB_URL='FULL_PATH_TO_YOUR_SQLITE_DB_FILE' # If it is used, please use the full path to the directory where the certificates are stored. # LOCAL_CERTIFICATE_PATH='FULL_PATH_TO_CERTIFICATES' -TURBO_TELEMETRY_DISABLED=1 \ No newline at end of file +TURBO_TELEMETRY_DISABLED=1 + +# Enable kubernetes tool +# ENABLE_KUBERNETES=true \ No newline at end of file diff --git a/apps/nextjs/public/images/kubernetes/configmaps.svg b/apps/nextjs/public/images/kubernetes/configmaps.svg new file mode 100644 index 000000000..85ac9b476 --- /dev/null +++ b/apps/nextjs/public/images/kubernetes/configmaps.svg @@ -0,0 +1,141 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/nextjs/public/images/kubernetes/ingresses.svg b/apps/nextjs/public/images/kubernetes/ingresses.svg new file mode 100644 index 000000000..0dde27514 --- /dev/null +++ b/apps/nextjs/public/images/kubernetes/ingresses.svg @@ -0,0 +1,84 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/apps/nextjs/public/images/kubernetes/namespaces.svg b/apps/nextjs/public/images/kubernetes/namespaces.svg new file mode 100644 index 000000000..231c21c9e --- /dev/null +++ b/apps/nextjs/public/images/kubernetes/namespaces.svg @@ -0,0 +1,85 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/apps/nextjs/public/images/kubernetes/nodes.svg b/apps/nextjs/public/images/kubernetes/nodes.svg new file mode 100644 index 000000000..c0f2b8e13 --- /dev/null +++ b/apps/nextjs/public/images/kubernetes/nodes.svg @@ -0,0 +1,84 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/apps/nextjs/public/images/kubernetes/pods.svg b/apps/nextjs/public/images/kubernetes/pods.svg new file mode 100644 index 000000000..f88d2dbca --- /dev/null +++ b/apps/nextjs/public/images/kubernetes/pods.svg @@ -0,0 +1,103 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/apps/nextjs/public/images/kubernetes/secrets.svg b/apps/nextjs/public/images/kubernetes/secrets.svg new file mode 100644 index 000000000..195727e1e --- /dev/null +++ b/apps/nextjs/public/images/kubernetes/secrets.svg @@ -0,0 +1,128 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/nextjs/public/images/kubernetes/services.svg b/apps/nextjs/public/images/kubernetes/services.svg new file mode 100644 index 000000000..779b61405 --- /dev/null +++ b/apps/nextjs/public/images/kubernetes/services.svg @@ -0,0 +1,117 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/nextjs/public/images/kubernetes/volumes.svg b/apps/nextjs/public/images/kubernetes/volumes.svg new file mode 100644 index 000000000..dba1bd2d7 --- /dev/null +++ b/apps/nextjs/public/images/kubernetes/volumes.svg @@ -0,0 +1,97 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/apps/nextjs/src/app/[locale]/manage/layout.tsx b/apps/nextjs/src/app/[locale]/manage/layout.tsx index 0dc505799..32013221c 100644 --- a/apps/nextjs/src/app/[locale]/manage/layout.tsx +++ b/apps/nextjs/src/app/[locale]/manage/layout.tsx @@ -28,6 +28,7 @@ import { import { auth } from "@homarr/auth/next"; import { isProviderEnabled } from "@homarr/auth/server"; import { createDocumentationLink } from "@homarr/definitions"; +import { env } from "@homarr/docker/env"; import { getScopedI18n } from "@homarr/translation/server"; import { MainHeader } from "~/components/layout/header"; @@ -113,7 +114,13 @@ export default async function ManageLayout({ children }: PropsWithChildren) { label: t("items.tools.items.docker"), icon: IconBrandDocker, href: "/manage/tools/docker", - hidden: !session?.user.permissions.includes("admin"), + hidden: !(session?.user.permissions.includes("admin") && env.ENABLE_DOCKER), + }, + { + label: t("items.tools.items.kubernetes"), + icon: IconBox, + href: "/manage/tools/kubernetes", + hidden: !(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES), }, { label: t("items.tools.items.api"), diff --git a/apps/nextjs/src/app/[locale]/manage/tools/docker/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/docker/page.tsx index 7af012d53..1da3db128 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/docker/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/docker/page.tsx @@ -3,6 +3,7 @@ import { Stack, Title } from "@mantine/core"; import { api } from "@homarr/api/server"; import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; import { getScopedI18n } from "@homarr/translation/server"; import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; @@ -10,7 +11,7 @@ import { DockerTable } from "./docker-table"; export default async function DockerPage() { const session = await auth(); - if (!session?.user || !session.user.permissions.includes("admin")) { + if (!(session?.user.permissions.includes("admin") && env.ENABLE_DOCKER)) { notFound(); } diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/cluster-dashboard.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/cluster-dashboard.tsx new file mode 100644 index 000000000..ccf0cc556 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/cluster-dashboard.tsx @@ -0,0 +1,76 @@ +"use client"; + +import { SimpleGrid, Skeleton, Stack, Title } from "@mantine/core"; + +import { clientApi } from "@homarr/api/client"; +import { createId } from "@homarr/db/client"; +import type { KubernetesLabelResourceType } from "@homarr/definitions"; +import { useI18n } from "@homarr/translation/client"; + +import KubernetesErrorPage from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/error"; +import { HeaderCard } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card"; +import { ResourceGauge } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge"; +import { ResourceTile } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile"; + +export function ClusterDashboard() { + const t = useI18n(); + + const { + data: clusterData, + isLoading: isClusterLoading, + isError: isClusterError, + } = clientApi.kubernetes.cluster.getCluster.useQuery(); + + const { + data: resourceCountsData, + isLoading: isResourceCountsLoading, + isError: isResourceCountsError, + } = clientApi.kubernetes.cluster.getClusterResourceCounts.useQuery(); + + return ( + + {t("kubernetes.cluster.title")} + + {isClusterError ? ( + Array.from({ length: 3 }).map(() => ) + ) : isClusterLoading ? ( + Array.from({ length: 3 }).map(() => ) + ) : ( + <> + + + + + )} + + + {t("kubernetes.cluster.capacity.title")} + + + {isClusterError + ? Array.from({ length: 3 }).map(() => ) + : isClusterLoading + ? Array.from({ length: 3 }).map(() => ) + : clusterData?.capacity.map((capacity) => ( + + ))} + + + {t("kubernetes.cluster.resources.title")} + + + {isResourceCountsError + ? Array.from({ length: 8 }).map(() => ) + : isResourceCountsLoading + ? Array.from({ length: 8 }).map(() => ) + : resourceCountsData?.map((clusterResourceCount) => ( + + ))} + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/error.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/error.tsx new file mode 100644 index 000000000..4baae5ace --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/error.tsx @@ -0,0 +1,27 @@ +"use client"; + +import Link from "next/link"; +import { Anchor, Center, Stack, Text } from "@mantine/core"; +import { IconCubeOff } from "@tabler/icons-react"; + +import { useI18n } from "@homarr/translation/client"; + +export default function KubernetesErrorPage() { + const t = useI18n(); + + return ( +
+ + + + + {t("kubernetes.error.internalServerError")} + + + {t("common.action.checkLogs")} + + + +
+ ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css new file mode 100644 index 000000000..b439e7f4b --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css @@ -0,0 +1,31 @@ +.header { + direction: inherit; + position: relative; + overflow: hidden; + padding: var(--mantine-spacing-xs); + padding-left: calc(var(--mantine-spacing-xs) * 2); + + @mixin hover { + box-shadow: var(--mantine-shadow-md); + } + + &::before { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 6px; + background-image: linear-gradient(0, var(--mantine-color-blue-4), var(--mantine-color-blue-9)); + } + + @mixin rtl { + padding-left: var(--mantine-spacing-xs); + padding-right: calc(var(--mantine-spacing-xs) * 2); + + &::before { + left: unset; + right: 0; + } + } +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx new file mode 100644 index 000000000..a8704e1b5 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx @@ -0,0 +1,44 @@ +import { Card, Flex, Text, ThemeIcon } from "@mantine/core"; + +import { isLocaleRTL } from "@homarr/translation"; +import { useCurrentLocale, useI18n } from "@homarr/translation/client"; + +import { HeaderIcon } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-icon"; +import classes from "./header-card.module.css"; + +export type HeaderTypes = "providers" | "version" | "architecture"; + +interface HeaderCardProps { + headerType: HeaderTypes; + value: string; +} + +export function HeaderCard(props: HeaderCardProps) { + const t = useI18n(); + const currentLocale = useCurrentLocale(); + const isRTL = isLocaleRTL(currentLocale); + + return ( + + + + + + + {isRTL + ? `${props.value} : ${t(`kubernetes.cluster.${props.headerType}`)}` + : `${t(`kubernetes.cluster.${props.headerType}`)} : ${props.value}`} + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-icon.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-icon.tsx new file mode 100644 index 000000000..483b937c8 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-icon.tsx @@ -0,0 +1,18 @@ +import { IconBrandGit, IconCloudShare, IconGeometry } from "@tabler/icons-react"; + +import type { HeaderTypes } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card"; + +interface HeaderIconProps { + type: HeaderTypes; +} + +export function HeaderIcon({ type }: HeaderIconProps) { + switch (type) { + case "providers": + return ; + case "version": + return ; + default: + return ; + } +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge.module.css b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge.module.css new file mode 100644 index 000000000..dd620b9c8 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge.module.css @@ -0,0 +1,20 @@ +.paper { + position: relative; + overflow: visible; + padding: var(--mantine-spacing-xl); + padding-top: calc(var(--mantine-spacing-xl) * 1.5 + 20px); +} + +.icon { + position: absolute; + top: -20px; + left: calc(50% - 30px); + border: groove white; +} + +.title { + font-family: + Greycliff CF, + var(--mantine-font-family); + line-height: 1; +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge.tsx new file mode 100644 index 000000000..95143178d --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge.tsx @@ -0,0 +1,90 @@ +import React from "react"; +import { Group, Paper, Progress, Text, ThemeIcon } from "@mantine/core"; + +import type { KubernetesCapacity } from "@homarr/definitions"; +import { isLocaleRTL } from "@homarr/translation"; +import { useCurrentLocale, useI18n } from "@homarr/translation/client"; + +import { ResourceIcon } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-icon"; +import classes from "./resource-gauge.module.css"; + +interface KubernetesResourceGaugeProps { + kubernetesCapacity: KubernetesCapacity; +} + +export function ResourceGauge(props: KubernetesResourceGaugeProps) { + const t = useI18n(); + const currentLocale = useCurrentLocale(); + const isRTL = Boolean(isLocaleRTL(currentLocale)); + + return ( + + + + + + + {props.kubernetesCapacity.type} + + + {props.kubernetesCapacity.resourcesStats.map((stat) => { + const isReserved = stat.type === "Reserved"; + const labelKey = isReserved + ? "kubernetes.cluster.capacity.resource.reserved" + : "kubernetes.cluster.capacity.resource.used"; + + return ( +
+ + + {isRTL ? ( + <> + {stat.capacityUnit && ( + + {stat.capacityUnit} + + )} + + {stat.maxUsedValue} / {stat.usedValue}{" "} + + + {t(labelKey)} + + + ) : ( + <> + + {t(labelKey)} + + + {" "} + {stat.usedValue} / {stat.maxUsedValue}{" "} + + {stat.capacityUnit && ( + + {stat.capacityUnit} + + )} + + )} + + + {isRTL ? `%${stat.percentageValue}` : `${stat.percentageValue}%`} + + + +
+ ); + })} +
+ ); +} + +function getProgressBarColor(value: number): string { + if (value > 50 && value < 65) { + return "yellow"; + } else if (value >= 65) { + return "red"; + } + return "blue"; +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-icon.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-icon.tsx new file mode 100644 index 000000000..b9f5f435c --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-icon.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import { IconCpu, IconCube, IconDeviceDesktopAnalytics } from "@tabler/icons-react"; + +import type { KubernetesCapacityType } from "@homarr/definitions"; + +const resourceIcons = { + CPU: IconCpu, + Memory: IconDeviceDesktopAnalytics, + Pods: IconCube, +} satisfies Record>; + +interface ResourceIconProps { + type: KubernetesCapacityType; + size?: number; + stroke?: number; +} + +export const ResourceIcon: React.FC = ({ type, size = 32, stroke = 1.5 }) => { + const Icon = resourceIcons[type]; + return ; +}; diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.module.css b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.module.css new file mode 100644 index 000000000..018eaaab6 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.module.css @@ -0,0 +1,10 @@ +.cardContainer { + transition: + box-shadow 150ms ease, + transform 100ms ease; + + @mixin hover { + box-shadow: var(--mantine-shadow-md); + transform: scale(1.02); + } +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx new file mode 100644 index 000000000..f1ad19df8 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import Image from "next/image"; +import Link from "next/link"; +import { Card, Group, Text } from "@mantine/core"; +import { IconArrowRight } from "@tabler/icons-react"; + +import type { KubernetesLabelResourceType } from "@homarr/definitions"; +import { useI18n } from "@homarr/translation/client"; + +import classes from "./resource-tile.module.css"; + +interface ResourceTileProps { + count: number; + label: KubernetesLabelResourceType; +} + +export function ResourceTile(props: ResourceTileProps) { + const t = useI18n(); + return ( + + + {props.label} + + + {props.count} {t(`kubernetes.cluster.resources.${props.label}`)} + + + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx new file mode 100644 index 000000000..ac144ee15 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx @@ -0,0 +1,74 @@ +"use client"; + +import React from "react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import type { MRT_ColumnDef } from "mantine-react-table"; +import { MantineReactTable } from "mantine-react-table"; + +import type { RouterOutputs } from "@homarr/api"; +import { clientApi } from "@homarr/api/client"; +import type { KubernetesBaseResource } from "@homarr/definitions"; +import type { ScopedTranslationFunction } from "@homarr/translation"; +import { useScopedI18n } from "@homarr/translation/client"; +import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; + +dayjs.extend(relativeTime); + +interface ConfigMapsTableComponentProps { + initialConfigMaps: RouterOutputs["kubernetes"]["configMaps"]["getConfigMaps"]; +} + +const createColumns = ( + t: ScopedTranslationFunction<"kubernetes.configmaps">, +): MRT_ColumnDef[] => [ + { + accessorKey: "name", + header: t("field.name.label"), + enableClickToCopy: true, + }, + { + accessorKey: "namespace", + header: t("field.namespace.label"), + enableClickToCopy: true, + }, + { + accessorKey: "creationTimestamp", + header: t("field.creationTimestamp.label"), + Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false), + }, +]; + +export function ConfigmapsTable(initialData: ConfigMapsTableComponentProps) { + const tConfigMaps = useScopedI18n("kubernetes.configmaps"); + + const { data } = clientApi.kubernetes.configMaps.getConfigMaps.useQuery(undefined, { + initialData: initialData.initialConfigMaps, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + const table = useTranslatedMantineReactTable({ + data, + enableDensityToggle: false, + enableColumnActions: false, + enableColumnFilters: false, + enablePagination: false, + enableRowSelection: true, + positionToolbarAlertBanner: "top", + enableTableFooter: false, + enableBottomToolbar: false, + positionGlobalFilter: "right", + initialState: { density: "xs", showGlobalFilter: true }, + mantineSearchTextInputProps: { + placeholder: tConfigMaps("table.search", { count: data.length }), + style: { minWidth: 300 }, + autoFocus: true, + }, + + columns: createColumns(tConfigMaps), + }); + + return ; +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/page.tsx new file mode 100644 index 000000000..ef49e5f21 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/page.tsx @@ -0,0 +1,30 @@ +import { notFound } from "next/navigation"; +import { Stack, Title } from "@mantine/core"; + +import { api } from "@homarr/api/server"; +import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; +import { getScopedI18n } from "@homarr/translation/server"; + +import { ConfigmapsTable } from "~/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table"; +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; + +export default async function ConfigMapsPage() { + const session = await auth(); + if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) { + notFound(); + } + + const configMaps = await api.kubernetes.configMaps.getConfigMaps(); + const tConfigMaps = await getScopedI18n("kubernetes.configmaps"); + + return ( + <> + + + {tConfigMaps("label")} + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx new file mode 100644 index 000000000..e53e492eb --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx @@ -0,0 +1,107 @@ +"use client"; + +import React from "react"; +import { Anchor, Flex } from "@mantine/core"; +import { IconArrowRight } from "@tabler/icons-react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import type { MRT_ColumnDef } from "mantine-react-table"; +import { MantineReactTable } from "mantine-react-table"; + +import type { RouterOutputs } from "@homarr/api"; +import { clientApi } from "@homarr/api/client"; +import { createId } from "@homarr/db/client"; +import type { KubernetesIngress } from "@homarr/definitions"; +import type { ScopedTranslationFunction } from "@homarr/translation"; +import { useScopedI18n } from "@homarr/translation/client"; +import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; + +dayjs.extend(relativeTime); + +interface IngressesTableComponentProps { + initialIngresses: RouterOutputs["kubernetes"]["ingresses"]["getIngresses"]; +} + +const createColumns = (t: ScopedTranslationFunction<"kubernetes.ingresses">): MRT_ColumnDef[] => [ + { + accessorKey: "name", + header: t("field.name.label"), + enableClickToCopy: true, + }, + { + accessorKey: "namespace", + header: t("field.namespace.label"), + enableClickToCopy: true, + }, + { + accessorKey: "className", + header: t("field.className.label"), + enableClickToCopy: true, + }, + { + accessorKey: "rulesAndPaths", + header: t("field.rulesAndPaths.label"), + Cell({ cell }) { + const getAbsoluteUrl = (host: string) => + host.startsWith("http://") || host.startsWith("https://") ? host : `https://${host}`; + return ( + <> + {cell.row.original.rulesAndPaths.map((ruleAndPaths) => ( +
+ + + {getAbsoluteUrl(ruleAndPaths.host)} + + + + {ruleAndPaths.paths.map((path) => ( +
+ {path.serviceName}:{path.port} +
+ ))} +
+ ))} + + ); + }, + }, + { + accessorKey: "creationTimestamp", + header: t("field.creationTimestamp.label"), + Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false), + }, +]; + +export function IngressesTable(initialData: IngressesTableComponentProps) { + const tIngresses = useScopedI18n("kubernetes.ingresses"); + + const { data } = clientApi.kubernetes.ingresses.getIngresses.useQuery(undefined, { + initialData: initialData.initialIngresses, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + const table = useTranslatedMantineReactTable({ + data, + enableDensityToggle: false, + enableColumnActions: false, + enableColumnFilters: false, + enablePagination: false, + enableRowSelection: true, + positionToolbarAlertBanner: "top", + enableTableFooter: false, + enableBottomToolbar: false, + positionGlobalFilter: "right", + initialState: { density: "xs", showGlobalFilter: true }, + mantineSearchTextInputProps: { + placeholder: tIngresses("table.search", { count: data.length }), + style: { minWidth: 300 }, + autoFocus: true, + }, + + columns: createColumns(tIngresses), + }); + + return ; +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/page.tsx new file mode 100644 index 000000000..1cfe5aa03 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/page.tsx @@ -0,0 +1,29 @@ +import { notFound } from "next/navigation"; +import { Stack, Title } from "@mantine/core"; + +import { api } from "@homarr/api/server"; +import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; +import { getScopedI18n } from "@homarr/translation/server"; + +import { IngressesTable } from "~/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table"; +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; + +export default async function NamespacesPage() { + const session = await auth(); + if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) { + notFound(); + } + + const ingresses = await api.kubernetes.ingresses.getIngresses(); + const tIngresses = await getScopedI18n("kubernetes.ingresses"); + return ( + <> + + + {tIngresses("label")} + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx new file mode 100644 index 000000000..9ef0e4a5b --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx @@ -0,0 +1,91 @@ +"use client"; + +import React from "react"; +import { Badge, rem } from "@mantine/core"; +import { IconCircleDashedCheck, IconHeartBroken } from "@tabler/icons-react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import type { MRT_ColumnDef } from "mantine-react-table"; +import { MantineReactTable } from "mantine-react-table"; + +import type { RouterOutputs } from "@homarr/api"; +import { clientApi } from "@homarr/api/client"; +import type { KubernetesNamespace } from "@homarr/definitions"; +import type { ScopedTranslationFunction } from "@homarr/translation"; +import { useScopedI18n } from "@homarr/translation/client"; +import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; + +dayjs.extend(relativeTime); + +interface NamespacesTableComponentProps { + initialNamespaces: RouterOutputs["kubernetes"]["namespaces"]["getNamespaces"]; +} + +const createColumns = (t: ScopedTranslationFunction<"kubernetes.namespaces">): MRT_ColumnDef[] => [ + { + accessorKey: "status", + header: t("field.state.label"), + + Cell({ cell }) { + const checkIcon = ; + const downIcon = ; + + const badgeKubernetesNamespaceStatusColor = cell.row.original.status === "Active" ? "green" : "yellow"; + const badgeKubernetesNamespaceStatusIcon = cell.row.original.status === "Active" ? checkIcon : downIcon; + + return ( + + {cell.row.original.status} + + ); + }, + }, + { + accessorKey: "name", + header: t("field.name.label"), + enableClickToCopy: true, + }, + { + accessorKey: "creationTimestamp", + header: t("field.creationTimestamp.label"), + Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false), + }, +]; + +export function NamespacesTable(initialData: NamespacesTableComponentProps) { + const tNamespaces = useScopedI18n("kubernetes.namespaces"); + + const { data } = clientApi.kubernetes.namespaces.getNamespaces.useQuery(undefined, { + initialData: initialData.initialNamespaces, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + const table = useTranslatedMantineReactTable({ + data, + enableDensityToggle: false, + enableColumnActions: false, + enableColumnFilters: false, + enablePagination: false, + enableRowSelection: true, + positionToolbarAlertBanner: "top", + enableTableFooter: false, + enableBottomToolbar: false, + positionGlobalFilter: "right", + initialState: { density: "xs", showGlobalFilter: true }, + mantineSearchTextInputProps: { + placeholder: tNamespaces("table.search", { count: data.length }), + style: { minWidth: 300 }, + autoFocus: true, + }, + + columns: createColumns(tNamespaces), + }); + + return ; +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/page.tsx new file mode 100644 index 000000000..14b48f757 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/page.tsx @@ -0,0 +1,29 @@ +import { notFound } from "next/navigation"; +import { Stack, Title } from "@mantine/core"; + +import { api } from "@homarr/api/server"; +import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; +import { getScopedI18n } from "@homarr/translation/server"; + +import { NamespacesTable } from "~/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table"; +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; + +export default async function NamespacesPage() { + const session = await auth(); + if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) { + notFound(); + } + + const namespaces = await api.kubernetes.namespaces.getNamespaces(); + const tNamespaces = await getScopedI18n("kubernetes.namespaces"); + return ( + <> + + + {tNamespaces("label")} + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx new file mode 100644 index 000000000..b7b17d984 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx @@ -0,0 +1,132 @@ +"use client"; + +import React from "react"; +import { Badge, rem, RingProgress, Text } from "@mantine/core"; +import { IconCircleDashedCheck, IconHeartBroken } from "@tabler/icons-react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import type { MRT_ColumnDef } from "mantine-react-table"; +import { MantineReactTable } from "mantine-react-table"; + +import type { RouterOutputs } from "@homarr/api"; +import { clientApi } from "@homarr/api/client"; +import type { KubernetesNode } from "@homarr/definitions"; +import type { ScopedTranslationFunction } from "@homarr/translation"; +import { useScopedI18n } from "@homarr/translation/client"; +import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; + +dayjs.extend(relativeTime); + +interface NodesListComponentProps { + initialNodes: RouterOutputs["kubernetes"]["nodes"]["getNodes"]; +} + +const createColumns = (t: ScopedTranslationFunction<"kubernetes.nodes">): MRT_ColumnDef[] => [ + { + accessorKey: "status", + header: t("field.state.label"), + + Cell({ cell }) { + const checkIcon = ; + const downIcon = ; + + const badgeKubernetesNodeStatusColor = cell.row.original.status === "Ready" ? "green" : "red"; + const badgeKubernetesNodeStatusIcon = cell.row.original.status === "Ready" ? checkIcon : downIcon; + + return ( + + {cell.row.original.status} + + ); + }, + }, + { + accessorKey: "name", + header: t("field.name.label"), + enableClickToCopy: true, + }, + { + accessorKey: "allocatableCpuPercentage", + header: t("field.cpu.label"), + Cell({ cell }) { + return getRingProgress(cell.row.original.allocatableCpuPercentage); + }, + }, + { + accessorKey: "allocatableRamPercentage", + header: t("field.memory.label"), + Cell({ cell }) { + return getRingProgress(cell.row.original.allocatableRamPercentage); + }, + }, + { + accessorKey: "operatingSystem", + header: t("field.operatingSystem.label"), + }, + { + accessorKey: "podsCount", + header: t("field.pods.label"), + }, + { + accessorKey: "architecture", + header: t("field.architecture.label"), + }, + { + accessorKey: "kubernetesVersion", + header: t("field.kubernetesVersion.label"), + }, + { + accessorKey: "creationTimestamp", + header: t("field.creationTimestamp.label"), + Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false), + }, +]; + +export function NodesTable(initialData: NodesListComponentProps) { + const tNodes = useScopedI18n("kubernetes.nodes"); + + const { data } = clientApi.kubernetes.nodes.getNodes.useQuery(undefined, { + initialData: initialData.initialNodes, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + const table = useTranslatedMantineReactTable({ + data, + enableDensityToggle: false, + enableColumnActions: false, + enableColumnFilters: false, + enablePagination: false, + enableRowSelection: true, + positionToolbarAlertBanner: "top", + enableTableFooter: false, + enableBottomToolbar: false, + positionGlobalFilter: "right", + initialState: { density: "xs", showGlobalFilter: true }, + mantineSearchTextInputProps: { + placeholder: tNodes("table.search", { count: data.length }), + style: { minWidth: 300 }, + autoFocus: true, + }, + columns: createColumns(tNodes), + }); + + return ; +} + +function getRingProgress(value: number) { + return ( + + {value}% +
+ } + /> + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/page.tsx new file mode 100644 index 000000000..20e59f80f --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/page.tsx @@ -0,0 +1,29 @@ +import { notFound } from "next/navigation"; +import { Stack, Title } from "@mantine/core"; + +import { api } from "@homarr/api/server"; +import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; +import { getScopedI18n } from "@homarr/translation/server"; + +import { NodesTable } from "~/app/[locale]/manage/tools/kubernetes/nodes/nodes-table"; +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; + +export default async function NodesPage() { + const session = await auth(); + if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) { + notFound(); + } + + const nodes = await api.kubernetes.nodes.getNodes(); + const tNodes = await getScopedI18n("kubernetes.nodes"); + return ( + <> + + + {tNodes("label")} + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/page.tsx new file mode 100644 index 000000000..ae9d8fe4c --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/page.tsx @@ -0,0 +1,21 @@ +import { notFound } from "next/navigation"; + +import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; + +import { ClusterDashboard } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/cluster-dashboard"; +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; + +export default async function KubernetesPage() { + const session = await auth(); + if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) { + notFound(); + } + + return ( + <> + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/page.tsx new file mode 100644 index 000000000..b261bf4e2 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/page.tsx @@ -0,0 +1,29 @@ +import { notFound } from "next/navigation"; +import { Stack, Title } from "@mantine/core"; + +import { api } from "@homarr/api/server"; +import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; +import { getScopedI18n } from "@homarr/translation/server"; + +import { PodsTable } from "~/app/[locale]/manage/tools/kubernetes/pods/pods-table"; +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; + +export default async function PodsPage() { + const session = await auth(); + if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) { + notFound(); + } + + const pods = await api.kubernetes.pods.getPods(); + const tPods = await getScopedI18n("kubernetes.pods"); + return ( + <> + + + {tPods("label")} + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx new file mode 100644 index 000000000..3a1e10820 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx @@ -0,0 +1,82 @@ +"use client"; + +import React from "react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import type { MRT_ColumnDef } from "mantine-react-table"; +import { MantineReactTable } from "mantine-react-table"; + +import type { RouterOutputs } from "@homarr/api"; +import { clientApi } from "@homarr/api/client"; +import type { KubernetesPod } from "@homarr/definitions"; +import type { ScopedTranslationFunction } from "@homarr/translation"; +import { useScopedI18n } from "@homarr/translation/client"; +import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; + +dayjs.extend(relativeTime); + +interface PodsTableComponentProps { + initialPods: RouterOutputs["kubernetes"]["pods"]["getPods"]; +} + +const createColumns = (t: ScopedTranslationFunction<"kubernetes.pods">): MRT_ColumnDef[] => [ + { + accessorKey: "name", + header: t("field.name.label"), + }, + { + accessorKey: "namespace", + header: t("field.namespace.label"), + }, + { + accessorKey: "image", + header: t("field.image.label"), + }, + { + accessorKey: "applicationType", + header: t("field.applicationType.label"), + }, + { + accessorKey: "status", + header: t("field.status.label"), + }, + { + accessorKey: "creationTimestamp", + header: t("field.creationTimestamp.label"), + Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false), + }, +]; + +export function PodsTable(initialData: PodsTableComponentProps) { + const tPods = useScopedI18n("kubernetes.pods"); + + const { data } = clientApi.kubernetes.pods.getPods.useQuery(undefined, { + initialData: initialData.initialPods, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + const table = useTranslatedMantineReactTable({ + data, + enableDensityToggle: false, + enableColumnActions: false, + enableColumnFilters: false, + enablePagination: false, + enableRowSelection: true, + positionToolbarAlertBanner: "top", + enableTableFooter: false, + enableBottomToolbar: false, + positionGlobalFilter: "right", + initialState: { density: "xs", showGlobalFilter: true, expanded: true }, + mantineSearchTextInputProps: { + placeholder: tPods("table.search", { count: data.length }), + style: { minWidth: 300 }, + autoFocus: true, + }, + enableGrouping: true, + columns: createColumns(tPods), + }); + + return ; +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/page.tsx new file mode 100644 index 000000000..b52b1ea41 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/page.tsx @@ -0,0 +1,29 @@ +import { notFound } from "next/navigation"; +import { Stack, Title } from "@mantine/core"; + +import { api } from "@homarr/api/server"; +import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; +import { getScopedI18n } from "@homarr/translation/server"; + +import { SecretsTable } from "~/app/[locale]/manage/tools/kubernetes/secrets/secrets-table"; +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; + +export default async function SecretsPage() { + const session = await auth(); + if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) { + notFound(); + } + + const secrets = await api.kubernetes.secrets.getSecrets(); + const tSecrets = await getScopedI18n("kubernetes.secrets"); + return ( + <> + + + {tSecrets("label")} + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx new file mode 100644 index 000000000..3c24ad0f1 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx @@ -0,0 +1,77 @@ +"use client"; + +import React from "react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import type { MRT_ColumnDef } from "mantine-react-table"; +import { MantineReactTable } from "mantine-react-table"; + +import type { RouterOutputs } from "@homarr/api"; +import { clientApi } from "@homarr/api/client"; +import type { KubernetesSecret } from "@homarr/definitions"; +import type { ScopedTranslationFunction } from "@homarr/translation"; +import { useScopedI18n } from "@homarr/translation/client"; +import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; + +dayjs.extend(relativeTime); + +interface SecretsTableComponentProps { + initialSecrets: RouterOutputs["kubernetes"]["secrets"]["getSecrets"]; +} + +const createColumns = (t: ScopedTranslationFunction<"kubernetes.secrets">): MRT_ColumnDef[] => [ + { + accessorKey: "name", + header: t("field.name.label"), + enableClickToCopy: true, + }, + { + accessorKey: "namespace", + header: t("field.namespace.label"), + enableClickToCopy: true, + }, + { + accessorKey: "type", + header: t("field.type.label"), + enableClickToCopy: true, + }, + { + accessorKey: "creationTimestamp", + header: t("field.creationTimestamp.label"), + Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false), + }, +]; + +export function SecretsTable(initialData: SecretsTableComponentProps) { + const tSecrets = useScopedI18n("kubernetes.secrets"); + + const { data } = clientApi.kubernetes.secrets.getSecrets.useQuery(undefined, { + initialData: initialData.initialSecrets, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + const table = useTranslatedMantineReactTable({ + data, + enableDensityToggle: false, + enableColumnActions: false, + enableColumnFilters: false, + enablePagination: false, + enableRowSelection: true, + positionToolbarAlertBanner: "top", + enableTableFooter: false, + enableBottomToolbar: false, + positionGlobalFilter: "right", + initialState: { density: "xs", showGlobalFilter: true }, + mantineSearchTextInputProps: { + placeholder: tSecrets("table.search", { count: data.length }), + style: { minWidth: 300 }, + autoFocus: true, + }, + + columns: createColumns(tSecrets), + }); + + return ; +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/page.tsx new file mode 100644 index 000000000..d50467aa8 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/page.tsx @@ -0,0 +1,29 @@ +import { notFound } from "next/navigation"; +import { Stack, Title } from "@mantine/core"; + +import { api } from "@homarr/api/server"; +import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; +import { getScopedI18n } from "@homarr/translation/server"; + +import { ServicesTable } from "~/app/[locale]/manage/tools/kubernetes/services/services-table"; +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; + +export default async function ServicesPage() { + const session = await auth(); + if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) { + notFound(); + } + + const services = await api.kubernetes.services.getServices(); + const tServices = await getScopedI18n("kubernetes.services"); + return ( + <> + + + {tServices("label")} + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx new file mode 100644 index 000000000..7e13a630a --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx @@ -0,0 +1,95 @@ +"use client"; + +import React from "react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import type { MRT_ColumnDef } from "mantine-react-table"; +import { MantineReactTable } from "mantine-react-table"; + +import type { RouterOutputs } from "@homarr/api"; +import { clientApi } from "@homarr/api/client"; +import { createId } from "@homarr/db/client"; +import type { KubernetesService } from "@homarr/definitions"; +import type { ScopedTranslationFunction } from "@homarr/translation"; +import { useScopedI18n } from "@homarr/translation/client"; +import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; + +dayjs.extend(relativeTime); + +interface ServicesTableComponentProps { + initialServices: RouterOutputs["kubernetes"]["services"]["getServices"]; +} + +const createColumns = (t: ScopedTranslationFunction<"kubernetes.services">): MRT_ColumnDef[] => [ + { + accessorKey: "name", + header: t("field.name.label"), + enableClickToCopy: true, + }, + { + accessorKey: "namespace", + header: t("field.namespace.label"), + enableClickToCopy: true, + }, + { + accessorKey: "type", + header: t("field.type.label"), + }, + { + accessorKey: "ports", + header: t("field.ports.label"), + Cell({ cell }) { + return cell.row.original.ports?.map((port) =>
{port}
); + }, + }, + { + accessorKey: "targetPorts", + header: t("field.targetPorts.label"), + Cell({ cell }) { + return cell.row.original.targetPorts?.map((targetPort) =>
{targetPort}
); + }, + }, + { + accessorKey: "clusterIP", + header: t("field.clusterIP.label"), + enableClickToCopy: true, + }, + { + accessorKey: "creationTimestamp", + header: t("field.creationTimestamp.label"), + Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false), + }, +]; + +export function ServicesTable(initialData: ServicesTableComponentProps) { + const tServices = useScopedI18n("kubernetes.services"); + + const { data } = clientApi.kubernetes.services.getServices.useQuery(undefined, { + initialData: initialData.initialServices, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + const table = useTranslatedMantineReactTable({ + data, + enableDensityToggle: false, + enableColumnActions: false, + enableColumnFilters: false, + enablePagination: false, + enableRowSelection: true, + positionToolbarAlertBanner: "top", + enableTableFooter: false, + enableBottomToolbar: false, + positionGlobalFilter: "right", + initialState: { density: "xs", showGlobalFilter: true }, + mantineSearchTextInputProps: { + placeholder: tServices("table.search", { count: data.length }), + style: { minWidth: 300 }, + autoFocus: true, + }, + columns: createColumns(tServices), + }); + + return ; +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/page.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/page.tsx new file mode 100644 index 000000000..301371dab --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/page.tsx @@ -0,0 +1,29 @@ +import { notFound } from "next/navigation"; +import { Stack, Title } from "@mantine/core"; + +import { api } from "@homarr/api/server"; +import { auth } from "@homarr/auth/next"; +import { env } from "@homarr/docker/env"; +import { getScopedI18n } from "@homarr/translation/server"; + +import { VolumesTable } from "~/app/[locale]/manage/tools/kubernetes/volumes/volumes-table"; +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; + +export default async function VolumesPage() { + const session = await auth(); + if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) { + notFound(); + } + + const volumes = await api.kubernetes.volumes.getVolumes(); + const tVolumes = await getScopedI18n("kubernetes.volumes"); + return ( + <> + + + {tVolumes("label")} + + + + ); +} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx new file mode 100644 index 000000000..be217d314 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx @@ -0,0 +1,101 @@ +"use client"; + +import React from "react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import type { MRT_ColumnDef } from "mantine-react-table"; +import { MantineReactTable } from "mantine-react-table"; + +import type { RouterOutputs } from "@homarr/api"; +import { clientApi } from "@homarr/api/client"; +import type { KubernetesVolume } from "@homarr/definitions"; +import type { ScopedTranslationFunction } from "@homarr/translation"; +import { useScopedI18n } from "@homarr/translation/client"; +import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; + +dayjs.extend(relativeTime); + +interface VolumesTableComponentProps { + initialVolumes: RouterOutputs["kubernetes"]["volumes"]["getVolumes"]; +} + +const createColumns = (t: ScopedTranslationFunction<"kubernetes.volumes">): MRT_ColumnDef[] => [ + { + accessorKey: "status", + header: t("field.status.label"), + }, + { + accessorKey: "name", + header: t("field.name.label"), + enableClickToCopy: true, + }, + { + accessorKey: "namespace", + header: t("field.namespace.label"), + enableClickToCopy: true, + }, + { + accessorKey: "storage", + header: t("field.storage.label"), + }, + { + accessorKey: "storageClassName", + header: t("field.storageClassName.label"), + enableClickToCopy: true, + }, + { + accessorKey: "volumeMode", + header: t("field.volumeMode.label"), + }, + { + accessorKey: "volumeName", + header: t("field.volumeName.label"), + enableClickToCopy: true, + }, + { + accessorKey: "accessModes", + header: t("field.accessModes.label"), + Cell({ cell }) { + return cell.row.original.accessModes.map((accessMode) =>
{accessMode}
); + }, + }, + { + accessorKey: "creationTimestamp", + header: t("field.creationTimestamp.label"), + Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false), + }, +]; + +export function VolumesTable(initialData: VolumesTableComponentProps) { + const tVolumes = useScopedI18n("kubernetes.volumes"); + + const { data } = clientApi.kubernetes.volumes.getVolumes.useQuery(undefined, { + initialData: initialData.initialVolumes, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }); + + const table = useTranslatedMantineReactTable({ + data, + enableDensityToggle: false, + enableColumnActions: false, + enableColumnFilters: false, + enablePagination: false, + enableRowSelection: true, + positionToolbarAlertBanner: "top", + enableTableFooter: false, + enableBottomToolbar: false, + positionGlobalFilter: "right", + initialState: { density: "xs", showGlobalFilter: true }, + mantineSearchTextInputProps: { + placeholder: tVolumes("table.search", { count: data.length }), + style: { minWidth: 300 }, + autoFocus: true, + }, + + columns: createColumns(tVolumes), + }); + + return ; +} diff --git a/development/development.docker-compose.yml b/development/development.docker-compose.yml index 9e8557808..0ee173260 100644 --- a/development/development.docker-compose.yml +++ b/development/development.docker-compose.yml @@ -11,4 +11,20 @@ services: container_name: redis image: redis ports: - - "6379:6379" \ No newline at end of file + - "6379:6379" + + mysql: + container_name: mysql + image: mysql:8.0 + ports: + - "3306:3306" + environment: + MYSQL_ROOT_PASSWORD: homarr + MYSQL_DATABASE: homarrdb + MYSQL_USER: homarr + MYSQL_PASSWORD: homarr + volumes: + - mysql_data:/var/lib/mysql + +volumes: + mysql_data: \ No newline at end of file diff --git a/packages/api/package.json b/packages/api/package.json index 7081da960..31667a3a4 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -40,6 +40,7 @@ "@homarr/request-handler": "workspace:^0.1.0", "@homarr/server-settings": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0", + "@kubernetes/client-node": "^1.0.0", "@trpc/client": "next", "@trpc/react-query": "next", "@trpc/server": "next", diff --git a/packages/api/src/env.ts b/packages/api/src/env.ts new file mode 100644 index 000000000..61512165d --- /dev/null +++ b/packages/api/src/env.ts @@ -0,0 +1,15 @@ +import { createEnv } from "@t3-oss/env-nextjs"; +import { z } from "zod"; + +import { shouldSkipEnvValidation } from "@homarr/common/env-validation"; + +export const env = createEnv({ + server: { + KUBERNETES_SERVICE_ACCOUNT_NAME: z.string().optional(), + }, + runtimeEnv: { + KUBERNETES_SERVICE_ACCOUNT_NAME: process.env.KUBERNETES_SERVICE_ACCOUNT_NAME, + }, + skipValidation: shouldSkipEnvValidation(), + emptyStringAsUndefined: true, +}); diff --git a/packages/api/src/middlewares/docker.ts b/packages/api/src/middlewares/docker.ts new file mode 100644 index 000000000..5a317b95a --- /dev/null +++ b/packages/api/src/middlewares/docker.ts @@ -0,0 +1,17 @@ +import { TRPCError } from "@trpc/server"; + +import { env } from "@homarr/docker/env"; + +import { publicProcedure } from "../trpc"; + +export const dockerMiddleware = () => { + return publicProcedure.use(async ({ next }) => { + if (env.ENABLE_DOCKER) { + return await next(); + } + throw new TRPCError({ + code: "NOT_FOUND", + message: "Docker route is not available", + }); + }); +}; diff --git a/packages/api/src/middlewares/kubernetes.ts b/packages/api/src/middlewares/kubernetes.ts new file mode 100644 index 000000000..8cefc0c35 --- /dev/null +++ b/packages/api/src/middlewares/kubernetes.ts @@ -0,0 +1,17 @@ +import { TRPCError } from "@trpc/server"; + +import { env } from "@homarr/docker/env"; + +import { publicProcedure } from "../trpc"; + +export const kubernetesMiddleware = () => { + return publicProcedure.use(async ({ next }) => { + if (env.ENABLE_KUBERNETES) { + return await next(); + } + throw new TRPCError({ + code: "NOT_FOUND", + message: "Kubernetes route is not available", + }); + }); +}; diff --git a/packages/api/src/root.ts b/packages/api/src/root.ts index 1a0a225df..7aec5f2ac 100644 --- a/packages/api/src/root.ts +++ b/packages/api/src/root.ts @@ -10,6 +10,7 @@ import { iconsRouter } from "./router/icons"; import { importRouter } from "./router/import/import-router"; import { integrationRouter } from "./router/integration/integration-router"; import { inviteRouter } from "./router/invite"; +import { kubernetesRouter } from "./router/kubernetes/router/kubernetes-router"; import { locationRouter } from "./router/location"; import { logRouter } from "./router/log"; import { mediaRouter } from "./router/medias/media-router"; @@ -39,6 +40,7 @@ export const appRouter = createTRPCRouter({ onboard: onboardRouter, home: homeRouter, docker: dockerRouter, + kubernetes: kubernetesRouter, serverSettings: serverSettingsRouter, cronJobs: cronJobsRouter, apiKeys: apiKeysRouter, diff --git a/packages/api/src/router/docker/docker-router.ts b/packages/api/src/router/docker/docker-router.ts index 05841e577..8b16de81c 100644 --- a/packages/api/src/router/docker/docker-router.ts +++ b/packages/api/src/router/docker/docker-router.ts @@ -8,6 +8,7 @@ import type { Container, ContainerInfo, ContainerState, Docker, Port } from "@ho import { logger } from "@homarr/log"; import { createCacheChannel } from "@homarr/redis"; +import { dockerMiddleware } from "../../middlewares/docker"; import { createTRPCRouter, permissionRequiredProcedure } from "../../trpc"; const dockerCache = createCacheChannel<{ @@ -15,72 +16,79 @@ const dockerCache = createCacheChannel<{ }>("docker-containers", 5 * 60 * 1000); export const dockerRouter = createTRPCRouter({ - getContainers: permissionRequiredProcedure.requiresPermission("admin").query(async () => { - const result = await dockerCache - .consumeAsync(async () => { - const dockerInstances = DockerSingleton.getInstances(); - const containers = await Promise.all( - // Return all the containers of all the instances into only one item - dockerInstances.map(({ instance, host: key }) => - instance.listContainers({ all: true }).then((containers) => - containers.map((container) => ({ - ...container, - instance: key, - })), + getContainers: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(dockerMiddleware()) + .query(async () => { + const result = await dockerCache + .consumeAsync(async () => { + const dockerInstances = DockerSingleton.getInstances(); + const containers = await Promise.all( + // Return all the containers of all the instances into only one item + dockerInstances.map(({ instance, host: key }) => + instance.listContainers({ all: true }).then((containers) => + containers.map((container) => ({ + ...container, + instance: key, + })), + ), ), - ), - ).then((containers) => containers.flat()); + ).then((containers) => containers.flat()); - const extractImage = (container: ContainerInfo) => container.Image.split("/").at(-1)?.split(":").at(0) ?? ""; - const likeQueries = containers.map((container) => like(icons.name, `%${extractImage(container)}%`)); - const dbIcons = - likeQueries.length >= 1 - ? await db.query.icons.findMany({ - where: or(...likeQueries), - }) - : []; + const extractImage = (container: ContainerInfo) => container.Image.split("/").at(-1)?.split(":").at(0) ?? ""; + const likeQueries = containers.map((container) => like(icons.name, `%${extractImage(container)}%`)); + const dbIcons = + likeQueries.length >= 1 + ? await db.query.icons.findMany({ + where: or(...likeQueries), + }) + : []; - return { - containers: containers.map((container) => ({ - ...container, - iconUrl: - dbIcons.find((icon) => { - const extractedImage = extractImage(container); - if (!extractedImage) return false; - return icon.name.toLowerCase().includes(extractedImage.toLowerCase()); - })?.url ?? null, - })), - }; - }) - .catch((error) => { - logger.error(error); - return { - isError: true, - error: error as unknown, - }; - }); + return { + containers: containers.map((container) => ({ + ...container, + iconUrl: + dbIcons.find((icon) => { + const extractedImage = extractImage(container); + if (!extractedImage) return false; + return icon.name.toLowerCase().includes(extractedImage.toLowerCase()); + })?.url ?? null, + })), + }; + }) + .catch((error) => { + logger.error(error); + return { + isError: true, + error: error as unknown, + }; + }); - if ("isError" in result) { - throw new TRPCError({ - code: "INTERNAL_SERVER_ERROR", - message: "An error occurred while fetching the containers", - cause: result.error, - }); - } + if ("isError" in result) { + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching the containers", + cause: result.error, + }); + } - const { data, timestamp } = result; + const { data, timestamp } = result; - return { - containers: sanitizeContainers(data.containers), - timestamp, - }; - }), - invalidate: permissionRequiredProcedure.requiresPermission("admin").mutation(async () => { - await dockerCache.invalidateAsync(); - return; - }), + return { + containers: sanitizeContainers(data.containers), + timestamp, + }; + }), + invalidate: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(dockerMiddleware()) + .mutation(async () => { + await dockerCache.invalidateAsync(); + return; + }), startAll: permissionRequiredProcedure .requiresPermission("admin") + .unstable_concat(dockerMiddleware()) .input(z.object({ ids: z.array(z.string()) })) .mutation(async ({ input }) => { await Promise.allSettled( @@ -94,6 +102,7 @@ export const dockerRouter = createTRPCRouter({ }), stopAll: permissionRequiredProcedure .requiresPermission("admin") + .unstable_concat(dockerMiddleware()) .input(z.object({ ids: z.array(z.string()) })) .mutation(async ({ input }) => { await Promise.allSettled( @@ -107,6 +116,7 @@ export const dockerRouter = createTRPCRouter({ }), restartAll: permissionRequiredProcedure .requiresPermission("admin") + .unstable_concat(dockerMiddleware()) .input(z.object({ ids: z.array(z.string()) })) .mutation(async ({ input }) => { await Promise.allSettled( @@ -120,6 +130,7 @@ export const dockerRouter = createTRPCRouter({ }), removeAll: permissionRequiredProcedure .requiresPermission("admin") + .unstable_concat(dockerMiddleware()) .input(z.object({ ids: z.array(z.string()) })) .mutation(async ({ input }) => { await Promise.allSettled( diff --git a/packages/api/src/router/kubernetes/kubernetes-client.ts b/packages/api/src/router/kubernetes/kubernetes-client.ts new file mode 100644 index 000000000..c0cb907aa --- /dev/null +++ b/packages/api/src/router/kubernetes/kubernetes-client.ts @@ -0,0 +1,73 @@ +import * as fs from "fs"; +import { CoreV1Api, KubeConfig, Metrics, NetworkingV1Api, VersionApi } from "@kubernetes/client-node"; + +import { env } from "../../env"; + +export class KubernetesClient { + private static instance: KubernetesClient | null = null; + public kubeConfig: KubeConfig; + public coreApi: CoreV1Api; + public networkingApi: NetworkingV1Api; + public metricsApi: Metrics; + public versionApi: VersionApi; + + private constructor() { + this.kubeConfig = new KubeConfig(); + + if (process.env.NODE_ENV === "development") { + this.kubeConfig.loadFromDefault(); + } else { + this.kubeConfig.loadFromCluster(); + + const currentCluster = this.kubeConfig.getCurrentCluster(); + if (!currentCluster) throw new Error("No cluster configuration found"); + + const token = fs.readFileSync("/var/run/secrets/kubernetes.io/serviceaccount/token", "utf8"); + const caData = fs.readFileSync("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt", "utf8"); + + const clusterWithCA = { + ...currentCluster, + name: `${currentCluster.name}-service-account`, + caData, + }; + + const serviceAccountUser = { + name: env.KUBERNETES_SERVICE_ACCOUNT_NAME ?? "default-sa", + token, + }; + + this.kubeConfig.clusters = []; + this.kubeConfig.users = []; + + this.kubeConfig.addCluster(clusterWithCA); + this.kubeConfig.addUser(serviceAccountUser); + + const currentContext = this.kubeConfig.getCurrentContext(); + const originalContext = this.kubeConfig.getContextObject(currentContext); + if (!originalContext) throw new Error("No context found"); + + const updatedContext = { + ...originalContext, + name: `${originalContext.name}-service-account`, + cluster: clusterWithCA.name, + user: serviceAccountUser.name, + }; + + this.kubeConfig.contexts = []; + this.kubeConfig.addContext(updatedContext); + this.kubeConfig.setCurrentContext(updatedContext.name); + } + + this.coreApi = this.kubeConfig.makeApiClient(CoreV1Api); + this.networkingApi = this.kubeConfig.makeApiClient(NetworkingV1Api); + this.metricsApi = new Metrics(this.kubeConfig); + this.versionApi = this.kubeConfig.makeApiClient(VersionApi); + } + + public static getInstance(): KubernetesClient { + if (!KubernetesClient.instance) { + KubernetesClient.instance = new KubernetesClient(); + } + return KubernetesClient.instance; + } +} diff --git a/packages/api/src/router/kubernetes/resource-parser/cpu-resource-parser.ts b/packages/api/src/router/kubernetes/resource-parser/cpu-resource-parser.ts new file mode 100644 index 000000000..d36017864 --- /dev/null +++ b/packages/api/src/router/kubernetes/resource-parser/cpu-resource-parser.ts @@ -0,0 +1,41 @@ +import type { ResourceParser } from "./resource-parser"; + +export class CpuResourceParser implements ResourceParser { + private readonly billionthsCore = 1_000_000_000; + private readonly millionthsCore = 1_000_000; + private readonly MiliCore = 1_000; + private readonly ThousandCore = 1_000; + + parse(value: string): number { + if (!value.length) { + return NaN; + } + + value = value.replace(/,/g, "").trim(); + + const [, numericValue, unit = ""] = /^([0-9.]+)\s*([a-zA-Z]*)$/.exec(value) ?? []; + + if (numericValue === undefined) { + return NaN; + } + + const parsedValue = parseFloat(numericValue); + + if (isNaN(parsedValue)) { + return NaN; + } + + switch (unit.toLowerCase()) { + case "n": // nano-cores (billionths of a core) + return parsedValue / this.billionthsCore; // 1 NanoCPU = 1/1,000,000,000 cores + case "u": // micro-cores (millionths of a core) + return parsedValue / this.millionthsCore; // 1 MicroCPU = 1/1,000,000 cores + case "m": // milli-cores + return parsedValue / this.MiliCore; // 1 milli-core = 1/1000 cores + case "k": // thousands of cores + return parsedValue * this.ThousandCore; // 1 thousand-core = 1000 cores + default: // cores (no unit) + return parsedValue; + } + } +} diff --git a/packages/api/src/router/kubernetes/resource-parser/memory-resource-parser.ts b/packages/api/src/router/kubernetes/resource-parser/memory-resource-parser.ts new file mode 100644 index 000000000..50a98b8ef --- /dev/null +++ b/packages/api/src/router/kubernetes/resource-parser/memory-resource-parser.ts @@ -0,0 +1,69 @@ +import type { ResourceParser } from "./resource-parser"; + +export class MemoryResourceParser implements ResourceParser { + private readonly binaryMultipliers: Record = { + ki: 1024, + mi: 1024 ** 2, + gi: 1024 ** 3, + ti: 1024 ** 4, + pi: 1024 ** 5, + } as const; + + private readonly decimalMultipliers: Record = { + k: 1000, + m: 1000 ** 2, + g: 1000 ** 3, + t: 1000 ** 4, + p: 1000 ** 5, + } as const; + + parse(value: string): number { + if (!value.length) { + return NaN; + } + + value = value.replace(/,/g, "").trim(); + + const [, numericValue, unit = ""] = /^([0-9.]+)\s*([a-zA-Z]*)$/.exec(value) ?? []; + + if (!numericValue) { + return NaN; + } + + const parsedValue = parseFloat(numericValue); + + if (isNaN(parsedValue)) { + return NaN; + } + + const unitLower = unit.toLowerCase(); + + // Handle binary units (Ki, Mi, Gi, etc.) + if (unitLower in this.binaryMultipliers) { + const multiplier = this.binaryMultipliers[unitLower]; + const giMultiplier = this.binaryMultipliers.gi; + + if (multiplier !== undefined && giMultiplier !== undefined) { + return (parsedValue * multiplier) / giMultiplier; + } + } + + // Handle decimal units (K, M, G, etc.) + if (unitLower in this.decimalMultipliers) { + const multiplier = this.decimalMultipliers[unitLower]; + const giMultiplier = this.binaryMultipliers.gi; + + if (multiplier !== undefined && giMultiplier !== undefined) { + return (parsedValue * multiplier) / giMultiplier; + } + } + + // No unit or unrecognized unit, assume bytes and convert to GiB + const giMultiplier = this.binaryMultipliers.gi; + if (giMultiplier !== undefined) { + return parsedValue / giMultiplier; + } + + return NaN; // Return NaN if giMultiplier is undefined + } +} diff --git a/packages/api/src/router/kubernetes/resource-parser/resource-parser.ts b/packages/api/src/router/kubernetes/resource-parser/resource-parser.ts new file mode 100644 index 000000000..23b652af8 --- /dev/null +++ b/packages/api/src/router/kubernetes/resource-parser/resource-parser.ts @@ -0,0 +1,3 @@ +export interface ResourceParser { + parse(value: string): number; +} diff --git a/packages/api/src/router/kubernetes/router/cluster.ts b/packages/api/src/router/kubernetes/router/cluster.ts new file mode 100644 index 000000000..8b44e5dcd --- /dev/null +++ b/packages/api/src/router/kubernetes/router/cluster.ts @@ -0,0 +1,196 @@ +import type { V1NodeList, VersionInfo } from "@kubernetes/client-node"; +import { TRPCError } from "@trpc/server"; + +import type { ClusterResourceCount, KubernetesCluster } from "@homarr/definitions"; +import { logger } from "@homarr/log"; + +import { kubernetesMiddleware } from "../../../middlewares/kubernetes"; +import { createTRPCRouter, permissionRequiredProcedure } from "../../../trpc"; +import { KubernetesClient } from "../kubernetes-client"; +import { CpuResourceParser } from "../resource-parser/cpu-resource-parser"; +import { MemoryResourceParser } from "../resource-parser/memory-resource-parser"; + +export const clusterRouter = createTRPCRouter({ + getCluster: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(kubernetesMiddleware()) + .query(async (): Promise => { + const { coreApi, metricsApi, versionApi, kubeConfig } = KubernetesClient.getInstance(); + + try { + const versionInfo = await versionApi.getCode(); + const nodes = await coreApi.listNode(); + const nodeMetricsClient = await metricsApi.getNodeMetrics(); + const listPodForAllNamespaces = await coreApi.listPodForAllNamespaces(); + + let totalCPUCapacity = 0; + let totalCPUAllocatable = 0; + let totalCPUUsage = 0; + + let totalMemoryCapacity = 0; + let totalMemoryAllocatable = 0; + let totalMemoryUsage = 0; + + let totalCapacityPods = 0; + const cpuResourceParser = new CpuResourceParser(); + const memoryResourceParser = new MemoryResourceParser(); + + nodes.items.forEach((node) => { + totalCapacityPods += Number(node.status?.capacity?.pods); + + const cpuCapacity = cpuResourceParser.parse(node.status?.capacity?.cpu ?? "0"); + const cpuAllocatable = cpuResourceParser.parse(node.status?.allocatable?.cpu ?? "0"); + totalCPUCapacity += cpuCapacity; + totalCPUAllocatable += cpuAllocatable; + + const memoryCapacity = memoryResourceParser.parse(node.status?.capacity?.memory ?? "0"); + const memoryAllocatable = memoryResourceParser.parse(node.status?.allocatable?.memory ?? "0"); + totalMemoryCapacity += memoryCapacity; + totalMemoryAllocatable += memoryAllocatable; + + const nodeName = node.metadata?.name; + const nodeMetric = nodeMetricsClient.items.find((metric) => metric.metadata.name === nodeName); + if (nodeMetric) { + const cpuUsage = cpuResourceParser.parse(nodeMetric.usage.cpu); + totalCPUUsage += cpuUsage; + + const memoryUsage = memoryResourceParser.parse(nodeMetric.usage.memory); + totalMemoryUsage += memoryUsage; + } + }); + + const reservedCPU = totalCPUCapacity - totalCPUAllocatable; + const reservedMemory = totalMemoryCapacity - totalMemoryAllocatable; + + const reservedCPUPercentage = (reservedCPU / totalCPUCapacity) * 100; + const reservedMemoryPercentage = (reservedMemory / totalMemoryCapacity) * 100; + + const usagePercentageAllocatable = (totalCPUUsage / totalCPUAllocatable) * 100; + const usagePercentageMemoryAllocatable = (totalMemoryUsage / totalMemoryAllocatable) * 100; + + const usedPodsPercentage = (listPodForAllNamespaces.items.length / totalCapacityPods) * 100; + + return { + name: kubeConfig.getCurrentContext(), + providers: getProviders(versionInfo, nodes), + kubernetesVersion: versionInfo.gitVersion, + architecture: versionInfo.platform, + nodeCount: nodes.items.length, + capacity: [ + { + type: "CPU", + resourcesStats: [ + { + percentageValue: Number(reservedCPUPercentage.toFixed(2)), + type: "Reserved", + capacityUnit: "Cores", + usedValue: Number(reservedCPU.toFixed(2)), + maxUsedValue: Number(totalCPUCapacity.toFixed(2)), + }, + { + percentageValue: Number(usagePercentageAllocatable.toFixed(2)), + type: "Used", + capacityUnit: "Cores", + usedValue: Number(totalCPUUsage.toFixed(2)), + maxUsedValue: Number(totalCPUAllocatable.toFixed(2)), + }, + ], + }, + { + type: "Memory", + resourcesStats: [ + { + percentageValue: Number(reservedMemoryPercentage.toFixed(2)), + type: "Reserved", + capacityUnit: "GiB", + usedValue: Number(reservedMemory.toFixed(2)), + maxUsedValue: Number(totalMemoryCapacity.toFixed(2)), + }, + { + percentageValue: Number(usagePercentageMemoryAllocatable.toFixed(2)), + type: "Used", + capacityUnit: "GiB", + usedValue: Number(totalMemoryUsage.toFixed(2)), + maxUsedValue: Number(totalMemoryAllocatable.toFixed(2)), + }, + ], + }, + { + type: "Pods", + resourcesStats: [ + { + percentageValue: Number(usedPodsPercentage.toFixed(2)), + type: "Used", + usedValue: listPodForAllNamespaces.items.length, + maxUsedValue: totalCapacityPods, + }, + ], + }, + ], + }; + } catch (error) { + logger.error("Unable to retrieve cluster", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes cluster", + cause: error, + }); + } + }), + getClusterResourceCounts: permissionRequiredProcedure + .requiresPermission("admin") + .query(async (): Promise => { + const { coreApi, networkingApi } = KubernetesClient.getInstance(); + + try { + const [pods, ingresses, services, configMaps, namespaces, nodes, secrets, volumes] = await Promise.all([ + coreApi.listPodForAllNamespaces(), + networkingApi.listIngressForAllNamespaces(), + coreApi.listServiceForAllNamespaces(), + coreApi.listConfigMapForAllNamespaces(), + coreApi.listNamespace(), + coreApi.listNode(), + coreApi.listSecretForAllNamespaces(), + coreApi.listPersistentVolumeClaimForAllNamespaces(), + ]); + + return [ + { label: "nodes", count: nodes.items.length }, + { label: "namespaces", count: namespaces.items.length }, + { label: "ingresses", count: ingresses.items.length }, + { label: "services", count: services.items.length }, + { label: "pods", count: pods.items.length }, + { label: "secrets", count: secrets.items.length }, + { label: "configmaps", count: configMaps.items.length }, + { label: "volumes", count: volumes.items.length }, + ]; + } catch (error) { + logger.error("Unable to retrieve cluster resource counts", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes resources count", + cause: error, + }); + } + }), +}); + +function getProviders(versionInfo: VersionInfo, nodes: V1NodeList) { + const providers = new Set(); + + if (versionInfo.gitVersion.includes("k3s")) providers.add("k3s"); + if (versionInfo.gitVersion.includes("gke")) providers.add("GKE"); + if (versionInfo.gitVersion.includes("eks")) providers.add("EKS"); + if (versionInfo.gitVersion.includes("aks")) providers.add("AKS"); + + nodes.items.forEach((node) => { + const nodeProviderLabel = + node.metadata?.labels?.["node.kubernetes.io/instance-type"] ?? node.metadata?.labels?.provider ?? ""; + if (nodeProviderLabel.includes("aws")) providers.add("EKS"); + if (nodeProviderLabel.includes("azure")) providers.add("AKS"); + if (nodeProviderLabel.includes("gce")) providers.add("GKE"); + if (nodeProviderLabel.includes("k3s")) providers.add("k3s"); + }); + + return Array.from(providers).join(", "); +} diff --git a/packages/api/src/router/kubernetes/router/configMaps.ts b/packages/api/src/router/kubernetes/router/configMaps.ts new file mode 100644 index 000000000..93aa1eb36 --- /dev/null +++ b/packages/api/src/router/kubernetes/router/configMaps.ts @@ -0,0 +1,36 @@ +import { TRPCError } from "@trpc/server"; + +import type { KubernetesBaseResource } from "@homarr/definitions"; +import { logger } from "@homarr/log"; + +import { kubernetesMiddleware } from "../../../middlewares/kubernetes"; +import { createTRPCRouter, permissionRequiredProcedure } from "../../../trpc"; +import { KubernetesClient } from "../kubernetes-client"; + +export const configMapsRouter = createTRPCRouter({ + getConfigMaps: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(kubernetesMiddleware()) + .query(async (): Promise => { + const { coreApi } = KubernetesClient.getInstance(); + + try { + const configMaps = await coreApi.listConfigMapForAllNamespaces(); + + return configMaps.items.map((configMap) => { + return { + name: configMap.metadata?.name ?? "unknown", + namespace: configMap.metadata?.namespace ?? "unknown", + creationTimestamp: configMap.metadata?.creationTimestamp, + }; + }); + } catch (error) { + logger.error("Unable to retrieve configMaps", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes ConfigMaps", + cause: error, + }); + } + }), +}); diff --git a/packages/api/src/router/kubernetes/router/ingresses.ts b/packages/api/src/router/kubernetes/router/ingresses.ts new file mode 100644 index 000000000..e0bea4932 --- /dev/null +++ b/packages/api/src/router/kubernetes/router/ingresses.ts @@ -0,0 +1,54 @@ +import type { V1HTTPIngressPath, V1Ingress, V1IngressRule } from "@kubernetes/client-node"; +import { TRPCError } from "@trpc/server"; + +import type { KubernetesIngress, KubernetesIngressPath, KubernetesIngressRuleAndPath } from "@homarr/definitions"; +import { logger } from "@homarr/log"; + +import { kubernetesMiddleware } from "../../../middlewares/kubernetes"; +import { createTRPCRouter, permissionRequiredProcedure } from "../../../trpc"; +import { KubernetesClient } from "../kubernetes-client"; + +export const ingressesRouter = createTRPCRouter({ + getIngresses: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(kubernetesMiddleware()) + .query(async (): Promise => { + const { networkingApi } = KubernetesClient.getInstance(); + try { + const ingresses = await networkingApi.listIngressForAllNamespaces(); + + const mapIngress = (ingress: V1Ingress): KubernetesIngress => { + return { + name: ingress.metadata?.name ?? "", + namespace: ingress.metadata?.namespace ?? "", + className: ingress.spec?.ingressClassName ?? "", + rulesAndPaths: getIngressRulesAndPaths(ingress.spec?.rules ?? []), + creationTimestamp: ingress.metadata?.creationTimestamp, + }; + }; + + const getIngressRulesAndPaths = (rules: V1IngressRule[] = []): KubernetesIngressRuleAndPath[] => { + return rules.map((rule) => ({ + host: rule.host ?? "", + paths: getPaths(rule.http?.paths ?? []), + })); + }; + + const getPaths = (paths: V1HTTPIngressPath[] = []): KubernetesIngressPath[] => { + return paths.map((path) => ({ + serviceName: path.backend.service?.name ?? "", + port: path.backend.service?.port?.number ?? 0, + })); + }; + + return ingresses.items.map(mapIngress); + } catch (error) { + logger.error("Unable to retrieve ingresses", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes ingresses", + cause: error, + }); + } + }), +}); diff --git a/packages/api/src/router/kubernetes/router/kubernetes-router.ts b/packages/api/src/router/kubernetes/router/kubernetes-router.ts new file mode 100644 index 000000000..ad9667c69 --- /dev/null +++ b/packages/api/src/router/kubernetes/router/kubernetes-router.ts @@ -0,0 +1,22 @@ +import { createTRPCRouter } from "../../../trpc"; +import { clusterRouter } from "./cluster"; +import { configMapsRouter } from "./configMaps"; +import { ingressesRouter } from "./ingresses"; +import { namespacesRouter } from "./namespaces"; +import { nodesRouter } from "./nodes"; +import { podsRouter } from "./pods"; +import { secretsRouter } from "./secrets"; +import { servicesRouter } from "./services"; +import { volumesRouter } from "./volumes"; + +export const kubernetesRouter = createTRPCRouter({ + nodes: nodesRouter, + cluster: clusterRouter, + namespaces: namespacesRouter, + ingresses: ingressesRouter, + services: servicesRouter, + pods: podsRouter, + secrets: secretsRouter, + configMaps: configMapsRouter, + volumes: volumesRouter, +}); diff --git a/packages/api/src/router/kubernetes/router/namespaces.ts b/packages/api/src/router/kubernetes/router/namespaces.ts new file mode 100644 index 000000000..90d5e62d9 --- /dev/null +++ b/packages/api/src/router/kubernetes/router/namespaces.ts @@ -0,0 +1,36 @@ +import { TRPCError } from "@trpc/server"; + +import type { KubernetesNamespace, KubernetesNamespaceState } from "@homarr/definitions"; +import { logger } from "@homarr/log"; + +import { kubernetesMiddleware } from "../../../middlewares/kubernetes"; +import { createTRPCRouter, permissionRequiredProcedure } from "../../../trpc"; +import { KubernetesClient } from "../kubernetes-client"; + +export const namespacesRouter = createTRPCRouter({ + getNamespaces: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(kubernetesMiddleware()) + .query(async (): Promise => { + const { coreApi } = KubernetesClient.getInstance(); + + try { + const namespaces = await coreApi.listNamespace(); + + return namespaces.items.map((namespace) => { + return { + status: namespace.status?.phase as KubernetesNamespaceState, + name: namespace.metadata?.name ?? "unknown", + creationTimestamp: namespace.metadata?.creationTimestamp, + } satisfies KubernetesNamespace; + }); + } catch (error) { + logger.error("Unable to retrieve namespaces", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes namespaces", + cause: error, + }); + } + }), +}); diff --git a/packages/api/src/router/kubernetes/router/nodes.ts b/packages/api/src/router/kubernetes/router/nodes.ts new file mode 100644 index 000000000..c241c6628 --- /dev/null +++ b/packages/api/src/router/kubernetes/router/nodes.ts @@ -0,0 +1,68 @@ +import { TRPCError } from "@trpc/server"; + +import type { KubernetesNode, KubernetesNodeState } from "@homarr/definitions"; +import { logger } from "@homarr/log"; + +import { kubernetesMiddleware } from "../../../middlewares/kubernetes"; +import { createTRPCRouter, permissionRequiredProcedure } from "../../../trpc"; +import { KubernetesClient } from "../kubernetes-client"; +import { CpuResourceParser } from "../resource-parser/cpu-resource-parser"; +import { MemoryResourceParser } from "../resource-parser/memory-resource-parser"; + +export const nodesRouter = createTRPCRouter({ + getNodes: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(kubernetesMiddleware()) + .query(async (): Promise => { + const { coreApi, metricsApi } = KubernetesClient.getInstance(); + + try { + const nodes = await coreApi.listNode(); + const nodeMetricsClient = await metricsApi.getNodeMetrics(); + const cpuResourceParser = new CpuResourceParser(); + const memoryResourceParser = new MemoryResourceParser(); + + return nodes.items.map((node) => { + const name = node.metadata?.name ?? "unknown"; + + const readyCondition = node.status?.conditions?.find((condition) => condition.type === "Ready"); + const status: KubernetesNodeState = readyCondition?.status === "True" ? "Ready" : "NotReady"; + + const cpuAllocatable = cpuResourceParser.parse(node.status?.allocatable?.cpu ?? "0"); + + const memoryAllocatable = memoryResourceParser.parse(node.status?.allocatable?.memory ?? "0"); + + let cpuUsage = 0; + let memoryUsage = 0; + + const nodeMetric = nodeMetricsClient.items.find((metric) => metric.metadata.name === name); + if (nodeMetric) { + cpuUsage += cpuResourceParser.parse(nodeMetric.usage.cpu); + memoryUsage += memoryResourceParser.parse(nodeMetric.usage.memory); + } + + const usagePercentageCPUAllocatable = (cpuUsage / cpuAllocatable) * 100; + const usagePercentageMemoryAllocatable = (memoryUsage / memoryAllocatable) * 100; + + return { + name, + status, + allocatableCpuPercentage: Number(usagePercentageCPUAllocatable.toFixed(0)), + allocatableRamPercentage: Number(usagePercentageMemoryAllocatable.toFixed(0)), + podsCount: Number(node.status?.capacity?.pods), + operatingSystem: node.status?.nodeInfo?.operatingSystem, + architecture: node.status?.nodeInfo?.architecture, + kubernetesVersion: node.status?.nodeInfo?.kubeletVersion, + creationTimestamp: node.metadata?.creationTimestamp, + }; + }); + } catch (error) { + logger.error("Unable to retrieve nodes", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes nodes", + cause: error, + }); + } + }), +}); diff --git a/packages/api/src/router/kubernetes/router/pods.ts b/packages/api/src/router/kubernetes/router/pods.ts new file mode 100644 index 000000000..bb785fa65 --- /dev/null +++ b/packages/api/src/router/kubernetes/router/pods.ts @@ -0,0 +1,104 @@ +import type { KubeConfig, V1OwnerReference } from "@kubernetes/client-node"; +import { AppsV1Api } from "@kubernetes/client-node"; +import { TRPCError } from "@trpc/server"; + +import type { KubernetesPod } from "@homarr/definitions"; +import { logger } from "@homarr/log"; + +import { kubernetesMiddleware } from "../../../middlewares/kubernetes"; +import { createTRPCRouter, permissionRequiredProcedure } from "../../../trpc"; +import { KubernetesClient } from "../kubernetes-client"; + +export const podsRouter = createTRPCRouter({ + getPods: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(kubernetesMiddleware()) + .query(async (): Promise => { + const { coreApi, kubeConfig } = KubernetesClient.getInstance(); + try { + const podsResp = await coreApi.listPodForAllNamespaces(); + + const pods: KubernetesPod[] = []; + + for (const pod of podsResp.items) { + const labels = pod.metadata?.labels ?? {}; + const ownerRefs = pod.metadata?.ownerReferences ?? []; + + let applicationType = "Pod"; + + if (labels["app.kubernetes.io/managed-by"] === "Helm") { + applicationType = "Helm"; + } else { + for (const owner of ownerRefs) { + if (["Deployment", "StatefulSet", "DaemonSet"].includes(owner.kind)) { + applicationType = owner.kind; + break; + } else if (owner.kind === "ReplicaSet") { + const ownerType = await getOwnerKind(kubeConfig, owner, pod.metadata?.namespace ?? ""); + if (ownerType) { + applicationType = ownerType; + break; + } + } + } + } + + pods.push({ + name: pod.metadata?.name ?? "", + namespace: pod.metadata?.namespace ?? "", + image: pod.spec?.containers.map((container) => container.image).join(", "), + applicationType, + status: pod.status?.phase ?? "unknown", + creationTimestamp: pod.metadata?.creationTimestamp, + }); + } + + return pods; + } catch (error) { + logger.error("Unable to retrieve pods", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes pods", + cause: error, + }); + } + }), +}); + +async function getOwnerKind( + kubeConfig: KubeConfig, + ownerRef: V1OwnerReference, + namespace: string, +): Promise { + const { kind, name } = ownerRef; + + if (kind === "ReplicaSet") { + const appsApi = kubeConfig.makeApiClient(AppsV1Api); + try { + const rsResp = await appsApi.readNamespacedReplicaSet({ + name, + namespace, + }); + + if (rsResp.metadata?.ownerReferences) { + for (const rsOwner of rsResp.metadata.ownerReferences) { + if (rsOwner.kind === "Deployment") { + return "Deployment"; + } + const parentKind = await getOwnerKind(kubeConfig, rsOwner, namespace); + if (parentKind) return parentKind; + } + } + return "ReplicaSet"; + } catch (error) { + logger.error("Error reading ReplicaSet:", error); + return null; + } + } + + if (["Deployment", "StatefulSet", "DaemonSet"].includes(kind)) { + return kind; + } + + return null; +} diff --git a/packages/api/src/router/kubernetes/router/secrets.ts b/packages/api/src/router/kubernetes/router/secrets.ts new file mode 100644 index 000000000..471eab785 --- /dev/null +++ b/packages/api/src/router/kubernetes/router/secrets.ts @@ -0,0 +1,36 @@ +import { TRPCError } from "@trpc/server"; + +import type { KubernetesSecret } from "@homarr/definitions"; +import { logger } from "@homarr/log"; + +import { kubernetesMiddleware } from "../../../middlewares/kubernetes"; +import { createTRPCRouter, permissionRequiredProcedure } from "../../../trpc"; +import { KubernetesClient } from "../kubernetes-client"; + +export const secretsRouter = createTRPCRouter({ + getSecrets: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(kubernetesMiddleware()) + .query(async (): Promise => { + const { coreApi } = KubernetesClient.getInstance(); + try { + const secrets = await coreApi.listSecretForAllNamespaces(); + + return secrets.items.map((secret) => { + return { + name: secret.metadata?.name ?? "unknown", + namespace: secret.metadata?.namespace ?? "unknown", + type: secret.type ?? "unknown", + creationTimestamp: secret.metadata?.creationTimestamp, + }; + }); + } catch (error) { + logger.error("Unable to retrieve secrets", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes secrets", + cause: error, + }); + } + }), +}); diff --git a/packages/api/src/router/kubernetes/router/services.ts b/packages/api/src/router/kubernetes/router/services.ts new file mode 100644 index 000000000..edb5c75ba --- /dev/null +++ b/packages/api/src/router/kubernetes/router/services.ts @@ -0,0 +1,40 @@ +import { TRPCError } from "@trpc/server"; + +import type { KubernetesService } from "@homarr/definitions"; +import { logger } from "@homarr/log"; + +import { kubernetesMiddleware } from "../../../middlewares/kubernetes"; +import { createTRPCRouter, permissionRequiredProcedure } from "../../../trpc"; +import { KubernetesClient } from "../kubernetes-client"; + +export const servicesRouter = createTRPCRouter({ + getServices: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(kubernetesMiddleware()) + .query(async (): Promise => { + const { coreApi } = KubernetesClient.getInstance(); + + try { + const services = await coreApi.listServiceForAllNamespaces(); + + return services.items.map((service) => { + return { + name: service.metadata?.name ?? "unknown", + namespace: service.metadata?.namespace ?? "", + type: service.spec?.type ?? "", + ports: service.spec?.ports?.map(({ port, protocol }) => `${port}/${protocol}`), + targetPorts: service.spec?.ports?.map(({ targetPort }) => `${targetPort}`), + clusterIP: service.spec?.clusterIP ?? "", + creationTimestamp: service.metadata?.creationTimestamp, + }; + }); + } catch (error) { + logger.error("Unable to retrieve services", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes services", + cause: error, + }); + } + }), +}); diff --git a/packages/api/src/router/kubernetes/router/volumes.ts b/packages/api/src/router/kubernetes/router/volumes.ts new file mode 100644 index 000000000..b2e06df1a --- /dev/null +++ b/packages/api/src/router/kubernetes/router/volumes.ts @@ -0,0 +1,42 @@ +import { TRPCError } from "@trpc/server"; + +import type { KubernetesVolume } from "@homarr/definitions"; +import { logger } from "@homarr/log"; + +import { kubernetesMiddleware } from "../../../middlewares/kubernetes"; +import { createTRPCRouter, permissionRequiredProcedure } from "../../../trpc"; +import { KubernetesClient } from "../kubernetes-client"; + +export const volumesRouter = createTRPCRouter({ + getVolumes: permissionRequiredProcedure + .requiresPermission("admin") + .unstable_concat(kubernetesMiddleware()) + .query(async (): Promise => { + const { coreApi } = KubernetesClient.getInstance(); + + try { + const volumes = await coreApi.listPersistentVolumeClaimForAllNamespaces(); + + return volumes.items.map((volume) => { + return { + name: volume.metadata?.name ?? "unknown", + namespace: volume.metadata?.namespace ?? "unknown", + accessModes: volume.status?.accessModes?.map((accessMode) => accessMode) ?? [], + storage: volume.status?.capacity?.storage ?? "", + storageClassName: volume.spec?.storageClassName ?? "", + volumeMode: volume.spec?.volumeMode ?? "", + volumeName: volume.spec?.volumeName ?? "", + status: volume.status?.phase ?? "", + creationTimestamp: volume.metadata?.creationTimestamp, + }; + }); + } catch (error) { + logger.error("Unable to retrieve volumes", error); + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "An error occurred while fetching Kubernetes Volumes", + cause: error, + }); + } + }), +}); diff --git a/packages/api/src/router/test/docker/docker-router.spec.ts b/packages/api/src/router/test/docker/docker-router.spec.ts index 24e3793c4..2becec4e6 100644 --- a/packages/api/src/router/test/docker/docker-router.spec.ts +++ b/packages/api/src/router/test/docker/docker-router.spec.ts @@ -24,6 +24,12 @@ vi.mock("@homarr/redis", () => ({ }), })); +vi.mock("@homarr/docker/env", () => ({ + env: { + ENABLE_DOCKER: true, + }, +})); + const createSessionWithPermissions = (...permissions: GroupPermissionKey[]) => ({ user: { diff --git a/packages/api/src/router/test/kubernetes/resource-parser/cpu-resource-parser.spec.ts b/packages/api/src/router/test/kubernetes/resource-parser/cpu-resource-parser.spec.ts new file mode 100644 index 000000000..819dce1ff --- /dev/null +++ b/packages/api/src/router/test/kubernetes/resource-parser/cpu-resource-parser.spec.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from "vitest"; + +import { CpuResourceParser } from "../../../kubernetes/resource-parser/cpu-resource-parser"; + +describe("CpuResourceParser", () => { + const parser = new CpuResourceParser(); + + it("should return NaN for empty or invalid input", () => { + expect(parser.parse("")).toBeNaN(); + expect(parser.parse(" ")).toBeNaN(); + expect(parser.parse("abc")).toBeNaN(); + }); + + it("should parse CPU values without a unit (cores)", () => { + expect(parser.parse("1")).toBe(1); + expect(parser.parse("2.5")).toBe(2.5); + expect(parser.parse("10")).toBe(10); + }); + + it("should parse CPU values with milli-core unit ('m')", () => { + expect(parser.parse("500m")).toBe(0.5); // 500 milli-cores = 0.5 cores + expect(parser.parse("250m")).toBe(0.25); + expect(parser.parse("1000m")).toBe(1); + }); + + it("should parse CPU values with kilo-core unit ('k')", () => { + expect(parser.parse("1k")).toBe(1000); // 1 kilo-core = 1000 cores + expect(parser.parse("2k")).toBe(2000); + expect(parser.parse("0.5k")).toBe(500); + }); + + it("should parse CPU values with nano-core unit ('n')", () => { + // Adjust the expected values for nano-cores to account for floating-point precision + expect(parser.parse("1000000000n")).toBe(1); // 1 NanoCPU = 1/1,000,000,000 cores + expect(parser.parse("500000000n")).toBe(0.5); + expect(parser.parse("0.000000001n")).toBe(0.000000000000000001); // Tiny value + }); + + it("should parse CPU values with micro-core unit ('u')", () => { + // Adjust the expected values for micro-cores to account for floating-point precision + expect(parser.parse("1000000u")).toBe(1); // 1 MicroCPU = 1/1,000,000 cores + expect(parser.parse("500000u")).toBe(0.5); + expect(parser.parse("0.000001u")).toBe(0.000000000001); // Tiny value + }); + + it("should handle input with commas", () => { + expect(parser.parse("1,000")).toBe(1000); // 1,000 cores + expect(parser.parse("1,500m")).toBe(1.5); // 1,500 milli-cores = 1.5 cores + }); + + it("should ignore leading and trailing whitespace", () => { + expect(parser.parse(" 1 ")).toBe(1); + expect(parser.parse(" 500m ")).toBe(0.5); + expect(parser.parse(" 2k ")).toBe(2000); + }); +}); diff --git a/packages/api/src/router/test/kubernetes/resource-parser/memory-resource-parser.spec.ts b/packages/api/src/router/test/kubernetes/resource-parser/memory-resource-parser.spec.ts new file mode 100644 index 000000000..f56f78237 --- /dev/null +++ b/packages/api/src/router/test/kubernetes/resource-parser/memory-resource-parser.spec.ts @@ -0,0 +1,61 @@ +import { describe, expect, it } from "vitest"; + +import { MemoryResourceParser } from "../../../kubernetes/resource-parser/memory-resource-parser"; + +const BYTES_IN_GIB = 1024 ** 3; // 1 GiB in bytes +const BYTES_IN_MIB = 1024 ** 2; // 1 MiB in bytes +const BYTES_IN_KIB = 1024; // 1 KiB in bytes +const KI = "Ki"; +const MI = "Mi"; +const GI = "Gi"; +const TI = "Ti"; +const PI = "Pi"; + +describe("MemoryResourceParser", () => { + const parser = new MemoryResourceParser(); + + it("should parse values without units as bytes and convert to GiB", () => { + expect(parser.parse("1073741824")).toBe(1); // 1 GiB + expect(parser.parse("2147483648")).toBe(2); // 2 GiB + }); + + it("should parse binary units (Ki, Mi, Gi, Ti, Pi) into GiB", () => { + expect(parser.parse(`1024${KI}`)).toBeCloseTo(1 / 1024); // 1 MiB = 1/1024 GiB + expect(parser.parse(`1${MI}`)).toBeCloseTo(1 / 1024); // 1 MiB = 1/1024 GiB + expect(parser.parse(`1${GI}`)).toBe(1); // 1 GiB + expect(parser.parse(`1${TI}`)).toBe(BYTES_IN_KIB); // 1 TiB = 1024 GiB + expect(parser.parse(`1${PI}`)).toBe(BYTES_IN_MIB); // 1 PiB = 1024^2 GiB + }); + + it("should parse decimal units (K, M, G, T, P) into GiB", () => { + expect(parser.parse("1000K")).toBeCloseTo(1000 / BYTES_IN_GIB); // 1000 KB + expect(parser.parse("1M")).toBeCloseTo(1 / BYTES_IN_KIB); // 1 MB = 1/1024 GiB + expect(parser.parse("1G")).toBeCloseTo(0.9313225746154785); // 1 GB ≈ 0.931 GiB + expect(parser.parse("1T")).toBeCloseTo(931.3225746154785); // 1 TB ≈ 931.32 GiB + expect(parser.parse("1P")).toBeCloseTo(931322.5746154785); // 1 PB ≈ 931,322.57 GiB + }); + + it("should handle invalid input and return NaN", () => { + expect(parser.parse("")).toBeNaN(); + expect(parser.parse(" ")).toBeNaN(); + expect(parser.parse("abc")).toBeNaN(); + }); + + it("should handle commas in input and convert to GiB", () => { + expect(parser.parse("1,073,741,824")).toBe(1); // 1 GiB + expect(parser.parse("1,024Ki")).toBeCloseTo(1 / BYTES_IN_KIB); // 1 MiB + }); + + it("should handle lowercase and uppercase units", () => { + expect(parser.parse("1ki")).toBeCloseTo(1 / BYTES_IN_KIB); // 1 MiB + expect(parser.parse("1KI")).toBeCloseTo(1 / BYTES_IN_KIB); + expect(parser.parse("1Mi")).toBeCloseTo(1 / BYTES_IN_KIB); + expect(parser.parse("1m")).toBeCloseTo(1 / BYTES_IN_KIB); + }); + + it("should assume bytes for unrecognized or no units and convert to GiB", () => { + expect(parser.parse("1073741824")).toBe(1); // 1 GiB + expect(parser.parse("42")).toBeCloseTo(42 / BYTES_IN_GIB); // 42 bytes in GiB + expect(parser.parse("42unknown")).toBeCloseTo(42 / BYTES_IN_GIB); // Invalid unit = bytes + }); +}); diff --git a/packages/definitions/src/index.ts b/packages/definitions/src/index.ts index 45f655491..22ca76b84 100644 --- a/packages/definitions/src/index.ts +++ b/packages/definitions/src/index.ts @@ -4,6 +4,7 @@ export * from "./section"; export * from "./widget"; export * from "./permissions"; export * from "./docker"; +export * from "./kubernetes"; export * from "./auth"; export * from "./user"; export * from "./group"; diff --git a/packages/definitions/src/kubernetes.ts b/packages/definitions/src/kubernetes.ts new file mode 100644 index 000000000..e6a6c710a --- /dev/null +++ b/packages/definitions/src/kubernetes.ts @@ -0,0 +1,110 @@ +export const kubernetesNodeStates = ["Ready", "NotReady"] as const; +export const kubernetesNamespaceStates = ["Active", "Terminating"] as const; +export const kubernetesResourceTypes = ["Reserved", "Used"] as const; +export const kubernetesCapacityTypes = ["Pods", "CPU", "Memory"] as const; +export const kubernetesLabelResourceTypes = [ + "configmaps", + "pods", + "ingresses", + "namespaces", + "nodes", + "secrets", + "services", + "volumes", +] as const; + +export type KubernetesNodeState = (typeof kubernetesNodeStates)[number]; +export type KubernetesNamespaceState = (typeof kubernetesNamespaceStates)[number]; +export type KubernetesResourceType = (typeof kubernetesResourceTypes)[number]; +export type KubernetesCapacityType = (typeof kubernetesCapacityTypes)[number]; +export type KubernetesLabelResourceType = (typeof kubernetesLabelResourceTypes)[number]; + +export interface KubernetesBaseResource { + name: string; + namespace?: string; + creationTimestamp?: Date; +} + +export interface KubernetesVolume extends KubernetesBaseResource { + accessModes: string[]; + storage: string; + storageClassName: string; + volumeMode: string; + volumeName: string; + status: string; +} + +export interface KubernetesSecret extends KubernetesBaseResource { + type: string; +} + +export interface KubernetesPod extends KubernetesBaseResource { + image?: string; + applicationType: string; + status: string; +} + +export interface KubernetesService extends KubernetesBaseResource { + type: string; + ports?: string[]; + targetPorts?: string[]; + clusterIP: string; +} + +export interface KubernetesIngressPath { + serviceName: string; + port: number; +} + +export interface KubernetesIngressRuleAndPath { + host: string; + paths: KubernetesIngressPath[]; +} + +export interface KubernetesIngress extends KubernetesBaseResource { + className: string; + rulesAndPaths: KubernetesIngressRuleAndPath[]; +} + +export interface KubernetesNamespace extends KubernetesBaseResource { + status: KubernetesNamespaceState; +} + +export interface KubernetesNode { + name: string; + status: KubernetesNodeState; + allocatableCpuPercentage: number; + allocatableRamPercentage: number; + podsCount: number; + operatingSystem?: string; + architecture?: string; + kubernetesVersion?: string; + creationTimestamp?: Date; +} + +export interface KubernetesCluster { + name: string; + providers: string; + kubernetesVersion: string; + architecture: string; + nodeCount: number; + capacity: KubernetesCapacity[]; +} + +export interface KubernetesCapacity { + type: KubernetesCapacityType; + resourcesStats: KubernetesResourceStat[]; +} + +export interface KubernetesResourceStat { + percentageValue: number; + type: KubernetesResourceType; + capacityUnit?: string; + usedValue: number; + maxUsedValue: number; +} + +export interface ClusterResourceCount { + label: string; + count: number; +} diff --git a/packages/docker/src/env.ts b/packages/docker/src/env.ts index 437684454..e71a26a66 100644 --- a/packages/docker/src/env.ts +++ b/packages/docker/src/env.ts @@ -1,12 +1,15 @@ import { z } from "zod"; import { createEnv } from "@homarr/env"; +import { createBooleanSchema } from "@homarr/env/schemas"; export const env = createEnv({ server: { // Comma separated list of docker hostnames that can be used to connect to query the docker endpoints (localhost:2375,host.docker.internal:2375, ...) DOCKER_HOSTNAMES: z.string().optional(), DOCKER_PORTS: z.string().optional(), + ENABLE_DOCKER: createBooleanSchema(true), + ENABLE_KUBERNETES: createBooleanSchema(false), }, experimental__runtimeEnv: process.env, }); diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 3565b0dbc..320abee21 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -2325,6 +2325,7 @@ "label": "Tools", "items": { "docker": "Docker", + "kubernetes": "Kubernetes", "logs": "Logs", "api": "API", "certificates": "Certificates", @@ -2758,7 +2759,7 @@ "title": "Containers", "table": { "updated": "Updated {when}", - "search": "Seach {count} containers", + "search": "Search {count} containers", "selected": "{selectCount} of {totalCount} containers selected" }, "field": { @@ -2871,6 +2872,246 @@ "internalServerError": "Failed to fetch Docker containers" } }, + "kubernetes": { + "cluster": { + "title": "Cluster Dashboard", + "label": "Cluster", + "providers": "Providers", + "version": "Version", + "architecture": "Architecture", + "capacity": { + "title": "Capacity", + "resource": { + "reserved": "Reserved", + "used": "Used" + } + }, + "resources": { + "title": "Resources", + "nodes": "Nodes", + "namespaces": "Namespaces", + "ingresses": "Ingresses", + "services": "Services", + "pods": "Pods", + "configmaps": "ConfigMaps", + "secrets": "Secrets", + "volumes": "Volumes" + } + }, + "nodes": { + "label": "Nodes", + "field": { + "name": { + "label": "Name" + }, + "state": { + "label": "State", + "option": { + "ready": "Ready", + "NotReady": "Not Ready" + } + }, + "cpu": { + "label": "CPU" + }, + "memory": { + "label": "RAM" + }, + "pods": { + "label": "Pods" + }, + "operatingSystem": { + "label": "OS" + }, + "architecture": { + "label": "Architecture" + }, + "kubernetesVersion": { + "label": "Kubernetes version" + }, + "creationTimestamp": { + "label": "Created" + } + }, + "table": { + "search": "Search {count} nodes" + } + }, + "namespaces": { + "label": "Namespaces", + "field": { + "name": { + "label": "Name" + }, + "state": { + "label": "State", + "option": { + "active": "Active", + "terminating": "Terminating" + } + }, + "creationTimestamp": { + "label": "Created" + } + }, + "table": { + "search": "Search {count} namespaces" + } + }, + "ingresses": { + "label": "Ingresses", + "field": { + "name": { + "label": "Name" + }, + "namespace": { + "label": "Namespace" + }, + "className": { + "label": "Class name" + }, + "rulesAndPaths": { + "label": "Rules & paths" + }, + "creationTimestamp": { + "label": "Created" + } + }, + "table": { + "search": "Search {count} ingresses" + } + }, + "services": { + "label": "Services", + "field": { + "name": { + "label": "Name" + }, + "namespace": { + "label": "Namespace" + }, + "type": { + "label": "Type" + }, + "ports": { + "label": "Ports" + }, + "targetPorts": { + "label": "Target ports" + }, + "clusterIP": { + "label": "Cluster IP" + }, + "creationTimestamp": { + "label": "Created" + } + }, + "table": { + "search": "Search {count} services" + } + }, + "pods": { + "label": "Pods", + "field": { + "name": { + "label": "Name" + }, + "namespace": { + "label": "Namespace" + }, + "image": { + "label": "Image" + }, + "applicationType": { + "label": "Application type" + }, + "status": { + "label": "Status" + }, + "creationTimestamp": { + "label": "Created" + } + }, + "table": { + "search": "Search {count} pods" + } + }, + "secrets": { + "label": "Secrets", + "field": { + "name": { + "label": "Name" + }, + "namespace": { + "label": "namespace" + }, + "type": { + "label": "type" + }, + "creationTimestamp": { + "label": "Created" + } + }, + "table": { + "search": "Search {count} secrets" + } + }, + "configmaps": { + "label": "ConfigMaps", + "field": { + "name": { + "label": "Name" + }, + "namespace": { + "label": "namespace" + }, + "creationTimestamp": { + "label": "Created" + } + }, + "table": { + "search": "Search {count} configMaps" + } + }, + "volumes": { + "label": "Volumes", + "field": { + "name": { + "label": "Name" + }, + "namespace": { + "label": "Namespace" + }, + "accessModes": { + "label": "Access Modes" + }, + "storage": { + "label": "Storage" + }, + "storageClassName": { + "label": "Storage Class Name" + }, + "volumeMode": { + "label": "Volume Mode" + }, + "volumeName": { + "label": "Volume Name" + }, + "status": { + "label": "Status" + }, + "creationTimestamp": { + "label": "Created" + } + }, + "table": { + "search": "Search {count} volumes" + } + }, + "error": { + "internalServerError": "Failed to fetch Kubernetes data" + } + }, "permission": { "title": "Permissions", "userSelect": { @@ -2956,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "Kubernetes", + "nodes": { + "label": "Nodes" + }, + "namespaces": { + "label": "Namespaces" + }, + "ingresses": { + "label": "Ingresses" + }, + "services": { + "label": "Services" + }, + "pods": { + "label": "pods" + }, + "configmaps": { + "label": "ConfigMaps" + }, + "secrets": { + "label": "Secrets" + }, + "volumes": { + "label": "Volumes" + } + }, "logs": { "label": "Logs" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ef31b534..b7333a3eb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -578,6 +578,9 @@ importers: '@homarr/validation': specifier: workspace:^0.1.0 version: link:../validation + '@kubernetes/client-node': + specifier: ^1.0.0 + version: 1.0.0 '@trpc/client': specifier: next version: 11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2) @@ -1480,7 +1483,7 @@ importers: version: link:../ui '@mantine/notifications': specifier: ^7.17.1 - version: 7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@tabler/icons-react': specifier: ^3.31.0 version: 3.31.0(react@19.0.0) @@ -1833,7 +1836,7 @@ importers: version: 7.17.1(react@19.0.0) '@mantine/spotlight': specifier: ^7.17.1 - version: 7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@tabler/icons-react': specifier: ^3.31.0 version: 3.31.0(react@19.0.0) @@ -3435,6 +3438,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} @@ -3471,6 +3478,21 @@ packages: '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@jsep-plugin/assignment@1.3.0': + resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@jsep-plugin/regex@1.0.4': + resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@kubernetes/client-node@1.0.0': + resolution: {integrity: sha512-a8NSvFDSHKFZ0sR1hbPSf8IDFNJwctEU5RodSCNiq/moRXWmrdmqhb1RRQzF+l+TSBaDgHw3YsYNxxE92STBzw==} + '@libsql/client-wasm@0.14.0': resolution: {integrity: sha512-gB/jtz0xuwrqAHApBv9e9JSew2030Fhj2edyZ83InZ4yPj/Q2LTUlEhaspEYT0T0xsAGqPy38uGrmq/OGS+DdQ==} bundledDependencies: @@ -4664,6 +4686,9 @@ packages: '@types/inquirer@6.5.0': resolution: {integrity: sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==} + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -4691,6 +4716,9 @@ packages: '@types/node-cron@3.0.11': resolution: {integrity: sha512-0ikrnug3/IyneSHqCBeslAhlK2aBfYek1fGo4bP4QnZPmiqSGRK+Oy7ZMisLWkesffJvQ1cqAcBnJC+8+nxIAg==} + '@types/node-fetch@2.6.12': + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + '@types/node@18.19.50': resolution: {integrity: sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==} @@ -4738,9 +4766,15 @@ packages: '@types/ssh2@1.15.1': resolution: {integrity: sha512-ZIbEqKAsi5gj35y4P4vkJYly642wIbY6PqoN0xiyQGshKUGXR9WQjF/iF9mXBQ8uBKy3ezfsCkcoHKhd0BzuDA==} + '@types/stream-buffers@3.0.7': + resolution: {integrity: sha512-azOCy05sXVXrO+qklf0c/B07H/oHaIuDDAiHPVwlk3A9Ek+ksHyTeMajLZl3r76FxpPpxem//4Te61G1iW3Giw==} + '@types/swagger-ui-react@5.18.0': resolution: {integrity: sha512-c2M9adVG7t28t1pq19K9Jt20VLQf0P/fwJwnfcmsVVsdkwCWhRmbKDu+tIs0/NGwJ/7GY8lBx+iKZxuDI5gDbw==} + '@types/tar@6.1.13': + resolution: {integrity: sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==} + '@types/through@0.0.33': resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} @@ -5404,6 +5438,10 @@ packages: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + chroma-js@3.1.2: resolution: {integrity: sha512-IJnETTalXbsLx1eKEgx19d5L6SRM7cH4vINw/99p/M11HCuXGRWL+6YmCm7FWFGIo6dtWuQoQi1dc5yQ7ESIHg==} @@ -7203,6 +7241,11 @@ packages: isomorphic-fetch@3.0.0: resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} + isomorphic-ws@5.0.0: + resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + peerDependencies: + ws: '*' + issue-parser@7.0.1: resolution: {integrity: sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==} engines: {node: ^18.17 || >=20.6.1} @@ -7285,6 +7328,10 @@ packages: canvas: optional: true + jsep@1.4.0: + resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} + engines: {node: '>= 10.16.0'} + jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} @@ -7317,6 +7364,11 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonpath-plus@10.3.0: + resolution: {integrity: sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==} + engines: {node: '>=18.0.0'} + hasBin: true + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -7616,6 +7668,10 @@ packages: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} engines: {node: '>=8'} + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + minipass@5.0.0: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} @@ -7628,6 +7684,10 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -7643,6 +7703,11 @@ packages: engines: {node: '>=10'} hasBin: true + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + moment-timezone@0.5.47: resolution: {integrity: sha512-UbNt/JAWS0m/NJOebR0QMRHBk0hu03r5dx9GK8Cs0AS3I81yDcOc9k+DytPItgVvBP7J6Mf6U2n3BPAacAV9oA==} @@ -8044,6 +8109,9 @@ packages: openapi3-ts@4.4.0: resolution: {integrity: sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==} + openid-client@6.3.3: + resolution: {integrity: sha512-lTK8AV8SjqCM4qznLX0asVESAwzV39XTVdfMAM185ekuaZCnkWdPzcxMTXNlsm9tsUAMa1Q30MBmKAykdT1LWw==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -8805,6 +8873,10 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + rollup@4.21.3: resolution: {integrity: sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -9143,6 +9215,10 @@ packages: std-env@3.8.0: resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + stream-buffers@3.0.3: + resolution: {integrity: sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==} + engines: {node: '>= 0.10.0'} + stream-combiner2@1.1.1: resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} @@ -9331,6 +9407,10 @@ packages: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + temp-dir@3.0.0: resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} engines: {node: '>=14.16'} @@ -9434,6 +9514,9 @@ packages: resolution: {integrity: sha512-Oh/CqRQ1NXNY7cy9NkTPUauOWiTro0jEYZTioGbOmcQh6EC45oribyIMJp0OJO3677r13tO6SKdWoGZUx2BDFw==} hasBin: true + tmp-promise@3.0.3: + resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -10200,6 +10283,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yaml@2.5.1: resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} engines: {node: '>= 14'} @@ -11154,6 +11241,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@istanbuljs/schema@0.1.3': {} '@jellyfin/sdk@0.11.0(axios@1.7.7)': @@ -11189,6 +11280,39 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} + '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsep-plugin/regex@1.0.4(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@kubernetes/client-node@1.0.0': + dependencies: + '@types/js-yaml': 4.0.9 + '@types/node': 22.13.10 + '@types/node-fetch': 2.6.12 + '@types/stream-buffers': 3.0.7 + '@types/tar': 6.1.13 + '@types/ws': 8.18.0 + form-data: 4.0.1 + isomorphic-ws: 5.0.0(ws@8.18.1) + js-yaml: 4.1.0 + jsonpath-plus: 10.3.0 + node-fetch: 2.7.0 + openid-client: 6.3.3 + rfc4648: 1.5.3 + stream-buffers: 3.0.3 + tar: 7.4.3 + tmp-promise: 3.0.3 + tslib: 2.8.1 + ws: 8.18.1 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + '@libsql/client-wasm@0.14.0': dependencies: '@libsql/core': 0.14.0 @@ -11252,7 +11376,7 @@ snapshots: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - '@mantine/notifications@7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@mantine/notifications@7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@mantine/core': 7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@mantine/hooks': 7.17.1(react@19.0.0) @@ -11261,7 +11385,7 @@ snapshots: react-dom: 19.0.0(react@19.0.0) react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@mantine/spotlight@7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@mantine/spotlight@7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@mantine/core': 7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@mantine/hooks': 7.17.1(react@19.0.0) @@ -12806,6 +12930,8 @@ snapshots: '@types/through': 0.0.33 rxjs: 6.6.7 + '@types/js-yaml@4.0.9': {} + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} @@ -12827,6 +12953,11 @@ snapshots: '@types/node-cron@3.0.11': {} + '@types/node-fetch@2.6.12': + dependencies: + '@types/node': 22.13.10 + form-data: 4.0.1 + '@types/node@18.19.50': dependencies: undici-types: 5.26.5 @@ -12881,10 +13012,19 @@ snapshots: dependencies: '@types/node': 18.19.50 + '@types/stream-buffers@3.0.7': + dependencies: + '@types/node': 22.13.10 + '@types/swagger-ui-react@5.18.0': dependencies: '@types/react': 19.0.10 + '@types/tar@6.1.13': + dependencies: + '@types/node': 22.13.10 + minipass: 4.2.8 + '@types/through@0.0.33': dependencies: '@types/node': 22.13.10 @@ -13708,6 +13848,8 @@ snapshots: chownr@2.0.0: {} + chownr@3.0.0: {} + chroma-js@3.1.2: {} chrome-trace-event@1.0.4: {} @@ -15777,6 +15919,10 @@ snapshots: transitivePeerDependencies: - encoding + isomorphic-ws@5.0.0(ws@8.18.1): + dependencies: + ws: 8.18.1 + issue-parser@7.0.1: dependencies: lodash.capitalize: 4.2.1 @@ -15885,6 +16031,8 @@ snapshots: - supports-color - utf-8-validate + jsep@1.4.0: {} + jsesc@3.0.2: {} json-buffer@3.0.1: {} @@ -15909,6 +16057,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonpath-plus@10.3.0: + dependencies: + '@jsep-plugin/assignment': 1.3.0(jsep@1.4.0) + '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) + jsep: 1.4.0 + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -16194,6 +16348,8 @@ snapshots: dependencies: yallist: 4.0.0 + minipass@4.2.8: {} + minipass@5.0.0: {} minipass@7.1.2: {} @@ -16203,6 +16359,11 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + mitt@3.0.1: {} mkdirp-classic@0.5.3: {} @@ -16213,6 +16374,8 @@ snapshots: mkdirp@1.0.4: {} + mkdirp@3.0.1: {} + moment-timezone@0.5.47: dependencies: moment: 2.30.1 @@ -16561,6 +16724,11 @@ snapshots: dependencies: yaml: 2.5.1 + openid-client@6.3.3: + dependencies: + jose: 6.0.8 + oauth4webapi: 3.3.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -17413,6 +17581,10 @@ snapshots: dependencies: glob: 7.2.3 + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + rollup@4.21.3: dependencies: '@types/estree': 1.0.5 @@ -17873,6 +18045,8 @@ snapshots: std-env@3.8.0: {} + stream-buffers@3.0.3: {} + stream-combiner2@1.1.1: dependencies: duplexer2: 0.1.4 @@ -18161,6 +18335,15 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + temp-dir@3.0.0: {} tempy@3.1.0: @@ -18276,6 +18459,10 @@ snapshots: dependencies: tldts-core: 6.1.69 + tmp-promise@3.0.3: + dependencies: + tmp: 0.2.3 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -19079,6 +19266,8 @@ snapshots: yallist@4.0.0: {} + yallist@5.0.0: {} + yaml@2.5.1: {} yargs-parser@20.2.9: {} From d6cfd230683b47f95b852a3dabf09657d509a099 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 02:54:31 +0000 Subject: [PATCH 25/60] chore(deps): update pnpm to v10.6.2 (#2557) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f7dadffb..f35f7d1fe 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.8" }, - "packageManager": "pnpm@10.6.1", + "packageManager": "pnpm@10.6.2", "engines": { "node": ">=22.14.0" }, From 9c582d906bb2702de5db282594293e51e94ca98d Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 11:13:59 +0000 Subject: [PATCH 26/60] fix(deps): update dependency swagger-ui-react to ^5.20.1 (#2558) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- apps/nextjs/package.json | 2 +- pnpm-lock.yaml | 198 ++++++++++----------------------------- 2 files changed, 49 insertions(+), 151 deletions(-) diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index 7155a3030..8b630b687 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -83,7 +83,7 @@ "react-simple-code-editor": "^0.14.1", "sass": "^1.85.1", "superjson": "2.2.2", - "swagger-ui-react": "^5.20.0", + "swagger-ui-react": "^5.20.1", "use-deep-compare-effect": "^1.8.1", "zod": "^3.24.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b7333a3eb..160224b49 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -216,16 +216,16 @@ importers: version: 5.67.2(@tanstack/react-query@5.67.2(react@19.0.0))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0) '@trpc/client': specifier: next - version: 11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2) + version: 11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2) '@trpc/next': specifier: next - version: 11.0.0-rc.824(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2))(@trpc/react-query@11.0.0-rc.824(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) + version: 11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/react-query@11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) '@trpc/react-query': specifier: next - version: 11.0.0-rc.824(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) + version: 11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) '@trpc/server': specifier: next - version: 11.0.0-rc.824(typescript@5.8.2) + version: 11.0.0-rc.828(typescript@5.8.2) '@xterm/addon-canvas': specifier: ^0.7.0 version: 0.7.0(@xterm/xterm@5.5.0) @@ -287,8 +287,8 @@ importers: specifier: 2.2.2 version: 2.2.2 swagger-ui-react: - specifier: ^5.20.0 - version: 5.20.0(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^5.20.1 + version: 5.20.1(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) use-deep-compare-effect: specifier: ^1.8.1 version: 1.8.1(react@19.0.0) @@ -583,13 +583,13 @@ importers: version: 1.0.0 '@trpc/client': specifier: next - version: 11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2) + version: 11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2) '@trpc/react-query': specifier: next - version: 11.0.0-rc.824(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) + version: 11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) '@trpc/server': specifier: next - version: 11.0.0-rc.824(typescript@5.8.2) + version: 11.0.0-rc.828(typescript@5.8.2) lodash.clonedeep: specifier: ^4.5.0 version: 4.5.0 @@ -610,7 +610,7 @@ importers: version: 2.2.2 trpc-to-openapi: specifier: ^2.1.3 - version: 2.1.3(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(zod-openapi@2.19.0(zod@3.24.2))(zod@3.24.2) + version: 2.1.3(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(zod-openapi@2.19.0(zod@3.24.2))(zod@3.24.2) zod: specifier: ^3.24.2 version: 3.24.2 @@ -4127,9 +4127,6 @@ packages: '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - '@swagger-api/apidom-ast@1.0.0-beta.11': - resolution: {integrity: sha512-QvKVHSYdYNISzq5ONqdfl0QfbVdNosVsgDMrXrB6AP0HoF0rR84Hvj16aPKfYYKU4cfB+orz4u4dWi0xdiDqtA==} - '@swagger-api/apidom-ast@1.0.0-beta.12': resolution: {integrity: sha512-KdJ+8PyYvfnHgpqrC0WWDRJLVx6+YkmYgAGpsdOa8S/p6btJdCUozeqpcXawmGqwAX/9jCXbmKdia3v3fUrP0w==} @@ -4148,42 +4145,24 @@ packages: '@swagger-api/apidom-ns-asyncapi-2@1.0.0-beta.11': resolution: {integrity: sha512-xFu/xZlmhbCo2WAyfTlaiRquH7AEnArAwjNynd3CWnerNJ0NMuO1OBsUh8JI3WJQPRKdtYyH0zP5bnVk9aHSYA==} - '@swagger-api/apidom-ns-json-schema-2019-09@1.0.0-beta.11': - resolution: {integrity: sha512-aNU+5qylnl9//pywt/aJHece6sJaSHE5PoCoBQYQ+La6Dt7xhMU5zRQv2inCpxcPP4H3F2yapXqsB+VU/If3yA==} - '@swagger-api/apidom-ns-json-schema-2019-09@1.0.0-beta.12': resolution: {integrity: sha512-mrcWwAfCcUDiPrGymowZqnrOpOk7hUNDkW9WjsMe3bFiTrCm4EsQYvGtyWAtB/0yo7hNBMGXYEtDWfGBsw8AyA==} - '@swagger-api/apidom-ns-json-schema-2020-12@1.0.0-beta.11': - resolution: {integrity: sha512-3WzQ9ykmTYR14cvjgZCpMODvaTcSLcScayAjWPXfH6cc8qtAf786654C52qtpMaQNbpWrdMz93LUvBFrBrGJhA==} - '@swagger-api/apidom-ns-json-schema-2020-12@1.0.0-beta.12': resolution: {integrity: sha512-SW0Jtty3o12OwpTAVJEewurvTSIhxJ72TZlMSk5L36jvekzqKfLL7aBYRCEE9QkV3rxTjxOf0WK/tYLRMKUbzw==} - '@swagger-api/apidom-ns-json-schema-draft-4@1.0.0-beta.11': - resolution: {integrity: sha512-5iAzcjFfai5mVKDeytG2M9R8kG9xSMhfzgNFvFX5X7NwPrHZeNJwS02BXwHPksBiE6QdfS6tDeF9iMToDCR+Yw==} - '@swagger-api/apidom-ns-json-schema-draft-4@1.0.0-beta.12': resolution: {integrity: sha512-Z3PnEEdkGnr6zomFAgmkkDGrwlj3bbbEJBfXsshxRuXf3i5RymiURFy42CfKa5Tmx3rw8rSw393p0TkHqS0NIg==} - '@swagger-api/apidom-ns-json-schema-draft-6@1.0.0-beta.11': - resolution: {integrity: sha512-Cmaw1JWP1UWrqFKgbRp+BTCsB0yuhLVBOL1Glf439+jk95cz7v14B7+P+/wN4tqn4bcmzXyhD6KJ9DYzHiHd2A==} - '@swagger-api/apidom-ns-json-schema-draft-6@1.0.0-beta.12': resolution: {integrity: sha512-QvubeYZvRd19Q8VVP4xGGYTuSVgLQqEp/epe8LXcrFJvgF6A9CTUxkfKVxL4+Q5a9DFaKTZKNYwkRaPzisvnWQ==} - '@swagger-api/apidom-ns-json-schema-draft-7@1.0.0-beta.11': - resolution: {integrity: sha512-I0Ls6It89Dvkm5lOMGF79Sbk3QcPP7Ijo7Ay5QEiLTD+u7jcfpJIp/scOCzdQLCpTWxzzLe4FY88NuauzTfuJw==} - '@swagger-api/apidom-ns-json-schema-draft-7@1.0.0-beta.12': resolution: {integrity: sha512-UIU/vY5xBhYeBEykmXMvQRaIXqWWNWc/RPG5L8LrfILoZhzZbjqcdRMf5w4wQWqteQxXxkpDdkcHVBsJxcQtJg==} '@swagger-api/apidom-ns-openapi-2@1.0.0-beta.11': resolution: {integrity: sha512-aVi48Dv3pk/QzxPXH/jmOReiGU01gkgkEFUbBiNGxuHD/bzS4SbLLdkw6ai8f8eQPpXI6xKP5F6LhFHWTE0IJg==} - '@swagger-api/apidom-ns-openapi-3-0@1.0.0-beta.11': - resolution: {integrity: sha512-amY1KI9Vx0Vye1OQ3K1mPJmL4ONWSZwWcH6COWer8aExNq66W7oWTXOfL3q6NAgRC6NGobbrXgFGXd196N7fNw==} - '@swagger-api/apidom-ns-openapi-3-0@1.0.0-beta.12': resolution: {integrity: sha512-6TWUagR1/Y9HB8t75/vrkHHDV5c5K0S72Wywx7PoDyNgQ1Jxy3p6iwuSHfTwJYH+/hAxg3f91i6HXXyrHB5RAg==} @@ -4541,20 +4520,20 @@ packages: tree-sitter: optional: true - '@trpc/client@11.0.0-rc.824': - resolution: {integrity: sha512-3JMsgiMrCEeblrzu7ScTjipYaeEmegbnM5ZPmqqkPIbXcnth/TwH5tRr+nQbLSU/NGkWJWsjgEq7bM0BV17sJw==} + '@trpc/client@11.0.0-rc.828': + resolution: {integrity: sha512-pV2bELnPqH7S2R1wBH6OB7lOi61ELt8CEcvHuxVM2YhL4hP408tzKT0YvNBo4GVqc8So/1ncpXJyRJQG0o6rsQ==} peerDependencies: - '@trpc/server': 11.0.0-rc.824+b21849468 + '@trpc/server': 11.0.0-rc.828+322552736 typescript: '>=5.7.2' - '@trpc/next@11.0.0-rc.824': - resolution: {integrity: sha512-DD7WbLgu5u1mocqF07U+9xG/3WMO7tdA3RLjDwcT5MwgM2lYmcDTc7z5zJw1UAtb3zNfY+4N7CgNvx+r/KKrBA==} + '@trpc/next@11.0.0-rc.828': + resolution: {integrity: sha512-Pyzyh0YM2DgYJHGI09oAinLF8ViRtUhAdcWVMr55sxGn1LPce0QD70K1WjvPRP2jvlRMaNRvD4nrqQ+c1hnBbA==} peerDependencies: '@tanstack/react-query': ^5.59.15 - '@trpc/client': 11.0.0-rc.824+b21849468 - '@trpc/react-query': 11.0.0-rc.824+b21849468 - '@trpc/server': 11.0.0-rc.824+b21849468 - next: 15.2.0 + '@trpc/client': 11.0.0-rc.828+322552736 + '@trpc/react-query': 11.0.0-rc.828+322552736 + '@trpc/server': 11.0.0-rc.828+322552736 + next: 15.2.1 react: '>=16.8.0' react-dom: '>=16.8.0' typescript: '>=5.7.2' @@ -4564,18 +4543,18 @@ packages: '@trpc/react-query': optional: true - '@trpc/react-query@11.0.0-rc.824': - resolution: {integrity: sha512-M1Ui946RBKDjQN/w9JRANJUXStoUDIRd+ti5IhggNdyzY21kx7AJkz5vujZ2GEUxUIQBG8QbUxXN7mj+5BL/mw==} + '@trpc/react-query@11.0.0-rc.828': + resolution: {integrity: sha512-oir4OikvCEqbheswHZhKrXSz1hKvFcDFlc/NZ9zShMlosJtO585az0XRrGuwFvjVShP5YCRvzFb4shiJjw5PXA==} peerDependencies: '@tanstack/react-query': ^5.67.1 - '@trpc/client': 11.0.0-rc.824+b21849468 - '@trpc/server': 11.0.0-rc.824+b21849468 + '@trpc/client': 11.0.0-rc.828+322552736 + '@trpc/server': 11.0.0-rc.828+322552736 react: '>=18.2.0' react-dom: '>=18.2.0' typescript: '>=5.7.2' - '@trpc/server@11.0.0-rc.824': - resolution: {integrity: sha512-6u6CZ/x+oe2bZDhOo5h0wonbMU3svPe8hs6Dr2ymrU+23NAHE6tHtROAX+dKrMzup9KJcqyAabuFRYHy2H0tjw==} + '@trpc/server@11.0.0-rc.828': + resolution: {integrity: sha512-+dvcIcE5QPy52cz4rqwfUqk+WQDYAH3Xri+u2t0NdzIoo78fnL14if8oSZXAPU1bCmWGyR1k/0m5rSQ7AZaKlQ==} peerDependencies: typescript: '>=5.7.2' @@ -9364,8 +9343,8 @@ packages: swagger-client@3.34.1: resolution: {integrity: sha512-aqk315C959936kijVpR28Q07eugElW9vp77a57hdFlQDF8Kuln7SeB1MwXnTCOQEM6/pIWYN00QlvIEwHqQkqw==} - swagger-ui-react@5.20.0: - resolution: {integrity: sha512-txC3j+aPi6KOV7OxJvCdmeosg1oPmPdtOH2Ny3kogRCSwj9y7FF0IHv5KWhjmOaUvQa+9+XiYiw+NGQvi88pSg==} + swagger-ui-react@5.20.1: + resolution: {integrity: sha512-8LKED6zWbPpJMHzC3PYwce6wUO0D1r5ALdJVHNEXZhd4eqa0mUyKEWa3Y+KSBWNLDI2xuNvVU2lBhBbWaiH3Xg==} peerDependencies: react: '>=16.8.0 <19' react-dom: '>=16.8.0 <19' @@ -12015,16 +11994,6 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} - '@swagger-api/apidom-ast@1.0.0-beta.11': - dependencies: - '@babel/runtime-corejs3': 7.26.9 - '@swagger-api/apidom-error': 1.0.0-beta.12 - '@types/ramda': 0.30.2 - ramda: 0.30.1 - ramda-adjunct: 5.1.0(ramda@0.30.1) - unraw: 3.0.0 - optional: true - '@swagger-api/apidom-ast@1.0.0-beta.12': dependencies: '@babel/runtime-corejs3': 7.26.9 @@ -12075,19 +12044,7 @@ snapshots: dependencies: '@babel/runtime-corejs3': 7.26.9 '@swagger-api/apidom-core': 1.0.0-beta.12 - '@swagger-api/apidom-ns-json-schema-draft-7': 1.0.0-beta.11 - '@types/ramda': 0.30.2 - ramda: 0.30.1 - ramda-adjunct: 5.1.0(ramda@0.30.1) - ts-mixer: 6.0.4 - optional: true - - '@swagger-api/apidom-ns-json-schema-2019-09@1.0.0-beta.11': - dependencies: - '@babel/runtime-corejs3': 7.26.9 - '@swagger-api/apidom-core': 1.0.0-beta.12 - '@swagger-api/apidom-error': 1.0.0-beta.12 - '@swagger-api/apidom-ns-json-schema-draft-7': 1.0.0-beta.11 + '@swagger-api/apidom-ns-json-schema-draft-7': 1.0.0-beta.12 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) @@ -12105,18 +12062,6 @@ snapshots: ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-json-schema-2020-12@1.0.0-beta.11': - dependencies: - '@babel/runtime-corejs3': 7.26.9 - '@swagger-api/apidom-core': 1.0.0-beta.12 - '@swagger-api/apidom-error': 1.0.0-beta.12 - '@swagger-api/apidom-ns-json-schema-2019-09': 1.0.0-beta.11 - '@types/ramda': 0.30.2 - ramda: 0.30.1 - ramda-adjunct: 5.1.0(ramda@0.30.1) - ts-mixer: 6.0.4 - optional: true - '@swagger-api/apidom-ns-json-schema-2020-12@1.0.0-beta.12': dependencies: '@babel/runtime-corejs3': 7.26.9 @@ -12128,17 +12073,6 @@ snapshots: ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-json-schema-draft-4@1.0.0-beta.11': - dependencies: - '@babel/runtime-corejs3': 7.26.9 - '@swagger-api/apidom-ast': 1.0.0-beta.11 - '@swagger-api/apidom-core': 1.0.0-beta.12 - '@types/ramda': 0.30.2 - ramda: 0.30.1 - ramda-adjunct: 5.1.0(ramda@0.30.1) - ts-mixer: 6.0.4 - optional: true - '@swagger-api/apidom-ns-json-schema-draft-4@1.0.0-beta.12': dependencies: '@babel/runtime-corejs3': 7.26.9 @@ -12149,18 +12083,6 @@ snapshots: ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-json-schema-draft-6@1.0.0-beta.11': - dependencies: - '@babel/runtime-corejs3': 7.26.9 - '@swagger-api/apidom-core': 1.0.0-beta.12 - '@swagger-api/apidom-error': 1.0.0-beta.12 - '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-beta.11 - '@types/ramda': 0.30.2 - ramda: 0.30.1 - ramda-adjunct: 5.1.0(ramda@0.30.1) - ts-mixer: 6.0.4 - optional: true - '@swagger-api/apidom-ns-json-schema-draft-6@1.0.0-beta.12': dependencies: '@babel/runtime-corejs3': 7.26.9 @@ -12172,18 +12094,6 @@ snapshots: ramda-adjunct: 5.1.0(ramda@0.30.1) ts-mixer: 6.0.4 - '@swagger-api/apidom-ns-json-schema-draft-7@1.0.0-beta.11': - dependencies: - '@babel/runtime-corejs3': 7.26.9 - '@swagger-api/apidom-core': 1.0.0-beta.12 - '@swagger-api/apidom-error': 1.0.0-beta.12 - '@swagger-api/apidom-ns-json-schema-draft-6': 1.0.0-beta.11 - '@types/ramda': 0.30.2 - ramda: 0.30.1 - ramda-adjunct: 5.1.0(ramda@0.30.1) - ts-mixer: 6.0.4 - optional: true - '@swagger-api/apidom-ns-json-schema-draft-7@1.0.0-beta.12': dependencies: '@babel/runtime-corejs3': 7.26.9 @@ -12200,19 +12110,7 @@ snapshots: '@babel/runtime-corejs3': 7.26.9 '@swagger-api/apidom-core': 1.0.0-beta.12 '@swagger-api/apidom-error': 1.0.0-beta.12 - '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-beta.11 - '@types/ramda': 0.30.2 - ramda: 0.30.1 - ramda-adjunct: 5.1.0(ramda@0.30.1) - ts-mixer: 6.0.4 - optional: true - - '@swagger-api/apidom-ns-openapi-3-0@1.0.0-beta.11': - dependencies: - '@babel/runtime-corejs3': 7.26.9 - '@swagger-api/apidom-core': 1.0.0-beta.12 - '@swagger-api/apidom-error': 1.0.0-beta.12 - '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-beta.11 + '@swagger-api/apidom-ns-json-schema-draft-4': 1.0.0-beta.12 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) @@ -12247,7 +12145,7 @@ snapshots: dependencies: '@babel/runtime-corejs3': 7.26.9 '@swagger-api/apidom-core': 1.0.0-beta.12 - '@swagger-api/apidom-ns-json-schema-2020-12': 1.0.0-beta.11 + '@swagger-api/apidom-ns-json-schema-2020-12': 1.0.0-beta.12 '@types/ramda': 0.30.2 ramda: 0.30.1 ramda-adjunct: 5.1.0(ramda@0.30.1) @@ -12301,7 +12199,7 @@ snapshots: '@swagger-api/apidom-parser-adapter-json@1.0.0-beta.11': dependencies: '@babel/runtime-corejs3': 7.26.9 - '@swagger-api/apidom-ast': 1.0.0-beta.11 + '@swagger-api/apidom-ast': 1.0.0-beta.12 '@swagger-api/apidom-core': 1.0.0-beta.12 '@swagger-api/apidom-error': 1.0.0-beta.12 '@types/ramda': 0.30.2 @@ -12327,7 +12225,7 @@ snapshots: dependencies: '@babel/runtime-corejs3': 7.26.9 '@swagger-api/apidom-core': 1.0.0-beta.12 - '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-beta.11 + '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-beta.12 '@swagger-api/apidom-parser-adapter-json': 1.0.0-beta.11 '@types/ramda': 0.30.2 ramda: 0.30.1 @@ -12360,7 +12258,7 @@ snapshots: dependencies: '@babel/runtime-corejs3': 7.26.9 '@swagger-api/apidom-core': 1.0.0-beta.12 - '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-beta.11 + '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-beta.12 '@swagger-api/apidom-parser-adapter-yaml-1-2': 1.0.0-beta.11 '@types/ramda': 0.30.2 ramda: 0.30.1 @@ -12403,7 +12301,7 @@ snapshots: '@swagger-api/apidom-parser-adapter-yaml-1-2@1.0.0-beta.11': dependencies: '@babel/runtime-corejs3': 7.26.9 - '@swagger-api/apidom-ast': 1.0.0-beta.11 + '@swagger-api/apidom-ast': 1.0.0-beta.12 '@swagger-api/apidom-core': 1.0.0-beta.12 '@swagger-api/apidom-error': 1.0.0-beta.12 '@tree-sitter-grammars/tree-sitter-yaml': 0.7.0(tree-sitter@0.22.1) @@ -12429,7 +12327,7 @@ snapshots: '@swagger-api/apidom-json-pointer': 1.0.0-beta.12 '@swagger-api/apidom-ns-asyncapi-2': 1.0.0-beta.11 '@swagger-api/apidom-ns-openapi-2': 1.0.0-beta.11 - '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-beta.11 + '@swagger-api/apidom-ns-openapi-3-0': 1.0.0-beta.12 '@swagger-api/apidom-ns-openapi-3-1': 1.0.0-beta.12 '@swagger-api/apidom-ns-workflows-1': 1.0.0-beta.11 '@swagger-api/apidom-parser-adapter-api-design-systems-json': 1.0.0-beta.11 @@ -12742,33 +12640,33 @@ snapshots: tree-sitter: 0.22.1 optional: true - '@trpc/client@11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2)': + '@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2)': dependencies: - '@trpc/server': 11.0.0-rc.824(typescript@5.8.2) + '@trpc/server': 11.0.0-rc.828(typescript@5.8.2) typescript: 5.8.2 - '@trpc/next@11.0.0-rc.824(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2))(@trpc/react-query@11.0.0-rc.824(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2)': + '@trpc/next@11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/react-query@11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2)': dependencies: - '@trpc/client': 11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2) - '@trpc/server': 11.0.0-rc.824(typescript@5.8.2) + '@trpc/client': 11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2) + '@trpc/server': 11.0.0-rc.828(typescript@5.8.2) next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 react-dom: 19.0.0(react@19.0.0) typescript: 5.8.2 optionalDependencies: '@tanstack/react-query': 5.67.2(react@19.0.0) - '@trpc/react-query': 11.0.0-rc.824(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) + '@trpc/react-query': 11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) - '@trpc/react-query@11.0.0-rc.824(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2)': + '@trpc/react-query@11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2)': dependencies: '@tanstack/react-query': 5.67.2(react@19.0.0) - '@trpc/client': 11.0.0-rc.824(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(typescript@5.8.2) - '@trpc/server': 11.0.0-rc.824(typescript@5.8.2) + '@trpc/client': 11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2) + '@trpc/server': 11.0.0-rc.828(typescript@5.8.2) react: 19.0.0 react-dom: 19.0.0(react@19.0.0) typescript: 5.8.2 - '@trpc/server@11.0.0-rc.824(typescript@5.8.2)': + '@trpc/server@11.0.0-rc.828(typescript@5.8.2)': dependencies: typescript: 5.8.2 @@ -18233,7 +18131,7 @@ snapshots: transitivePeerDependencies: - debug - swagger-ui-react@5.20.0(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + swagger-ui-react@5.20.1(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: '@babel/runtime-corejs3': 7.26.9 '@scarf/scarf': 1.4.0 @@ -18511,9 +18409,9 @@ snapshots: triple-beam@1.4.1: {} - trpc-to-openapi@2.1.3(@trpc/server@11.0.0-rc.824(typescript@5.8.2))(zod-openapi@2.19.0(zod@3.24.2))(zod@3.24.2): + trpc-to-openapi@2.1.3(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(zod-openapi@2.19.0(zod@3.24.2))(zod@3.24.2): dependencies: - '@trpc/server': 11.0.0-rc.824(typescript@5.8.2) + '@trpc/server': 11.0.0-rc.828(typescript@5.8.2) co-body: 6.2.0 h3: 1.13.0 openapi3-ts: 4.4.0 From 8cb8eaf9cc2aaa842869c6be75e9208b9a19fd77 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 18:19:33 +0000 Subject: [PATCH 27/60] fix(deps): update dependency prismjs to ^1.30.0 (#2562) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- apps/nextjs/package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index 8b630b687..7ce45f303 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -76,7 +76,7 @@ "mantine-react-table": "2.0.0-beta.9", "next": "15.1.7", "postcss-preset-mantine": "^1.17.0", - "prismjs": "^1.29.0", + "prismjs": "^1.30.0", "react": "19.0.0", "react-dom": "19.0.0", "react-error-boundary": "^5.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 160224b49..ab0270c93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -266,8 +266,8 @@ importers: specifier: ^1.17.0 version: 1.17.0(postcss@8.4.47) prismjs: - specifier: ^1.29.0 - version: 1.29.0 + specifier: ^1.30.0 + version: 1.30.0 react: specifier: 19.0.0 version: 19.0.0 @@ -8419,8 +8419,8 @@ packages: resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} engines: {node: '>=6'} - prismjs@1.29.0: - resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} engines: {node: '>=6'} process-nextick-args@2.0.1: @@ -16956,7 +16956,7 @@ snapshots: prismjs@1.27.0: {} - prismjs@1.29.0: {} + prismjs@1.30.0: {} process-nextick-args@2.0.1: {} @@ -17291,7 +17291,7 @@ snapshots: highlight.js: 10.7.3 highlightjs-vue: 1.0.0 lowlight: 1.20.0 - prismjs: 1.29.0 + prismjs: 1.30.0 react: 19.0.0 refractor: 3.6.0 From 55ad0b0a6533df44e7d1f6eecf33135654cea104 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 18:42:17 +0000 Subject: [PATCH 28/60] fix(deps): update dependency typescript-eslint to ^8.26.1 (#2561) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 114 ++++++++++++++++++------------------ tooling/eslint/package.json | 2 +- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab0270c93..92353edb2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2183,7 +2183,7 @@ importers: version: 2.4.4(eslint@9.22.0)(turbo@2.4.4) eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0) + version: 2.31.0(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0) eslint-plugin-jsx-a11y: specifier: ^6.10.2 version: 6.10.2(eslint@9.22.0) @@ -2194,8 +2194,8 @@ importers: specifier: ^5.2.0 version: 5.2.0(eslint@9.22.0) typescript-eslint: - specifier: ^8.26.0 - version: 8.26.0(eslint@9.22.0)(typescript@5.8.2) + specifier: ^8.26.1 + version: 8.26.1(eslint@9.22.0)(typescript@5.8.2) devDependencies: '@homarr/prettier-config': specifier: workspace:^0.1.0 @@ -4781,51 +4781,51 @@ packages: '@types/xml2js@0.4.14': resolution: {integrity: sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==} - '@typescript-eslint/eslint-plugin@8.26.0': - resolution: {integrity: sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q==} + '@typescript-eslint/eslint-plugin@8.26.1': + resolution: {integrity: sha512-2X3mwqsj9Bd3Ciz508ZUtoQQYpOhU/kWoUqIf49H8Z0+Vbh6UF/y0OEYp0Q0axOGzaBGs7QxRwq0knSQ8khQNA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.26.0': - resolution: {integrity: sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA==} + '@typescript-eslint/parser@8.26.1': + resolution: {integrity: sha512-w6HZUV4NWxqd8BdeFf81t07d7/YV9s7TCWrQQbG5uhuvGUAW+fq1usZ1Hmz9UPNLniFnD8GLSsDpjP0hm1S4lQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/scope-manager@8.26.0': - resolution: {integrity: sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA==} + '@typescript-eslint/scope-manager@8.26.1': + resolution: {integrity: sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.26.0': - resolution: {integrity: sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q==} + '@typescript-eslint/type-utils@8.26.1': + resolution: {integrity: sha512-Kcj/TagJLwoY/5w9JGEFV0dclQdyqw9+VMndxOJKtoFSjfZhLXhYjzsQEeyza03rwHx2vFEGvrJWJBXKleRvZg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/types@8.26.0': - resolution: {integrity: sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA==} + '@typescript-eslint/types@8.26.1': + resolution: {integrity: sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.26.0': - resolution: {integrity: sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ==} + '@typescript-eslint/typescript-estree@8.26.1': + resolution: {integrity: sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.26.0': - resolution: {integrity: sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig==} + '@typescript-eslint/utils@8.26.1': + resolution: {integrity: sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/visitor-keys@8.26.0': - resolution: {integrity: sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg==} + '@typescript-eslint/visitor-keys@8.26.1': + resolution: {integrity: sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@umami/node@0.4.0': @@ -9735,8 +9735,8 @@ packages: types-ramda@0.30.1: resolution: {integrity: sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==} - typescript-eslint@8.26.0: - resolution: {integrity: sha512-PtVz9nAnuNJuAVeUFvwztjuUgSnJInODAUx47VDwWPXzd5vismPOtPtt83tzNXyOjVQbPRp786D6WFW/M2koIA==} + typescript-eslint@8.26.1: + resolution: {integrity: sha512-t/oIs9mYyrwZGRpDv3g+3K6nZ5uhKEMt2oNmAPwaY4/ye0+EH4nXIPYNtkYFS6QHm+1DFg34DbglYBz5P9Xysg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -12948,14 +12948,14 @@ snapshots: dependencies: '@types/node': 22.13.10 - '@typescript-eslint/eslint-plugin@8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2)': + '@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.26.0(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/scope-manager': 8.26.0 - '@typescript-eslint/type-utils': 8.26.0(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.0(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.26.0 + '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/scope-manager': 8.26.1 + '@typescript-eslint/type-utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 8.26.1 eslint: 9.22.0 graphemer: 1.4.0 ignore: 5.3.2 @@ -12965,27 +12965,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2)': + '@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2)': dependencies: - '@typescript-eslint/scope-manager': 8.26.0 - '@typescript-eslint/types': 8.26.0 - '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.26.0 + '@typescript-eslint/scope-manager': 8.26.1 + '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 8.26.1 debug: 4.4.0 eslint: 9.22.0 typescript: 5.8.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.26.0': + '@typescript-eslint/scope-manager@8.26.1': dependencies: - '@typescript-eslint/types': 8.26.0 - '@typescript-eslint/visitor-keys': 8.26.0 + '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/visitor-keys': 8.26.1 - '@typescript-eslint/type-utils@8.26.0(eslint@9.22.0)(typescript@5.8.2)': + '@typescript-eslint/type-utils@8.26.1(eslint@9.22.0)(typescript@5.8.2)': dependencies: - '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.0(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) + '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) debug: 4.4.0 eslint: 9.22.0 ts-api-utils: 2.0.1(typescript@5.8.2) @@ -12993,12 +12993,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.26.0': {} + '@typescript-eslint/types@8.26.1': {} - '@typescript-eslint/typescript-estree@8.26.0(typescript@5.8.2)': + '@typescript-eslint/typescript-estree@8.26.1(typescript@5.8.2)': dependencies: - '@typescript-eslint/types': 8.26.0 - '@typescript-eslint/visitor-keys': 8.26.0 + '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/visitor-keys': 8.26.1 debug: 4.4.0 fast-glob: 3.3.2 is-glob: 4.0.3 @@ -13009,20 +13009,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.26.0(eslint@9.22.0)(typescript@5.8.2)': + '@typescript-eslint/utils@8.26.1(eslint@9.22.0)(typescript@5.8.2)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.22.0) - '@typescript-eslint/scope-manager': 8.26.0 - '@typescript-eslint/types': 8.26.0 - '@typescript-eslint/typescript-estree': 8.26.0(typescript@5.8.2) + '@typescript-eslint/scope-manager': 8.26.1 + '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) eslint: 9.22.0 typescript: 5.8.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.26.0': + '@typescript-eslint/visitor-keys@8.26.1': dependencies: - '@typescript-eslint/types': 8.26.0 + '@typescript-eslint/types': 8.26.1 eslint-visitor-keys: 4.2.0 '@umami/node@0.4.0': {} @@ -14701,17 +14701,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.22.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.22.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.26.0(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) eslint: 9.22.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -14722,7 +14722,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.22.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.22.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.22.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -14734,7 +14734,7 @@ snapshots: string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.26.0(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -18609,11 +18609,11 @@ snapshots: dependencies: ts-toolbelt: 9.6.0 - typescript-eslint@8.26.0(eslint@9.22.0)(typescript@5.8.2): + typescript-eslint@8.26.1(eslint@9.22.0)(typescript@5.8.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.26.0(@typescript-eslint/parser@8.26.0(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/parser': 8.26.0(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.0(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/eslint-plugin': 8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) eslint: 9.22.0 typescript: 5.8.2 transitivePeerDependencies: diff --git a/tooling/eslint/package.json b/tooling/eslint/package.json index 68863a94c..1c63029f1 100644 --- a/tooling/eslint/package.json +++ b/tooling/eslint/package.json @@ -24,7 +24,7 @@ "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-react": "^7.37.4", "eslint-plugin-react-hooks": "^5.2.0", - "typescript-eslint": "^8.26.0" + "typescript-eslint": "^8.26.1" }, "devDependencies": { "@homarr/prettier-config": "workspace:^0.1.0", From ff6ca86a78ccec4a2dee3d08c1420948c4de28ee Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 18:56:34 +0000 Subject: [PATCH 29/60] fix(deps): update dependency jotai to ^2.12.2 (#2560) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- apps/nextjs/package.json | 2 +- packages/spotlight/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index 7ce45f303..ea1b91a01 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -72,7 +72,7 @@ "dotenv": "^16.4.7", "flag-icons": "^7.3.2", "glob": "^11.0.1", - "jotai": "^2.12.1", + "jotai": "^2.12.2", "mantine-react-table": "2.0.0-beta.9", "next": "15.1.7", "postcss-preset-mantine": "^1.17.0", diff --git a/packages/spotlight/package.json b/packages/spotlight/package.json index 80ea1ca6c..dc8785628 100644 --- a/packages/spotlight/package.json +++ b/packages/spotlight/package.json @@ -37,7 +37,7 @@ "@mantine/hooks": "^7.17.1", "@mantine/spotlight": "^7.17.1", "@tabler/icons-react": "^3.31.0", - "jotai": "^2.12.1", + "jotai": "^2.12.2", "next": "15.1.7", "react": "19.0.0", "react-dom": "19.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 92353edb2..97d86d993 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -254,8 +254,8 @@ importers: specifier: ^11.0.1 version: 11.0.1 jotai: - specifier: ^2.12.1 - version: 2.12.1(@types/react@19.0.10)(react@19.0.0) + specifier: ^2.12.2 + version: 2.12.2(@types/react@19.0.10)(react@19.0.0) mantine-react-table: specifier: 2.0.0-beta.9 version: 2.0.0-beta.9(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/dates@7.17.1(@mantine/core@7.17.1(@mantine/hooks@7.17.1(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mantine/hooks@7.17.1(react@19.0.0))(@tabler/icons-react@3.31.0(react@19.0.0))(clsx@2.1.1)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -1841,8 +1841,8 @@ importers: specifier: ^3.31.0 version: 3.31.0(react@19.0.0) jotai: - specifier: ^2.12.1 - version: 2.12.1(@types/react@19.0.10)(react@19.0.0) + specifier: ^2.12.2 + version: 2.12.2(@types/react@19.0.10)(react@19.0.0) next: specifier: 15.1.7 version: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) @@ -7270,8 +7270,8 @@ packages: jose@6.0.8: resolution: {integrity: sha512-EyUPtOKyTYq+iMOszO42eobQllaIjJnwkZ2U93aJzNyPibCy7CEvT9UQnaCVB51IAd49gbNdCew1c0LcLTCB2g==} - jotai@2.12.1: - resolution: {integrity: sha512-VUW0nMPYIru5g89tdxwr9ftiVdc/nGV9jvHISN8Ucx+m1vI9dBeHemfqYzEuw5XSkmYjD/MEyApN9k6yrATsZQ==} + jotai@2.12.2: + resolution: {integrity: sha512-oN8715y7MkjXlSrpyjlR887TOuc/NLZMs9gvgtfWH/JP47ChwO0lR2ijSwBvPMYyXRAPT+liIAhuBavluKGgtA==} engines: {node: '>=12.20.0'} peerDependencies: '@types/react': '>=17.0.0' @@ -15883,7 +15883,7 @@ snapshots: jose@6.0.8: {} - jotai@2.12.1(@types/react@19.0.10)(react@19.0.0): + jotai@2.12.2(@types/react@19.0.10)(react@19.0.0): optionalDependencies: '@types/react': 19.0.10 react: 19.0.0 From 483ce9c28dda002093fb5413620621bb0389e01f Mon Sep 17 00:00:00 2001 From: "homarr-crowdin[bot]" <190541745+homarr-crowdin[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 19:28:30 +0000 Subject: [PATCH 30/60] chore(lang): updated translations from crowdin Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com> --- packages/translation/src/lang/ca.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/cn.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/cs.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/da.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/de.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/el.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/es.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/et.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/fr.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/he.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/hr.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/hu.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/it.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/ja.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/ko.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/lt.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/lv.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/nl.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/no.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/pl.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/pt.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/ro.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/ru.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/sk.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/sl.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/sv.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/tr.json | 280 +++++++++++++++++++++++++- packages/translation/src/lang/uk.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/vi.json | 272 +++++++++++++++++++++++++ packages/translation/src/lang/zh.json | 272 +++++++++++++++++++++++++ 30 files changed, 8164 insertions(+), 4 deletions(-) diff --git a/packages/translation/src/lang/ca.json b/packages/translation/src/lang/ca.json index 7e1402759..bdab9ccff 100644 --- a/packages/translation/src/lang/ca.json +++ b/packages/translation/src/lang/ca.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/cn.json b/packages/translation/src/lang/cn.json index 1c99f7207..26946162d 100644 --- a/packages/translation/src/lang/cn.json +++ b/packages/translation/src/lang/cn.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "结束于" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "显示媒体服务器上的当前流", "option": {}, "items": { + "currentlyPlaying": "", "user": "用户", "name": "名称", "id": "ID" @@ -2321,6 +2325,7 @@ "label": "工具", "items": { "docker": "Docker", + "kubernetes": "", "logs": "日志", "api": "API", "certificates": "证书", @@ -2867,6 +2872,246 @@ "internalServerError": "获取 Docker 容器失败" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "权限", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "日志" }, diff --git a/packages/translation/src/lang/cs.json b/packages/translation/src/lang/cs.json index d53e222d0..4bca48edb 100644 --- a/packages/translation/src/lang/cs.json +++ b/packages/translation/src/lang/cs.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "Uživatel", "name": "Jméno", "id": "Id" @@ -2321,6 +2325,7 @@ "label": "Nástroje", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "Oprávnění", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/da.json b/packages/translation/src/lang/da.json index 422628c8a..cec47b0d7 100644 --- a/packages/translation/src/lang/da.json +++ b/packages/translation/src/lang/da.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "Slut kl" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "Vis de aktuelle streams på dine medieservere", "option": {}, "items": { + "currentlyPlaying": "", "user": "Bruger", "name": "Navn", "id": "Id" @@ -2321,6 +2325,7 @@ "label": "Værktøjer", "items": { "docker": "Docker", + "kubernetes": "", "logs": "Logfiler", "api": "API", "certificates": "Certifikater", @@ -2867,6 +2872,246 @@ "internalServerError": "Kunne ikke hente Docker-containere" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "Tilladelser", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "Logs" }, diff --git a/packages/translation/src/lang/de.json b/packages/translation/src/lang/de.json index cf1f486af..137834d39 100644 --- a/packages/translation/src/lang/de.json +++ b/packages/translation/src/lang/de.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "Endet am" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "Zeige die aktuellen Streams auf deinen Medienservern an", "option": {}, "items": { + "currentlyPlaying": "", "user": "Benutzer", "name": "Name", "id": "Id" @@ -2321,6 +2325,7 @@ "label": "Werkzeuge", "items": { "docker": "Docker", + "kubernetes": "", "logs": "Logs", "api": "API", "certificates": "Zertifikate", @@ -2867,6 +2872,246 @@ "internalServerError": "Fehler beim Abrufen der Docker Container" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "Berechtigungen", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "Logs" }, diff --git a/packages/translation/src/lang/el.json b/packages/translation/src/lang/el.json index e791e84e8..52d252f69 100644 --- a/packages/translation/src/lang/el.json +++ b/packages/translation/src/lang/el.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Εργαλεία", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/es.json b/packages/translation/src/lang/es.json index 3dd2cdcf7..e32d829ca 100644 --- a/packages/translation/src/lang/es.json +++ b/packages/translation/src/lang/es.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Herramientas", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/et.json b/packages/translation/src/lang/et.json index 356bd4635..5b270419b 100644 --- a/packages/translation/src/lang/et.json +++ b/packages/translation/src/lang/et.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/fr.json b/packages/translation/src/lang/fr.json index 0fcb6ef65..6eeb17603 100644 --- a/packages/translation/src/lang/fr.json +++ b/packages/translation/src/lang/fr.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Outils", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/he.json b/packages/translation/src/lang/he.json index 669f44978..076aa1ccb 100644 --- a/packages/translation/src/lang/he.json +++ b/packages/translation/src/lang/he.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "סיים ב" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "הצג את הזרמים הנוכחיים בשרתי המדיה שלך", "option": {}, "items": { + "currentlyPlaying": "", "user": "משתמש", "name": "שם", "id": "מזהה" @@ -2321,6 +2325,7 @@ "label": "כלים", "items": { "docker": "דוקר", + "kubernetes": "", "logs": "קובצי לוג", "api": "ממשק API", "certificates": "אישורי אבטחה", @@ -2867,6 +2872,246 @@ "internalServerError": "נכשל בקבלת קונטיינרי דוקר" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "הרשאות", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "דוקר" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "קבצי לוג" }, diff --git a/packages/translation/src/lang/hr.json b/packages/translation/src/lang/hr.json index 417ce24a4..274a17524 100644 --- a/packages/translation/src/lang/hr.json +++ b/packages/translation/src/lang/hr.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Alati", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/hu.json b/packages/translation/src/lang/hu.json index 07fdfd420..6c4eb4080 100644 --- a/packages/translation/src/lang/hu.json +++ b/packages/translation/src/lang/hu.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Eszközök", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/it.json b/packages/translation/src/lang/it.json index c0008e707..1c0dc099f 100644 --- a/packages/translation/src/lang/it.json +++ b/packages/translation/src/lang/it.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Strumenti", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/ja.json b/packages/translation/src/lang/ja.json index dfce0b80c..5fbe7df9e 100644 --- a/packages/translation/src/lang/ja.json +++ b/packages/translation/src/lang/ja.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "ツール", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/ko.json b/packages/translation/src/lang/ko.json index ec8243f9d..7efac09ff 100644 --- a/packages/translation/src/lang/ko.json +++ b/packages/translation/src/lang/ko.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "도구", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/lt.json b/packages/translation/src/lang/lt.json index 8cb718897..32bf39897 100644 --- a/packages/translation/src/lang/lt.json +++ b/packages/translation/src/lang/lt.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Įrankiai", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/lv.json b/packages/translation/src/lang/lv.json index 0943fdc9b..f593f5922 100644 --- a/packages/translation/src/lang/lv.json +++ b/packages/translation/src/lang/lv.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Rīki", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/nl.json b/packages/translation/src/lang/nl.json index a17a839ee..6233b27e9 100644 --- a/packages/translation/src/lang/nl.json +++ b/packages/translation/src/lang/nl.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "Eindig bij" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "De huidige streams op je mediaservers weergeven", "option": {}, "items": { + "currentlyPlaying": "", "user": "Gebruiker", "name": "Naam", "id": "Id" @@ -2321,6 +2325,7 @@ "label": "Gereedschappen", "items": { "docker": "Docker", + "kubernetes": "", "logs": "Logs", "api": "API", "certificates": "Certificaten", @@ -2867,6 +2872,246 @@ "internalServerError": "Docker-containers zijn niet opgehaald" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "Machtigingen", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "Logs" }, diff --git a/packages/translation/src/lang/no.json b/packages/translation/src/lang/no.json index 67a0e116f..8456b831f 100644 --- a/packages/translation/src/lang/no.json +++ b/packages/translation/src/lang/no.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "Slutt på" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "Vis pågående strømmer på dine media-servere", "option": {}, "items": { + "currentlyPlaying": "", "user": "Bruker", "name": "Navn", "id": "Id" @@ -2321,6 +2325,7 @@ "label": "Verktøy", "items": { "docker": "Docker", + "kubernetes": "", "logs": "Logger", "api": "API", "certificates": "Sertifikater", @@ -2867,6 +2872,246 @@ "internalServerError": "Klarte ikke hente Docker-containere" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "Rettigheter", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "Logger" }, diff --git a/packages/translation/src/lang/pl.json b/packages/translation/src/lang/pl.json index ae3392882..609ab87ec 100644 --- a/packages/translation/src/lang/pl.json +++ b/packages/translation/src/lang/pl.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "Koniec o" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "Pokaż bieżące strumienie na serwerach multimedialnych", "option": {}, "items": { + "currentlyPlaying": "", "user": "Użytkownik", "name": "Nazwa", "id": "ID" @@ -2321,6 +2325,7 @@ "label": "Narzędzia", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/pt.json b/packages/translation/src/lang/pt.json index 7c4c855ed..56ea14fc1 100644 --- a/packages/translation/src/lang/pt.json +++ b/packages/translation/src/lang/pt.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Ferramentas", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/ro.json b/packages/translation/src/lang/ro.json index 1727513e9..ee473db30 100644 --- a/packages/translation/src/lang/ro.json +++ b/packages/translation/src/lang/ro.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Unelte", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/ru.json b/packages/translation/src/lang/ru.json index c9c685aef..a5715d01e 100644 --- a/packages/translation/src/lang/ru.json +++ b/packages/translation/src/lang/ru.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "Заканчивая" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "Отображает текущие сеансы воспроизведения на медиасерверах", "option": {}, "items": { + "currentlyPlaying": "", "user": "Пользователь", "name": "Название", "id": "Id" @@ -2321,6 +2325,7 @@ "label": "Инструменты", "items": { "docker": "Docker", + "kubernetes": "", "logs": "Логи", "api": "API", "certificates": "Сертификаты", @@ -2867,6 +2872,246 @@ "internalServerError": "Произошла ошибка при обновлении данных о контейнерах" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "Права доступа", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "Логи" }, diff --git a/packages/translation/src/lang/sk.json b/packages/translation/src/lang/sk.json index b2e00afb9..cf53e94a5 100644 --- a/packages/translation/src/lang/sk.json +++ b/packages/translation/src/lang/sk.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "Koniec o" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "Zobrazte aktuálne streamy na vašich mediálnych serveroch", "option": {}, "items": { + "currentlyPlaying": "", "user": "Používateľ", "name": "Názov", "id": "Id" @@ -2321,6 +2325,7 @@ "label": "Nástroje", "items": { "docker": "Docker", + "kubernetes": "", "logs": "Záznamy", "api": "API", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "Nepodarilo sa načítať kontajnery Docker" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "Povolenia", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "Záznamy" }, diff --git a/packages/translation/src/lang/sl.json b/packages/translation/src/lang/sl.json index edc4ddb1a..bf3020c33 100644 --- a/packages/translation/src/lang/sl.json +++ b/packages/translation/src/lang/sl.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Orodja", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/sv.json b/packages/translation/src/lang/sv.json index 1e9664a87..bb9481cb1 100644 --- a/packages/translation/src/lang/sv.json +++ b/packages/translation/src/lang/sv.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Verktyg", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/tr.json b/packages/translation/src/lang/tr.json index 7b2fa9275..4e1b6b4e6 100644 --- a/packages/translation/src/lang/tr.json +++ b/packages/translation/src/lang/tr.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "Bitiş" + }, + "showUnmonitored": { + "label": "Takip edilmeyenleri göster" } } }, @@ -1665,6 +1668,7 @@ "description": "Medya sunucularınızdaki mevcut akışları gösterin", "option": {}, "items": { + "currentlyPlaying": "Şuan Oynatılan", "user": "Kullanıcı", "name": "İsim", "id": "Kimlik" @@ -1889,10 +1893,10 @@ "statistics": { "empty": "Boş", "transcodes": "Kod dönüştürmeler", - "transcodesCount": "Kod dönüştürmeler: {value}", - "healthChecksCount": "Sağlık kontrolleri: {value}", - "filesCount": "Dosyalar: {value}", - "savedSpace": "Kaydedilen alan: {value}", + "transcodesCount": "Kod dönüştürmeler", + "healthChecksCount": "Sağlık kontrolleri", + "filesCount": "Dosyalar", + "savedSpace": "Kaydedilen alan", "healthChecks": "Sağlık kontrolleri", "videoCodecs": "Kodek'ler", "videoContainers": "Konteyner", @@ -2321,6 +2325,7 @@ "label": "Araçlar", "items": { "docker": "Docker", + "kubernetes": "", "logs": "Günlükler", "api": "API", "certificates": "Sertifikalar", @@ -2867,6 +2872,246 @@ "internalServerError": "Docker konteynerlerları getirilemedi" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "İzinler", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "Günlükler" }, diff --git a/packages/translation/src/lang/uk.json b/packages/translation/src/lang/uk.json index 1712a22ed..dfe73d54e 100644 --- a/packages/translation/src/lang/uk.json +++ b/packages/translation/src/lang/uk.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "Показує поточні потоки з ваших медіасерверів", "option": {}, "items": { + "currentlyPlaying": "", "user": "Користувач", "name": "Назва", "id": "Id" @@ -2321,6 +2325,7 @@ "label": "Інструменти", "items": { "docker": "Докер", + "kubernetes": "", "logs": "Логи", "api": "API", "certificates": "Сертифікати", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "Дозволи", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Докер" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "Логи" }, diff --git a/packages/translation/src/lang/vi.json b/packages/translation/src/lang/vi.json index 60db5bd00..7df6be0f7 100644 --- a/packages/translation/src/lang/vi.json +++ b/packages/translation/src/lang/vi.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "", "option": {}, "items": { + "currentlyPlaying": "", "user": "", "name": "", "id": "" @@ -2321,6 +2325,7 @@ "label": "Công cụ", "items": { "docker": "", + "kubernetes": "", "logs": "", "api": "", "certificates": "", @@ -2867,6 +2872,246 @@ "internalServerError": "" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "" }, diff --git a/packages/translation/src/lang/zh.json b/packages/translation/src/lang/zh.json index 4e282878a..37dd9d49f 100644 --- a/packages/translation/src/lang/zh.json +++ b/packages/translation/src/lang/zh.json @@ -1434,6 +1434,9 @@ }, "filterFutureMonths": { "label": "終止於" + }, + "showUnmonitored": { + "label": "" } } }, @@ -1665,6 +1668,7 @@ "description": "顯示當前多媒體伺服器的串流", "option": {}, "items": { + "currentlyPlaying": "", "user": "使用者", "name": "名稱", "id": "ID" @@ -2321,6 +2325,7 @@ "label": "工具", "items": { "docker": "Docker", + "kubernetes": "", "logs": "Logs", "api": "API", "certificates": "憑證", @@ -2867,6 +2872,246 @@ "internalServerError": "取得 Docker 容器失敗" } }, + "kubernetes": { + "cluster": { + "title": "", + "label": "", + "providers": "", + "version": "", + "architecture": "", + "capacity": { + "title": "", + "resource": { + "reserved": "", + "used": "" + } + }, + "resources": { + "title": "", + "nodes": "", + "namespaces": "", + "ingresses": "", + "services": "", + "pods": "", + "configmaps": "", + "secrets": "", + "volumes": "" + } + }, + "nodes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "ready": "", + "NotReady": "" + } + }, + "cpu": { + "label": "" + }, + "memory": { + "label": "" + }, + "pods": { + "label": "" + }, + "operatingSystem": { + "label": "" + }, + "architecture": { + "label": "" + }, + "kubernetesVersion": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "namespaces": { + "label": "", + "field": { + "name": { + "label": "" + }, + "state": { + "label": "", + "option": { + "active": "", + "terminating": "" + } + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "ingresses": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "className": { + "label": "" + }, + "rulesAndPaths": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "services": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "ports": { + "label": "" + }, + "targetPorts": { + "label": "" + }, + "clusterIP": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "pods": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "image": { + "label": "" + }, + "applicationType": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "secrets": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "type": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "configmaps": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "volumes": { + "label": "", + "field": { + "name": { + "label": "" + }, + "namespace": { + "label": "" + }, + "accessModes": { + "label": "" + }, + "storage": { + "label": "" + }, + "storageClassName": { + "label": "" + }, + "volumeMode": { + "label": "" + }, + "volumeName": { + "label": "" + }, + "status": { + "label": "" + }, + "creationTimestamp": { + "label": "" + } + }, + "table": { + "search": "" + } + }, + "error": { + "internalServerError": "" + } + }, "permission": { "title": "權限", "userSelect": { @@ -2952,6 +3197,33 @@ "docker": { "label": "Docker" }, + "kubernetes": { + "label": "", + "nodes": { + "label": "" + }, + "namespaces": { + "label": "" + }, + "ingresses": { + "label": "" + }, + "services": { + "label": "" + }, + "pods": { + "label": "" + }, + "configmaps": { + "label": "" + }, + "secrets": { + "label": "" + }, + "volumes": { + "label": "" + } + }, "logs": { "label": "Logs" }, From d714e53cfa88da22a6fc75473455d57be7bac497 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Mon, 10 Mar 2025 20:29:50 +0100 Subject: [PATCH 31/60] fix(downloads): improve responsive styles (#2552) --- packages/widgets/src/downloads/component.tsx | 191 +++++++------------ packages/widgets/src/widgets-common.css | 37 ---- 2 files changed, 71 insertions(+), 157 deletions(-) diff --git a/packages/widgets/src/downloads/component.tsx b/packages/widgets/src/downloads/component.tsx index 10c98ba8a..588cdf608 100644 --- a/packages/widgets/src/downloads/component.tsx +++ b/packages/widgets/src/downloads/component.tsx @@ -24,7 +24,6 @@ import { Tooltip, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; -import type { IconProps } from "@tabler/icons-react"; import { IconAlertTriangle, IconCirclesRelation, @@ -75,16 +74,6 @@ const columnsRatios: Record = { upSpeed: 3, }; -const actionIconIconStyle: IconProps["style"] = { - height: "var(--ai-icon-size)", - width: "var(--ai-icon-size)", -}; - -const standardIconStyle: IconProps["style"] = { - height: "var(--icon-size)", - width: "var(--icon-size)", -}; - export default function DownloadClientsWidget({ isEditMode, integrationIds, @@ -307,72 +296,41 @@ export default function DownloadClientsWidget({ upSpeed: options.columns.includes("upSpeed") && integrationTypes.includes("torrent"), } satisfies Record; - //Set a relative width using ratio table - const totalWidth = options.columns.reduce( - (count: number, column) => (columnVisibility[column] ? count + columnsRatios[column] : count), - 0, - ); - //Default styling behavior for stopping interaction when editing. (Applied everywhere except the table header) const editStyle: MantineStyleProp = { pointerEvents: isEditMode ? "none" : undefined, }; - //General style sizing as vars that should apply or be applied to all elements - const baseStyle: MantineStyleProp = { - "--total-width": totalWidth, - "--ratio-width": "calc(100cqw / var(--total-width))", - "--space-size": "calc(var(--ratio-width) * 0.1)", //Standard gap and spacing value - "--text-fz": "calc(var(--ratio-width) * 0.45)", //General Font Size - "--button-fz": "var(--text-fz)", - "--icon-size": "calc(var(--ratio-width) * 2 / 3)", //Normal icon size - "--ai-icon-size": "calc(var(--ratio-width) * 0.5)", //Icon inside action icons size - "--button-size": "calc(var(--ratio-width) * 0.75)", //Action Icon, button and avatar size - "--image-size": "var(--button-size)", - "--mrt-base-background-color": "transparent", - }; - //Base element in common with all columns const columnsDefBase = useCallback( ({ key, showHeader, - align, }: { key: keyof ExtendedDownloadClientItem; showHeader: boolean; - align?: "center" | "left" | "right" | "justify" | "char"; }): MRT_ColumnDef => { - const style: MantineStyleProp = { - minWidth: 0, - width: "var(--column-width)", - height: "var(--ratio-width)", - padding: "var(--space-size)", - transition: "unset", - "--key-width": columnsRatios[key], - "--column-width": "calc((var(--key-width)/var(--total-width) * 100cqw))", - }; return { id: key, accessorKey: key, header: key, size: columnsRatios[key], - mantineTableBodyCellProps: { style, align }, - mantineTableHeadCellProps: { - style, - align: isEditMode ? "center" : align, - }, - Header: () => (showHeader && !isEditMode ? {t(`items.${key}.columnTitle`)} : ""), + Header: () => + showHeader ? ( + + {t(`items.${key}.columnTitle`)} + + ) : null, }; }, - [isEditMode, t], + [t], ); //Make columns and cell elements, Memoized to data with deps on data and EditMode const columns = useMemo[]>( () => [ { - ...columnsDefBase({ key: "actions", showHeader: false, align: "center" }), + ...columnsDefBase({ key: "actions", showHeader: false }), enableSorting: false, Cell: ({ cell, row }) => { const actions = cell.getValue(); @@ -380,19 +338,15 @@ export default function DownloadClientsWidget({ const [opened, { open, close }] = useDisclosure(false); return actions ? ( - + - - {pausedAction === "resume" ? ( - - ) : ( - - )} + + {pausedAction === "resume" ? : } - - + + @@ -423,68 +377,68 @@ export default function DownloadClientsWidget({ ) : ( - - + + ); }, }, { - ...columnsDefBase({ key: "added", showHeader: true, align: "center" }), + ...columnsDefBase({ key: "added", showHeader: true }), sortUndefined: "last", Cell: ({ cell }) => { const added = cell.getValue(); - return {added !== undefined ? dayjs(added).fromNow() : "unknown"}; + return {added !== undefined ? dayjs(added).fromNow() : "unknown"}; }, }, { - ...columnsDefBase({ key: "category", showHeader: false, align: "center" }), + ...columnsDefBase({ key: "category", showHeader: false }), sortUndefined: "last", Cell: ({ cell }) => { const category = cell.getValue(); return ( category !== undefined && ( - + ) ); }, }, { - ...columnsDefBase({ key: "downSpeed", showHeader: true, align: "right" }), + ...columnsDefBase({ key: "downSpeed", showHeader: true }), sortUndefined: "last", Cell: ({ cell }) => { const downSpeed = cell.getValue(); - return downSpeed && {humanFileSize(downSpeed, "/s")}; + return downSpeed ? {humanFileSize(downSpeed, "/s")} : null; }, }, { - ...columnsDefBase({ key: "id", showHeader: false, align: "center" }), + ...columnsDefBase({ key: "id", showHeader: false }), enableSorting: false, Cell: ({ cell }) => { const id = cell.getValue(); return ( - + ); }, }, { - ...columnsDefBase({ key: "index", showHeader: true, align: "center" }), + ...columnsDefBase({ key: "index", showHeader: true }), Cell: ({ cell }) => { const index = cell.getValue(); - return {index}; + return {index}; }, }, { - ...columnsDefBase({ key: "integration", showHeader: false, align: "center" }), + ...columnsDefBase({ key: "integration", showHeader: false }), Cell: ({ cell }) => { const integration = cell.getValue(); return ( - + ); }, @@ -494,62 +448,61 @@ export default function DownloadClientsWidget({ Cell: ({ cell }) => { const name = cell.getValue(); return ( - + {name} ); }, }, { - ...columnsDefBase({ key: "progress", showHeader: true, align: "center" }), + ...columnsDefBase({ key: "progress", showHeader: true }), Cell: ({ cell, row }) => { const progress = cell.getValue(); return ( - - + + {new Intl.NumberFormat("en", { style: "percent", notation: "compact", unitDisplay: "narrow" }).format( progress, )} - + ); }, }, { - ...columnsDefBase({ key: "ratio", showHeader: true, align: "center" }), + ...columnsDefBase({ key: "ratio", showHeader: true }), sortUndefined: "last", Cell: ({ cell }) => { const ratio = cell.getValue(); - return ratio !== undefined && {ratio.toFixed(ratio >= 100 ? 0 : ratio >= 10 ? 1 : 2)}; + return ratio !== undefined && {ratio.toFixed(ratio >= 100 ? 0 : ratio >= 10 ? 1 : 2)}; }, }, { - ...columnsDefBase({ key: "received", showHeader: true, align: "right" }), + ...columnsDefBase({ key: "received", showHeader: true }), Cell: ({ cell }) => { const received = cell.getValue(); - return {humanFileSize(received)}; + return {humanFileSize(received)}; }, }, { - ...columnsDefBase({ key: "sent", showHeader: true, align: "right" }), + ...columnsDefBase({ key: "sent", showHeader: true }), sortUndefined: "last", Cell: ({ cell }) => { const sent = cell.getValue(); - return sent && {humanFileSize(sent)}; + return sent && {humanFileSize(sent)}; }, }, { - ...columnsDefBase({ key: "size", showHeader: true, align: "right" }), + ...columnsDefBase({ key: "size", showHeader: true }), Cell: ({ cell }) => { const size = cell.getValue(); - return {humanFileSize(size)}; + return {humanFileSize(size)}; }, }, { @@ -557,25 +510,25 @@ export default function DownloadClientsWidget({ enableSorting: false, Cell: ({ cell }) => { const state = cell.getValue(); - return {t(`states.${state}`)}; + return {t(`states.${state}`)}; }, }, { - ...columnsDefBase({ key: "time", showHeader: true, align: "center" }), + ...columnsDefBase({ key: "time", showHeader: true }), Cell: ({ cell }) => { const time = cell.getValue(); - return time === 0 ? : {dayjs().add(time).fromNow()}; + return time === 0 ? : {dayjs().add(time).fromNow()}; }, }, { ...columnsDefBase({ key: "type", showHeader: true }), Cell: ({ cell }) => { const type = cell.getValue(); - return {type}; + return {type}; }, }, { - ...columnsDefBase({ key: "upSpeed", showHeader: true, align: "right" }), + ...columnsDefBase({ key: "upSpeed", showHeader: true }), sortUndefined: "last", Cell: ({ cell }) => { const upSpeed = cell.getValue(); @@ -604,17 +557,17 @@ export default function DownloadClientsWidget({ mantineTableContainerProps: { style: { height: "100%" } }, mantineTableProps: { className: "downloads-widget-table", - style: { - "--sortButtonSize": "var(--button-size)", - "--dragButtonSize": "var(--button-size)", - }, }, mantineTableBodyProps: { style: editStyle }, + mantineTableHeadCellProps: { + p: 4, + }, mantineTableBodyCellProps: ({ cell, row }) => ({ onClick: () => { setClickedIndex(row.index); if (cell.column.id !== "actions") open(); }, + p: 4, }), onColumnOrderChange: (order) => { //Order has a tendency to add the disabled column at the end of the the real ordered array @@ -666,26 +619,25 @@ export default function DownloadClientsWidget({ if (options.columns.length === 0) return (
- {t("errors.noColumns")} + {t("errors.noColumns")}
); //The actual widget return ( - + {integrationTypes.includes("torrent") && ( - - {`${t("globalRatio")}:`} - {(globalTraffic.up / globalTraffic.down).toFixed(2)} + + {`${t("globalRatio")}:`} + {(globalTraffic.up / globalTraffic.down).toFixed(2)} )} - - + + - + {t("items.integration.columnTitle")} - + {clients.map((client) => ( ))} @@ -847,37 +799,37 @@ const ClientsControl = ({ clients, filters, setFilters, availableStatuses }: Cli {someInteract && ( mutateResumeQueue({ integrationIds: integrationsStatuses.paused })} > - + )} {someInteract && ( mutatePauseQueue({ integrationIds: integrationsStatuses.active })} > - + )} @@ -967,9 +919,8 @@ const ClientAvatar = ({ client }: ClientAvatarProps) => { key={client.integration.id} src={getIconUrl(client.integration.kind)} style={{ filter: !isConnected ? "grayscale(100%)" : undefined }} - size={30} + size="sm" p={5} - bd={`calc(var(--space-size)*0.5) solid ${client.status ? "transparent" : "var(--mantine-color-red-filled)"}`} /> ); }; diff --git a/packages/widgets/src/widgets-common.css b/packages/widgets/src/widgets-common.css index 5bcacd11f..7c75ebf0a 100644 --- a/packages/widgets/src/widgets-common.css +++ b/packages/widgets/src/widgets-common.css @@ -1,40 +1,3 @@ -.downloads-widget-table { - /*Set Header static and overflow body instead*/ - display: flex; - height: 100%; - flex-direction: column; - .mantine-Table-tbody { - overflow-y: auto; - flex: 1; - scrollbar-width: 0; - } - /*Hide scrollbar until I can apply an overlay scrollbar instead*/ - .mantine-Table-tbody::-webkit-scrollbar { - width: 0; - } - /*Properly size header*/ - .mrt-table-head-cell-labels { - min-height: var(--ratioWidth); - gap: 0; - padding: 0; - } - /*Properly size controls*/ - .mrt-grab-handle-button { - margin: unset; - width: var(--dragButtonSize); - min-width: var(--dragButtonSize); - height: var(--dragButtonSize); - min-height: var(--dragButtonSize); - } - .mrt-table-head-sort-button { - margin: unset; - width: var(--sortButtonSize); - min-width: var(--sortButtonSize); - height: var(--sortButtonSize); - min-height: var(--sortButtonSize); - } -} - /*Make background of component different on hover, depending on base var*/ .hoverable-component { &:hover { From 225ed4881b8ba0e1d89ca74e2fd3ecf517fdb8d6 Mon Sep 17 00:00:00 2001 From: "homarr-crowdin[bot]" <190541745+homarr-crowdin[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 00:47:24 +0000 Subject: [PATCH 32/60] chore(lang): updated translations from crowdin Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com> --- packages/translation/src/lang/no.json | 288 +++++++++++++------------- packages/translation/src/lang/tr.json | 188 ++++++++--------- 2 files changed, 238 insertions(+), 238 deletions(-) diff --git a/packages/translation/src/lang/no.json b/packages/translation/src/lang/no.json index 8456b831f..2d0b034bb 100644 --- a/packages/translation/src/lang/no.json +++ b/packages/translation/src/lang/no.json @@ -307,12 +307,12 @@ "name": "Navn", "members": "Medlemmer", "homeBoard": { - "label": "", - "description": "" + "label": "Hjem tavle", + "description": "Bare tavler som er tilgjengelige for gruppen kan velges" }, "mobileBoard": { - "label": "", - "description": "" + "label": "Mobiltavle", + "description": "Bare tavler som er tilgjengelige for gruppen kan velges" } }, "permission": { @@ -514,12 +514,12 @@ "board": { "notification": { "success": { - "title": "", - "message": "" + "title": "Innstillinger lagret", + "message": "Innstillinger for tavle er lagret" }, "error": { - "title": "", - "message": "" + "title": "Kunne ikke lagre innstillinger", + "message": "Kan ikke lagre tavleinnstillinger" } } } @@ -527,17 +527,17 @@ "changePosition": { "notification": { "success": { - "message": "" + "message": "Posisjonen ble endret" }, "error": { - "message": "" + "message": "Kan ikke endre posisjon" } } } }, "defaultGroup": { - "name": "", - "description": "" + "name": "Standard gruppe", + "description": "{name} – Alle påloggede brukere" } }, "app": { @@ -603,8 +603,8 @@ }, "useDifferentUrlForPing": { "checkbox": { - "label": "", - "description": "" + "label": "Bruk annen URL for ping", + "description": "Nyttig hvis Homarr kan få direkte tilgang med et internt vertsnavn eller nettverk for å unngå båndbreddebruk av ISP" } } }, @@ -930,7 +930,7 @@ }, "dangerZone": "Faresonen", "noResults": "Ingen resultater funnet", - "unsavedChanges": "", + "unsavedChanges": "Du har ulagrede endringer!", "preview": { "show": "Vis forhåndsvisning", "hide": "Skjul forhåndsvisning" @@ -974,7 +974,7 @@ }, "option": { "borderColor": { - "label": "" + "label": "Grensefarge" } }, "remove": { @@ -1072,7 +1072,7 @@ "label": "Egendefinerte css-klasser" }, "borderColor": { - "label": "" + "label": "Grensefarge" } } }, @@ -1129,12 +1129,12 @@ "label": "Rutenettet" }, "gridHorizontal": { - "label": "" + "label": "Rutenett horisontalt" } } }, "hideTitle": { - "label": "" + "label": "Skjul tittel" }, "hideIcon": { "label": "Skjul ikoner" @@ -1436,7 +1436,7 @@ "label": "Slutt på" }, "showUnmonitored": { - "label": "" + "label": "Vis ikke monitorert" } } }, @@ -1632,7 +1632,7 @@ "app": { "noData": "Ingen app funnet", "description": "Klikk for å opprette en ny app", - "quickCreate": "" + "quickCreate": "Opprett app direkte" }, "error": { "noIntegration": "Ingen integrasjon valgt", @@ -1668,7 +1668,7 @@ "description": "Vis pågående strømmer på dine media-servere", "option": {}, "items": { - "currentlyPlaying": "", + "currentlyPlaying": "Spilles nå", "user": "Bruker", "name": "Navn", "id": "Id" @@ -1835,10 +1835,10 @@ "available": "Tilgjengelig" }, "status": { - "pending": "", - "approved": "", - "declined": "", - "failed": "" + "pending": "Venter", + "approved": "Godkjent", + "declined": "Avslått", + "failed": "Feilet" }, "toBeDetermined": "Uavklart" }, @@ -1893,10 +1893,10 @@ "statistics": { "empty": "Tøm", "transcodes": "Transkoder", - "transcodesCount": "Transkoder: {value}", - "healthChecksCount": "Helsesjekker: {value}", - "filesCount": "Filer: {value}", - "savedSpace": "Diskplass spart: {value}", + "transcodesCount": "Transkoder", + "healthChecksCount": "Helsesjekker", + "filesCount": "Filer", + "savedSpace": "Diskplass spart", "healthChecks": "Helsesjekker", "videoCodecs": "Kodeker", "videoContainers": "Containere", @@ -2041,8 +2041,8 @@ }, "quickCreateApp": { "modal": { - "title": "", - "createAndUse": "" + "title": "Opprett app direkte", + "createAndUse": "Opprett og bruk" } } }, @@ -2119,7 +2119,7 @@ "label": "Gjennomsiktighet" }, "iconColor": { - "label": "" + "label": "Ikonfarge" }, "customCss": { "label": "Tilpasset css for denne tavlen", @@ -2137,14 +2137,14 @@ "label": "Antall kolonner" }, "itemRadius": { - "label": "", - "description": "", + "label": "Objekt radius", + "description": "Endrer flisenes rundhet på tavlen", "option": { - "xs": "", - "sm": "", - "md": "", - "lg": "", - "xl": "" + "xs": "Veldig liten", + "sm": "Liten", + "md": "Medium", + "lg": "Stor", + "xl": "Veldig stor" } }, "name": { @@ -2168,9 +2168,9 @@ "layout": { "title": "Oppsett", "responsive": { - "title": "", + "title": "Responsivt oppsett", "action": { - "add": "" + "add": "Legg til oppsett" } } }, @@ -2178,7 +2178,7 @@ "title": "Bakgrunn" }, "appearance": { - "title": "" + "title": "Utseende" }, "customCss": { "title": "Egendefinert css" @@ -2283,14 +2283,14 @@ "layout": { "field": { "name": { - "label": "" + "label": "Navn" }, "columnCount": { - "label": "" + "label": "Antall kolonner" }, "breakpoint": { - "label": "", - "description": "" + "label": "Stoppunkt", + "description": "Oppsett vil bli brukt på alle skjermer som er større enn dette bruddpunktet til neste større bruddpunkt." } } }, @@ -2325,7 +2325,7 @@ "label": "Verktøy", "items": { "docker": "Docker", - "kubernetes": "", + "kubernetes": "Kubernetes", "logs": "Logger", "api": "API", "certificates": "Sertifikater", @@ -2524,10 +2524,10 @@ "ownerOfGroupDeleted": "Eieren av gruppen ble slettet. Den har for øyeblikket ingen eier." }, "setting": { - "title": "", - "alert": "", + "title": "Innstillinger", + "alert": "Gruppeinnstillinger er prioritert etter rekkefølgen på gruppene i listen. Øverste innstillinger overskriver bunninnstillingene.", "board": { - "title": "" + "title": "Tavler" } }, "members": { @@ -2874,242 +2874,242 @@ }, "kubernetes": { "cluster": { - "title": "", - "label": "", - "providers": "", - "version": "", - "architecture": "", + "title": "Klynge dashbord", + "label": "Klynge", + "providers": "Leverandør", + "version": "Versjon", + "architecture": "Arkitektur", "capacity": { - "title": "", + "title": "Kapasitet", "resource": { - "reserved": "", - "used": "" + "reserved": "Reservert", + "used": "Brukt" } }, "resources": { - "title": "", - "nodes": "", - "namespaces": "", - "ingresses": "", - "services": "", - "pods": "", - "configmaps": "", - "secrets": "", - "volumes": "" + "title": "Ressurser", + "nodes": "Noder", + "namespaces": "Navnerom", + "ingresses": "Ingress", + "services": "Tjenester", + "pods": "Pods", + "configmaps": "ConfigMaps", + "secrets": "Hemmeligheter", + "volumes": "Volumer" } }, "nodes": { - "label": "", + "label": "Noder", "field": { "name": { - "label": "" + "label": "Navn" }, "state": { - "label": "", + "label": "Status", "option": { - "ready": "", - "NotReady": "" + "ready": "Klar", + "NotReady": "Ikke klar" } }, "cpu": { - "label": "" + "label": "CPU" }, "memory": { - "label": "" + "label": "RAM" }, "pods": { - "label": "" + "label": "Pods" }, "operatingSystem": { - "label": "" + "label": "OS" }, "architecture": { - "label": "" + "label": "Arkitektur" }, "kubernetesVersion": { - "label": "" + "label": "Kubernetes versjon" }, "creationTimestamp": { - "label": "" + "label": "Opprettet" } }, "table": { - "search": "" + "search": "Søk i {count} noder" } }, "namespaces": { - "label": "", + "label": "Navnerom", "field": { "name": { - "label": "" + "label": "Navn" }, "state": { - "label": "", + "label": "Status", "option": { - "active": "", - "terminating": "" + "active": "Aktiv", + "terminating": "Avslutter" } }, "creationTimestamp": { - "label": "" + "label": "Opprettet" } }, "table": { - "search": "" + "search": "Søk i {count} navnerom" } }, "ingresses": { - "label": "", + "label": "Ingress", "field": { "name": { - "label": "" + "label": "Navn" }, "namespace": { - "label": "" + "label": "Navnerom" }, "className": { - "label": "" + "label": "Klassenavn" }, "rulesAndPaths": { - "label": "" + "label": "Regler & stier" }, "creationTimestamp": { - "label": "" + "label": "Opprettet" } }, "table": { - "search": "" + "search": "Søk i {count} ingress" } }, "services": { - "label": "", + "label": "Tjenester", "field": { "name": { - "label": "" + "label": "Navn" }, "namespace": { - "label": "" + "label": "Navnerom" }, "type": { - "label": "" + "label": "Type" }, "ports": { - "label": "" + "label": "Porter" }, "targetPorts": { - "label": "" + "label": "Målporter" }, "clusterIP": { - "label": "" + "label": "Klynge IP" }, "creationTimestamp": { - "label": "" + "label": "Opprettet" } }, "table": { - "search": "" + "search": "Søk i {count} tjenester" } }, "pods": { - "label": "", + "label": "Pods", "field": { "name": { - "label": "" + "label": "Navn" }, "namespace": { - "label": "" + "label": "Navnerom" }, "image": { - "label": "" + "label": "Image" }, "applicationType": { - "label": "" + "label": "Applikasjonstype" }, "status": { - "label": "" + "label": "Status" }, "creationTimestamp": { - "label": "" + "label": "Opprettet" } }, "table": { - "search": "" + "search": "Søk i {count} pods" } }, "secrets": { - "label": "", + "label": "Hemmeligheter", "field": { "name": { - "label": "" + "label": "Navn" }, "namespace": { - "label": "" + "label": "navnerom" }, "type": { - "label": "" + "label": "type" }, "creationTimestamp": { - "label": "" + "label": "Opprettet" } }, "table": { - "search": "" + "search": "Søk i {count} hemmeligheter" } }, "configmaps": { - "label": "", + "label": "ConfigMaps", "field": { "name": { - "label": "" + "label": "Navn" }, "namespace": { - "label": "" + "label": "navnerom" }, "creationTimestamp": { - "label": "" + "label": "Opprettet" } }, "table": { - "search": "" + "search": "Søk i {count} configMaps" } }, "volumes": { - "label": "", + "label": "Volumer", "field": { "name": { - "label": "" + "label": "Navn" }, "namespace": { - "label": "" + "label": "Navnerom" }, "accessModes": { - "label": "" + "label": "Tilgang moduser" }, "storage": { - "label": "" + "label": "Lagring" }, "storageClassName": { - "label": "" + "label": "Lagerklasse navn" }, "volumeMode": { - "label": "" + "label": "Volum modus" }, "volumeName": { - "label": "" + "label": "Volum navn" }, "status": { - "label": "" + "label": "Status" }, "creationTimestamp": { - "label": "" + "label": "Opprettet" } }, "table": { - "search": "" + "search": "Søk i {count} volumer" } }, "error": { - "internalServerError": "" + "internalServerError": "Kan ikke hente data fra Kubernetes" } }, "permission": { @@ -3198,30 +3198,30 @@ "label": "Docker" }, "kubernetes": { - "label": "", + "label": "Kubernetes", "nodes": { - "label": "" + "label": "Noder" }, "namespaces": { - "label": "" + "label": "Navnerom" }, "ingresses": { - "label": "" + "label": "Ingress" }, "services": { - "label": "" + "label": "Tjenester" }, "pods": { - "label": "" + "label": "pods" }, "configmaps": { - "label": "" + "label": "ConfigMaps" }, "secrets": { - "label": "" + "label": "Hemmeligheter" }, "volumes": { - "label": "" + "label": "Volumer" } }, "logs": { diff --git a/packages/translation/src/lang/tr.json b/packages/translation/src/lang/tr.json index 4e1b6b4e6..0f9b1cb56 100644 --- a/packages/translation/src/lang/tr.json +++ b/packages/translation/src/lang/tr.json @@ -2325,7 +2325,7 @@ "label": "Araçlar", "items": { "docker": "Docker", - "kubernetes": "", + "kubernetes": "Kubernetes", "logs": "Günlükler", "api": "API", "certificates": "Sertifikalar", @@ -2874,242 +2874,242 @@ }, "kubernetes": { "cluster": { - "title": "", - "label": "", - "providers": "", - "version": "", - "architecture": "", + "title": "Küme Panosu", + "label": "Küme", + "providers": "Sağlayıcılar", + "version": "Sürüm", + "architecture": "Mimari", "capacity": { - "title": "", + "title": "Kapasite", "resource": { - "reserved": "", - "used": "" + "reserved": "Rezerve", + "used": "Kullanılan" } }, "resources": { - "title": "", - "nodes": "", - "namespaces": "", - "ingresses": "", - "services": "", - "pods": "", - "configmaps": "", - "secrets": "", - "volumes": "" + "title": "Kaynaklar", + "nodes": "Nodes", + "namespaces": "İsim Alanları", + "ingresses": "Ingress'ler", + "services": "Hizmetler", + "pods": "Pod'lar", + "configmaps": "ConfigMap'ler", + "secrets": "Gizli anahtarlar", + "volumes": "Birimler" } }, "nodes": { - "label": "", + "label": "Node'lar", "field": { "name": { - "label": "" + "label": "İsim" }, "state": { - "label": "", + "label": "Durum", "option": { - "ready": "", - "NotReady": "" + "ready": "Hazır", + "NotReady": "Hazır Değil" } }, "cpu": { - "label": "" + "label": "İşlemci" }, "memory": { - "label": "" + "label": "BELLEK" }, "pods": { - "label": "" + "label": "Pod'lar" }, "operatingSystem": { - "label": "" + "label": "İşletim Sistemi" }, "architecture": { - "label": "" + "label": "Mimari" }, "kubernetesVersion": { - "label": "" + "label": "Kubernetes Sürümü" }, "creationTimestamp": { - "label": "" + "label": "Oluşturuldu" } }, "table": { - "search": "" + "search": "{count} node içinde ara" } }, "namespaces": { - "label": "", + "label": "İsim Alanları", "field": { "name": { - "label": "" + "label": "İsim" }, "state": { - "label": "", + "label": "Durum", "option": { - "active": "", - "terminating": "" + "active": "Aktif", + "terminating": "Sonlandırma" } }, "creationTimestamp": { - "label": "" + "label": "Oluşturuldu" } }, "table": { - "search": "" + "search": "{count} isim alanı içinde ara" } }, "ingresses": { - "label": "", + "label": "Ingress'ler", "field": { "name": { - "label": "" + "label": "İsim" }, "namespace": { - "label": "" + "label": "İsim Alanı" }, "className": { - "label": "" + "label": "Sınıf ismi" }, "rulesAndPaths": { - "label": "" + "label": "Kurallar & yollar" }, "creationTimestamp": { - "label": "" + "label": "Oluşturuldu" } }, "table": { - "search": "" + "search": "{count} ingress içinde ara" } }, "services": { - "label": "", + "label": "Hizmetler", "field": { "name": { - "label": "" + "label": "İsim" }, "namespace": { - "label": "" + "label": "İsim Alanı" }, "type": { - "label": "" + "label": "Tip" }, "ports": { - "label": "" + "label": "Bağlantı noktaları" }, "targetPorts": { - "label": "" + "label": "Hedef bağlantı noktası" }, "clusterIP": { - "label": "" + "label": "Küme IP'si" }, "creationTimestamp": { - "label": "" + "label": "Oluşturuldu" } }, "table": { - "search": "" + "search": "{count} hizmet içerisinde ara" } }, "pods": { - "label": "", + "label": "Pod'lar", "field": { "name": { - "label": "" + "label": "İsim" }, "namespace": { - "label": "" + "label": "İsim Alanı" }, "image": { - "label": "" + "label": "İmaj" }, "applicationType": { - "label": "" + "label": "Uygulama Türü" }, "status": { - "label": "" + "label": "Durum" }, "creationTimestamp": { - "label": "" + "label": "Oluşturuldu" } }, "table": { - "search": "" + "search": "{count} pod içerisinde ara" } }, "secrets": { - "label": "", + "label": "Gizli anahtarlar", "field": { "name": { - "label": "" + "label": "İsim" }, "namespace": { - "label": "" + "label": "i̇sim Alanı" }, "type": { - "label": "" + "label": "tür" }, "creationTimestamp": { - "label": "" + "label": "Oluşturuldu" } }, "table": { - "search": "" + "search": "{count} gizli anahtar içerisinde ara" } }, "configmaps": { - "label": "", + "label": "ConfigMap'ler", "field": { "name": { - "label": "" + "label": "İsim" }, "namespace": { - "label": "" + "label": "İsim Alanı" }, "creationTimestamp": { - "label": "" + "label": "Oluşturuldu" } }, "table": { - "search": "" + "search": "{count} configMap içinde ara" } }, "volumes": { - "label": "", + "label": "Birimler", "field": { "name": { - "label": "" + "label": "İsim" }, "namespace": { - "label": "" + "label": "İsim Alanı" }, "accessModes": { - "label": "" + "label": "Erişim Modları" }, "storage": { - "label": "" + "label": "Depolama" }, "storageClassName": { - "label": "" + "label": "Depolama Sınıfı Adı" }, "volumeMode": { - "label": "" + "label": "Birim Modu" }, "volumeName": { - "label": "" + "label": "Birim Adı" }, "status": { - "label": "" + "label": "Durum" }, "creationTimestamp": { - "label": "" + "label": "Oluşturuldu" } }, "table": { - "search": "" + "search": "{count} birim içerisinde ara" } }, "error": { - "internalServerError": "" + "internalServerError": "Kubernetes verileri alınamadı" } }, "permission": { @@ -3198,30 +3198,30 @@ "label": "Docker" }, "kubernetes": { - "label": "", + "label": "Kubernetes", "nodes": { - "label": "" + "label": "Node'lar" }, "namespaces": { - "label": "" + "label": "İsim Alanları" }, "ingresses": { - "label": "" + "label": "Ingress'ler" }, "services": { - "label": "" + "label": "Hizmetler" }, "pods": { - "label": "" + "label": "pod'lar" }, "configmaps": { - "label": "" + "label": "ConfigMap'ler" }, "secrets": { - "label": "" + "label": "Gizli anahtarlar" }, "volumes": { - "label": "" + "label": "Birimler" } }, "logs": { From a102f39518722d898d75d978df91ae2a7f8da3e9 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 13:05:22 +0000 Subject: [PATCH 33/60] fix(deps): update dependency video.js to ^8.22.0 (#2564) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- packages/widgets/package.json | 2 +- pnpm-lock.yaml | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/widgets/package.json b/packages/widgets/package.json index ec7450a0a..edd958ad2 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -68,7 +68,7 @@ "next": "15.1.7", "react": "19.0.0", "react-dom": "19.0.0", - "video.js": "^8.21.0", + "video.js": "^8.22.0", "zod": "^3.24.2" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 97d86d993..a431f0a64 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2145,8 +2145,8 @@ importers: specifier: 19.0.0 version: 19.0.0(react@19.0.0) video.js: - specifier: ^8.21.0 - version: 8.21.0 + specifier: ^8.22.0 + version: 8.22.0 zod: specifier: ^3.24.2 version: 3.24.2 @@ -4831,8 +4831,8 @@ packages: '@umami/node@0.4.0': resolution: {integrity: sha512-pyphprbiF7KiDSc+SWZ4/rVM8B5vU27zIiFfEPj2lEqczpI4xAKSp+dM3tlzyRAWJL32fcbCfAaLGhJZQV13Rg==} - '@videojs/http-streaming@3.16.2': - resolution: {integrity: sha512-fvt4ko7FknxiT9FnjyNQt6q2px+awrkM+Orv7IB/4gldvj94u4fowGfmNHynnvNTPgPkdxHklGmFLGfclYw8HA==} + '@videojs/http-streaming@3.17.0': + resolution: {integrity: sha512-Ch1P3tvvIEezeZXyK11UfWgp4cWKX4vIhZ30baN/lRinqdbakZ5hiAI3pGjRy3d+q/Epyc8Csz5xMdKNNGYpcw==} engines: {node: '>=8', npm: '>=5'} peerDependencies: video.js: ^8.19.0 @@ -9960,8 +9960,8 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - video.js@8.21.0: - resolution: {integrity: sha512-zcwerRb257QAuWfi8NH9yEX7vrGKFthjfcONmOQ4lxFRpDAbAi+u5LAjCjMWqhJda6zEmxkgdDpOMW3Y21QpXA==} + video.js@8.22.0: + resolution: {integrity: sha512-xge2kpjsvC0zgFJ1cqt+wTqsi21+huFswlonPFh7qiplypsb4FN/D2Rz6bWdG/S9eQaPHfWHsarmJL/7D3DHoA==} videojs-contrib-quality-levels@4.1.0: resolution: {integrity: sha512-TfrXJJg1Bv4t6TOCMEVMwF/CoS8iENYsWNKip8zfhB5kTcegiFYezEA0eHAJPU64ZC8NQbxQgOwAsYU8VXbOWA==} @@ -13027,7 +13027,7 @@ snapshots: '@umami/node@0.4.0': {} - '@videojs/http-streaming@3.16.2(video.js@8.21.0)': + '@videojs/http-streaming@3.17.0(video.js@8.22.0)': dependencies: '@babel/runtime': 7.25.6 '@videojs/vhs-utils': 4.1.1 @@ -13036,7 +13036,7 @@ snapshots: m3u8-parser: 7.2.0 mpd-parser: 1.3.1 mux.js: 7.1.0 - video.js: 8.21.0 + video.js: 8.22.0 '@videojs/vhs-utils@4.0.0': dependencies: @@ -18817,10 +18817,10 @@ snapshots: vary@1.1.2: {} - video.js@8.21.0: + video.js@8.22.0: dependencies: '@babel/runtime': 7.25.6 - '@videojs/http-streaming': 3.16.2(video.js@8.21.0) + '@videojs/http-streaming': 3.17.0(video.js@8.22.0) '@videojs/vhs-utils': 4.1.1 '@videojs/xhr': 2.7.0 aes-decrypter: 4.0.2 @@ -18828,14 +18828,14 @@ snapshots: m3u8-parser: 7.2.0 mpd-parser: 1.3.1 mux.js: 7.1.0 - videojs-contrib-quality-levels: 4.1.0(video.js@8.21.0) + videojs-contrib-quality-levels: 4.1.0(video.js@8.22.0) videojs-font: 4.2.0 videojs-vtt.js: 0.15.5 - videojs-contrib-quality-levels@4.1.0(video.js@8.21.0): + videojs-contrib-quality-levels@4.1.0(video.js@8.22.0): dependencies: global: 4.4.0 - video.js: 8.21.0 + video.js: 8.22.0 videojs-font@4.2.0: {} From afcde8afe5ecc1870f016f42c2be2881d2ab375a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 17:58:31 +0100 Subject: [PATCH 34/60] chore(deps): bump prismjs from 1.27.0 to 1.30.0 (#2565) Bumps [prismjs](https://github.com/PrismJS/prism) from 1.27.0 to 1.30.0. - [Release notes](https://github.com/PrismJS/prism/releases) - [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md) - [Commits](https://github.com/PrismJS/prism/compare/v1.27.0...v1.30.0) --- updated-dependencies: - dependency-name: prismjs dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 444 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 305 insertions(+), 139 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a431f0a64..a2261e215 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,7 +42,7 @@ importers: version: 2.4.4(@types/node@22.13.10)(typescript@5.8.2) '@vitejs/plugin-react': specifier: ^4.3.4 - version: 4.3.4(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0)) + version: 4.3.4(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0)) '@vitest/coverage-v8': specifier: ^3.0.8 version: 3.0.8(vitest@3.0.8) @@ -75,10 +75,10 @@ importers: version: 5.8.2 vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.2)(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0)) + version: 5.1.4(typescript@5.8.2)(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0)) vitest: specifier: ^3.0.8 - version: 3.0.8(@types/node@22.13.10)(@vitest/ui@3.0.8)(jsdom@26.0.0)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0) + version: 3.0.8(@types/node@22.13.10)(@vitest/ui@3.0.8)(jsdom@26.0.0)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0) apps/nextjs: dependencies: @@ -2336,6 +2336,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.26.9': + resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-transform-react-jsx-self@7.25.9': resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} engines: {node: '>=6.9.0'} @@ -2368,6 +2373,10 @@ packages: resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} + '@babel/types@7.26.9': + resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} + engines: {node: '>=6.9.0'} + '@balena/dockerignore@1.0.2': resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==} @@ -3455,6 +3464,10 @@ packages: resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -4127,6 +4140,9 @@ packages: '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@swagger-api/apidom-ast@1.0.0-beta.12': resolution: {integrity: sha512-KdJ+8PyYvfnHgpqrC0WWDRJLVx6+YkmYgAGpsdOa8S/p6btJdCUozeqpcXawmGqwAX/9jCXbmKdia3v3fUrP0w==} @@ -4897,50 +4913,50 @@ packages: '@vitest/utils@3.0.8': resolution: {integrity: sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==} - '@webassemblyjs/ast@1.12.1': - resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} - '@webassemblyjs/floating-point-hex-parser@1.11.6': - resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} - '@webassemblyjs/helper-api-error@1.11.6': - resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} - '@webassemblyjs/helper-buffer@1.12.1': - resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} - '@webassemblyjs/helper-numbers@1.11.6': - resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} - '@webassemblyjs/helper-wasm-bytecode@1.11.6': - resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} - '@webassemblyjs/helper-wasm-section@1.12.1': - resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} - '@webassemblyjs/ieee754@1.11.6': - resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} - '@webassemblyjs/leb128@1.11.6': - resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} - '@webassemblyjs/utf8@1.11.6': - resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} - '@webassemblyjs/wasm-edit@1.12.1': - resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} - '@webassemblyjs/wasm-gen@1.12.1': - resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - '@webassemblyjs/wasm-opt@1.12.1': - resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - '@webassemblyjs/wasm-parser@1.12.1': - resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - '@webassemblyjs/wast-printer@1.12.1': - resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} '@xmldom/xmldom@0.8.10': resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} @@ -4998,6 +5014,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + adm-zip@0.5.16: resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==} engines: {node: '>=12.0'} @@ -5025,14 +5046,30 @@ packages: resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==} engines: {node: '>=18'} + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: ajv: ^6.9.1 + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -5296,6 +5333,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-crc32@1.0.0: resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} engines: {node: '>=8.0.0'} @@ -5363,6 +5405,9 @@ packages: caniuse-lite@1.0.30001679: resolution: {integrity: sha512-j2YqID/YwpLnKzCmBOS4tlZdWprXm3ZmQLBH9ZBXFOhoxLA46fwyBvx6toCBWBmnuwUY/qB3kEU6gFx8qgCroA==} + caniuse-lite@1.0.30001703: + resolution: {integrity: sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==} + chai@5.2.0: resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} engines: {node: '>=12'} @@ -5454,8 +5499,8 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} - cli-high@0.4.2: - resolution: {integrity: sha512-q/CIxOggmzAw/67QYS4j1bMo72IpC+dAlswZl8xHxp8XvmWS97x3Q30pWNXq8mg0pZLSJwIFWZpUWTfcF119wA==} + cli-high@0.4.3: + resolution: {integrity: sha512-YbwZhmK0fpwVn3bsbYiYdkseXFcGvSVkX+fl0CY73PAz77Uzkr46X3Ifs4V7NgwfvCqGx+6C5zEi8SL8m9lqtg==} hasBin: true cli-highlight@2.1.11: @@ -6046,8 +6091,11 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - effect@3.9.2: - resolution: {integrity: sha512-1sx/v1HTWHTodXfzWxAFg+SCF+ACgpJVruaAMIh/NmDVvrUsf0x9PzpXvkgJUbQ1fMdmKYK//FqxeHSQ+Zxv/Q==} + effect@3.13.10: + resolution: {integrity: sha512-f2n51BJJ25G9rb/C1ClkgsVFXH6YTkCHmd6ebpu6cAkwQxfhnfbkVWKgkn3nyW9YnC9z4K8bGohRYaZ+HyWtLg==} + + electron-to-chromium@1.5.114: + resolution: {integrity: sha512-DFptFef3iktoKlFQK/afbo274/XNWD00Am0xa7M8FZUepHlHT8PEuiNBoRfFHbH1okqN58AlhbJ4QTkcnXorjA==} electron-to-chromium@1.5.55: resolution: {integrity: sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==} @@ -6082,8 +6130,8 @@ packages: resolution: {integrity: sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.17.1: - resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -6373,6 +6421,10 @@ packages: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} + fast-check@3.23.2: + resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} + engines: {node: '>=8.0.0'} + fast-content-type-parse@2.0.1: resolution: {integrity: sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==} @@ -6399,6 +6451,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + fast-xml-parser@4.5.1: resolution: {integrity: sha512-y655CeyUQ+jj7KBbYMc4FG01V8ZQqjN+gDYGJ50RtfsUB8iG9AmwmwoAgeKLJdmueKKMrH1RJ7yXHTSoczdv5w==} hasBin: true @@ -7328,6 +7383,9 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -7735,6 +7793,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@3.3.9: + resolution: {integrity: sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + nanoid@5.0.7: resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} engines: {node: ^18 || >=20} @@ -7893,6 +7956,9 @@ packages: node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + nopt@5.0.0: resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} engines: {node: '>=6'} @@ -8275,6 +8341,9 @@ packages: picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -8539,6 +8608,9 @@ packages: resolution: {integrity: sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==} engines: {node: '>=8'} + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + qs@6.13.1: resolution: {integrity: sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==} engines: {node: '>=0.6'} @@ -8734,8 +8806,8 @@ packages: resolution: {integrity: sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==} engines: {node: '>= 14.16.0'} - recast@0.23.9: - resolution: {integrity: sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==} + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} redis-errors@1.2.0: @@ -8803,6 +8875,10 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -8947,6 +9023,10 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} + schema-utils@4.3.0: + resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + engines: {node: '>= 10.13.0'} + semantic-release@24.2.3: resolution: {integrity: sha512-KRhQG9cUazPavJiJEFIJ3XAMjgfd0fcK3B+T26qOl8L0UG5aZUjeRfREO0KM5InGtYwxqiiytkJrbcYoLDEv0A==} engines: {node: '>=20.8.1'} @@ -9303,8 +9383,8 @@ packages: babel-plugin-macros: optional: true - sugar-high@0.6.1: - resolution: {integrity: sha512-kg1qMW7WwJcueXIlHkChL/p2EWY3gf8rQmP6n5nUq2TWVqatqDTMLvViS9WgAjgyTKH5/3/b8sRwWPOOAo1zMA==} + sugar-high@0.7.5: + resolution: {integrity: sha512-lfGxo0il0Mx4WLdXEt0WsJ8V3QkQWssXnolj5xBurzlGJW07LuwmJWKtS0B2WJ5XWz1439RHngXAmzsnLD0rFA==} sugarss@4.0.1: resolution: {integrity: sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==} @@ -9398,8 +9478,8 @@ packages: resolution: {integrity: sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==} engines: {node: '>=14.16'} - terser-webpack-plugin@5.3.10: - resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + terser-webpack-plugin@5.3.14: + resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -9414,8 +9494,8 @@ packages: uglify-js: optional: true - terser@5.32.0: - resolution: {integrity: sha512-v3Gtw3IzpBJ0ugkxEX8U0W6+TnPKRRCWGh1jC/iM/e3Ki5+qvO1L1EAZ56bZasc64aXHwRHNIQEzm6//i5cemQ==} + terser@5.39.0: + resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} engines: {node: '>=10'} hasBin: true @@ -9841,6 +9921,12 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + update-check@1.5.4: resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==} @@ -10445,6 +10531,10 @@ snapshots: dependencies: '@babel/types': 7.26.0 + '@babel/parser@7.26.9': + dependencies: + '@babel/types': 7.26.9 + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -10487,6 +10577,11 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@babel/types@7.26.9': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@balena/dockerignore@1.0.2': {} '@bcoe/v8-coverage@1.0.2': {} @@ -10499,7 +10594,7 @@ snapshots: '@clack/prompts@0.7.0': dependencies: '@clack/core': 0.3.5 - picocolors: 1.1.0 + picocolors: 1.1.1 sisteransi: 1.0.5 '@clack/prompts@0.8.2': @@ -11236,13 +11331,19 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/set-array@1.2.1': {} '@jridgewell/source-map@0.3.6': dependencies: - '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/sourcemap-codec@1.5.0': {} @@ -11404,15 +11505,15 @@ snapshots: dependencies: '@antfu/ni': 0.21.12 '@axiomhq/js': 1.0.0-rc.3 - '@babel/parser': 7.26.2 + '@babel/parser': 7.26.9 '@babel/types': 7.26.0 '@clack/prompts': 0.7.0 ast-types: 0.14.2 - cli-high: 0.4.2 + cli-high: 0.4.3 diff: 5.2.0 - effect: 3.9.2 + effect: 3.13.10 nanoid: 5.0.7 - recast: 0.23.9 + recast: 0.23.11 xycolors: 0.1.2 '@million/lint@1.0.14(rollup@4.21.3)(webpack-sources@3.2.3)': @@ -11994,6 +12095,8 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} + '@standard-schema/spec@1.0.0': {} + '@swagger-api/apidom-ast@1.0.0-beta.12': dependencies: '@babel/runtime-corejs3': 7.26.9 @@ -13055,14 +13158,14 @@ snapshots: global: 4.4.0 is-function: 1.0.2 - '@vitejs/plugin-react@4.3.4(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0))': + '@vitejs/plugin-react@4.3.4(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0))': dependencies: '@babel/core': 7.26.0 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0) + vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0) transitivePeerDependencies: - supports-color @@ -13080,7 +13183,7 @@ snapshots: std-env: 3.8.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.0.8(@types/node@22.13.10)(@vitest/ui@3.0.8)(jsdom@26.0.0)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0) + vitest: 3.0.8(@types/node@22.13.10)(@vitest/ui@3.0.8)(jsdom@26.0.0)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0) transitivePeerDependencies: - supports-color @@ -13091,13 +13194,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.8(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0))': + '@vitest/mocker@3.0.8(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0))': dependencies: '@vitest/spy': 3.0.8 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0) + vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0) '@vitest/pretty-format@3.0.8': dependencies: @@ -13127,7 +13230,7 @@ snapshots: sirv: 3.0.1 tinyglobby: 0.2.12 tinyrainbow: 2.0.0 - vitest: 3.0.8(@types/node@22.13.10)(@vitest/ui@3.0.8)(jsdom@26.0.0)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0) + vitest: 3.0.8(@types/node@22.13.10)(@vitest/ui@3.0.8)(jsdom@26.0.0)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0) '@vitest/utils@3.0.8': dependencies: @@ -13135,80 +13238,80 @@ snapshots: loupe: 3.1.3 tinyrainbow: 2.0.0 - '@webassemblyjs/ast@1.12.1': + '@webassemblyjs/ast@1.14.1': dependencies: - '@webassemblyjs/helper-numbers': 1.11.6 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/floating-point-hex-parser@1.11.6': {} + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} - '@webassemblyjs/helper-api-error@1.11.6': {} + '@webassemblyjs/helper-api-error@1.13.2': {} - '@webassemblyjs/helper-buffer@1.12.1': {} + '@webassemblyjs/helper-buffer@1.14.1': {} - '@webassemblyjs/helper-numbers@1.11.6': + '@webassemblyjs/helper-numbers@1.13.2': dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.11.6 - '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 '@xtuc/long': 4.2.2 - '@webassemblyjs/helper-wasm-bytecode@1.11.6': {} + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} - '@webassemblyjs/helper-wasm-section@1.12.1': + '@webassemblyjs/helper-wasm-section@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-buffer': 1.12.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/ieee754@1.11.6': + '@webassemblyjs/ieee754@1.13.2': dependencies: '@xtuc/ieee754': 1.2.0 - '@webassemblyjs/leb128@1.11.6': + '@webassemblyjs/leb128@1.13.2': dependencies: '@xtuc/long': 4.2.2 - '@webassemblyjs/utf8@1.11.6': {} + '@webassemblyjs/utf8@1.13.2': {} - '@webassemblyjs/wasm-edit@1.12.1': + '@webassemblyjs/wasm-edit@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-buffer': 1.12.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/helper-wasm-section': 1.12.1 - '@webassemblyjs/wasm-gen': 1.12.1 - '@webassemblyjs/wasm-opt': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - '@webassemblyjs/wast-printer': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 - '@webassemblyjs/wasm-gen@1.12.1': + '@webassemblyjs/wasm-gen@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/ieee754': 1.11.6 - '@webassemblyjs/leb128': 1.11.6 - '@webassemblyjs/utf8': 1.11.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 - '@webassemblyjs/wasm-opt@1.12.1': + '@webassemblyjs/wasm-opt@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-buffer': 1.12.1 - '@webassemblyjs/wasm-gen': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 - '@webassemblyjs/wasm-parser@1.12.1': + '@webassemblyjs/wasm-parser@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/helper-api-error': 1.11.6 - '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - '@webassemblyjs/ieee754': 1.11.6 - '@webassemblyjs/leb128': 1.11.6 - '@webassemblyjs/utf8': 1.11.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 - '@webassemblyjs/wast-printer@1.12.1': + '@webassemblyjs/wast-printer@1.14.1': dependencies: - '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 '@xmldom/xmldom@0.8.10': {} @@ -13240,9 +13343,9 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-attributes@1.9.5(acorn@8.14.0): + acorn-import-attributes@1.9.5(acorn@8.14.1): dependencies: - acorn: 8.14.0 + acorn: 8.14.1 acorn-jsx@5.3.2(acorn@8.14.0): dependencies: @@ -13254,6 +13357,8 @@ snapshots: acorn@8.14.0: {} + acorn@8.14.1: {} + adm-zip@0.5.16: {} aes-decrypter@4.0.2: @@ -13287,10 +13392,19 @@ snapshots: clean-stack: 5.2.0 indent-string: 5.0.0 + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -13298,6 +13412,13 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-align@3.0.1: dependencies: string-width: 4.2.3 @@ -13614,6 +13735,13 @@ snapshots: node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) + browserslist@4.24.4: + dependencies: + caniuse-lite: 1.0.30001703 + electron-to-chromium: 1.5.114 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.4) + buffer-crc32@1.0.0: {} buffer-from@1.1.2: {} @@ -13679,6 +13807,8 @@ snapshots: caniuse-lite@1.0.30001679: {} + caniuse-lite@1.0.30001703: {} + chai@5.2.0: dependencies: assertion-error: 2.0.1 @@ -13770,10 +13900,10 @@ snapshots: dependencies: restore-cursor: 3.1.0 - cli-high@0.4.2: + cli-high@0.4.3: dependencies: '@clack/prompts': 0.7.0 - sugar-high: 0.6.1 + sugar-high: 0.7.5 xycolors: 0.1.2 yargs: 17.7.2 @@ -14302,7 +14432,12 @@ snapshots: eastasianwidth@0.2.0: {} - effect@3.9.2: {} + effect@3.13.10: + dependencies: + '@standard-schema/spec': 1.0.0 + fast-check: 3.23.2 + + electron-to-chromium@1.5.114: {} electron-to-chromium@1.5.55: {} @@ -14351,7 +14486,7 @@ snapshots: - supports-color - utf-8-validate - enhanced-resolve@5.17.1: + enhanced-resolve@5.18.1: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 @@ -14926,6 +15061,10 @@ snapshots: iconv-lite: 0.4.24 tmp: 0.0.33 + fast-check@3.23.2: + dependencies: + pure-rand: 6.1.0 + fast-content-type-parse@2.0.1: {} fast-deep-equal@3.1.3: {} @@ -14954,6 +15093,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-uri@3.0.6: {} + fast-xml-parser@4.5.1: dependencies: strnum: 1.0.5 @@ -15941,6 +16082,8 @@ snapshots: json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} json5@1.0.2: @@ -16327,6 +16470,8 @@ snapshots: nanoid@3.3.7: {} + nanoid@3.3.9: {} + nanoid@5.0.7: {} napi-build-utils@1.0.2: {} @@ -16475,6 +16620,8 @@ snapshots: node-releases@2.0.18: {} + node-releases@2.0.19: {} + nopt@5.0.0: dependencies: abbrev: 1.1.1 @@ -16817,6 +16964,8 @@ snapshots: picocolors@1.1.0: {} + picocolors@1.1.1: {} + picomatch@2.3.1: {} picomatch@4.0.2: {} @@ -16897,7 +17046,7 @@ snapshots: postcss@8.4.47: dependencies: - nanoid: 3.3.7 + nanoid: 3.3.9 picocolors: 1.1.0 source-map-js: 1.2.1 @@ -17144,6 +17293,8 @@ snapshots: dependencies: escape-goat: 2.1.1 + pure-rand@6.1.0: {} + qs@6.13.1: dependencies: side-channel: 1.1.0 @@ -17359,7 +17510,7 @@ snapshots: readdirp@4.0.1: {} - recast@0.23.9: + recast@0.23.11: dependencies: ast-types: 0.16.1 esprima: 4.0.1 @@ -17440,6 +17591,8 @@ snapshots: require-directory@2.1.1: {} + require-from-string@2.0.2: {} + requires-port@1.0.0: {} reselect@5.1.1: {} @@ -17610,6 +17763,13 @@ snapshots: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) + schema-utils@4.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + semantic-release@24.2.3(typescript@5.8.2): dependencies: '@semantic-release/commit-analyzer': 13.0.1(semantic-release@24.2.3(typescript@5.8.2)) @@ -18074,7 +18234,7 @@ snapshots: optionalDependencies: '@babel/core': 7.26.0 - sugar-high@0.6.1: {} + sugar-high@0.7.5: {} sugarss@4.0.1(postcss@8.4.47): dependencies: @@ -18251,19 +18411,19 @@ snapshots: type-fest: 2.19.0 unique-string: 3.0.0 - terser-webpack-plugin@5.3.10(webpack@5.94.0): + terser-webpack-plugin@5.3.14(webpack@5.94.0): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 - schema-utils: 3.3.0 + schema-utils: 4.3.0 serialize-javascript: 6.0.2 - terser: 5.32.0 + terser: 5.39.0 webpack: 5.94.0 - terser@5.32.0: + terser@5.39.0: dependencies: '@jridgewell/source-map': 0.3.6 - acorn: 8.14.0 + acorn: 8.14.1 commander: 2.20.3 source-map-support: 0.5.21 @@ -18699,7 +18859,13 @@ snapshots: dependencies: browserslist: 4.24.2 escalade: 3.2.0 - picocolors: 1.1.0 + picocolors: 1.1.1 + + update-browserslist-db@1.1.3(browserslist@4.24.4): + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 update-check@1.5.4: dependencies: @@ -18843,13 +19009,13 @@ snapshots: dependencies: global: 4.4.0 - vite-node@3.0.8(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0): + vite-node@3.0.8(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0) + vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0) transitivePeerDependencies: - '@types/node' - less @@ -18861,18 +19027,18 @@ snapshots: - supports-color - terser - vite-tsconfig-paths@5.1.4(typescript@5.8.2)(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0)): + vite-tsconfig-paths@5.1.4(typescript@5.8.2)(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0)): dependencies: debug: 4.3.7 globrex: 0.1.2 tsconfck: 3.1.3(typescript@5.8.2) optionalDependencies: - vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0) + vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0) transitivePeerDependencies: - supports-color - typescript - vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0): + vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0): dependencies: esbuild: 0.21.5 postcss: 8.4.47 @@ -18882,12 +19048,12 @@ snapshots: fsevents: 2.3.3 sass: 1.85.1 sugarss: 4.0.1(postcss@8.4.47) - terser: 5.32.0 + terser: 5.39.0 - vitest@3.0.8(@types/node@22.13.10)(@vitest/ui@3.0.8)(jsdom@26.0.0)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0): + vitest@3.0.8(@types/node@22.13.10)(@vitest/ui@3.0.8)(jsdom@26.0.0)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0): dependencies: '@vitest/expect': 3.0.8 - '@vitest/mocker': 3.0.8(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0)) + '@vitest/mocker': 3.0.8(vite@5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0)) '@vitest/pretty-format': 3.0.8 '@vitest/runner': 3.0.8 '@vitest/snapshot': 3.0.8 @@ -18903,8 +19069,8 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0) - vite-node: 3.0.8(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0) + vite: 5.4.5(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0) + vite-node: 3.0.8(@types/node@22.13.10)(sass@1.85.1)(sugarss@4.0.1(postcss@8.4.47))(terser@5.39.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.13.10 @@ -18952,14 +19118,14 @@ snapshots: webpack@5.94.0: dependencies: '@types/estree': 1.0.6 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.14.0 - acorn-import-attributes: 1.9.5(acorn@8.14.0) - browserslist: 4.24.2 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.14.1 + acorn-import-attributes: 1.9.5(acorn@8.14.1) + browserslist: 4.24.4 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.17.1 + enhanced-resolve: 5.18.1 es-module-lexer: 1.6.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -18971,7 +19137,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.94.0) + terser-webpack-plugin: 5.3.14(webpack@5.94.0) watchpack: 2.4.2 webpack-sources: 3.2.3 transitivePeerDependencies: From 8486073f271c69f767d9cc76fdd3f27cf1f9db20 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 17:37:42 +0000 Subject: [PATCH 35/60] fix(deps): update tanstack-query monorepo to ^5.67.3 (#2567) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- apps/nextjs/package.json | 6 ++-- pnpm-lock.yaml | 78 ++++++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index ea1b91a01..68cb96285 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -56,9 +56,9 @@ "@mantine/tiptap": "^7.17.1", "@million/lint": "1.0.14", "@tabler/icons-react": "^3.31.0", - "@tanstack/react-query": "^5.67.2", - "@tanstack/react-query-devtools": "^5.67.2", - "@tanstack/react-query-next-experimental": "^5.67.2", + "@tanstack/react-query": "^5.67.3", + "@tanstack/react-query-devtools": "^5.67.3", + "@tanstack/react-query-next-experimental": "^5.67.3", "@trpc/client": "next", "@trpc/next": "next", "@trpc/react-query": "next", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a2261e215..ebb03acc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -206,23 +206,23 @@ importers: specifier: ^3.31.0 version: 3.31.0(react@19.0.0) '@tanstack/react-query': - specifier: ^5.67.2 - version: 5.67.2(react@19.0.0) + specifier: ^5.67.3 + version: 5.67.3(react@19.0.0) '@tanstack/react-query-devtools': - specifier: ^5.67.2 - version: 5.67.2(@tanstack/react-query@5.67.2(react@19.0.0))(react@19.0.0) + specifier: ^5.67.3 + version: 5.67.3(@tanstack/react-query@5.67.3(react@19.0.0))(react@19.0.0) '@tanstack/react-query-next-experimental': - specifier: ^5.67.2 - version: 5.67.2(@tanstack/react-query@5.67.2(react@19.0.0))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0) + specifier: ^5.67.3 + version: 5.67.3(@tanstack/react-query@5.67.3(react@19.0.0))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0) '@trpc/client': specifier: next version: 11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2) '@trpc/next': specifier: next - version: 11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/react-query@11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) + version: 11.0.0-rc.828(@tanstack/react-query@5.67.3(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/react-query@11.0.0-rc.828(@tanstack/react-query@5.67.3(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) '@trpc/react-query': specifier: next - version: 11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) + version: 11.0.0-rc.828(@tanstack/react-query@5.67.3(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) '@trpc/server': specifier: next version: 11.0.0-rc.828(typescript@5.8.2) @@ -586,7 +586,7 @@ importers: version: 11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2) '@trpc/react-query': specifier: next - version: 11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) + version: 11.0.0-rc.828(@tanstack/react-query@5.67.3(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) '@trpc/server': specifier: next version: 11.0.0-rc.828(typescript@5.8.2) @@ -4283,27 +4283,27 @@ packages: resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==} engines: {node: '>=12'} - '@tanstack/query-core@5.67.2': - resolution: {integrity: sha512-+iaFJ/pt8TaApCk6LuZ0WHS/ECVfTzrxDOEL9HH9Dayyb5OVuomLzDXeSaI2GlGT/8HN7bDGiRXDts3LV+u6ww==} + '@tanstack/query-core@5.67.3': + resolution: {integrity: sha512-pq76ObpjcaspAW4OmCbpXLF6BCZP2Zr/J5ztnyizXhSlNe7fIUp0QKZsd0JMkw9aDa+vxDX/OY7N+hjNY/dCGg==} '@tanstack/query-devtools@5.67.2': resolution: {integrity: sha512-O4QXFFd7xqp6EX7sdvc9tsVO8nm4lpWBqwpgjpVLW5g7IeOY6VnS/xvs/YzbRhBVkKTMaJMOUGU7NhSX+YGoNg==} - '@tanstack/react-query-devtools@5.67.2': - resolution: {integrity: sha512-cmj2DxBc+/9btQ66n5xI8wTtAma2BLVa403K7zIYiguzJ/kV201jnGensYqJeu1Rd8uRMLLRM74jLVMLDWNRJA==} + '@tanstack/react-query-devtools@5.67.3': + resolution: {integrity: sha512-+PM2UnCyXAQozXB32cnawx38wwnaHPTtFAhX1V5QmHy/FL1u9k7nd8nxn2+GTwf15SGbUaGfxA/vq/9EARUEIQ==} peerDependencies: - '@tanstack/react-query': ^5.67.2 + '@tanstack/react-query': ^5.67.3 react: ^18 || ^19 - '@tanstack/react-query-next-experimental@5.67.2': - resolution: {integrity: sha512-KTYjhfx1BblTMOKQhmzdSMCkJdl8twtuDqaNeKR1KwU8qqsypXyk5lqfZ3bX5XtGOfAfrtINrVNACmE7vopDdw==} + '@tanstack/react-query-next-experimental@5.67.3': + resolution: {integrity: sha512-Zk6TDJ5bNGFCYzwz5S+gIqli3v9viyty86hjkWXR+rc+LnDL7sorvZF+JcieUvNllWkBIFONUHdblzRX7atEeQ==} peerDependencies: - '@tanstack/react-query': ^5.67.2 + '@tanstack/react-query': ^5.67.3 next: ^13 || ^14 || ^15 react: ^18 || ^19 - '@tanstack/react-query@5.67.2': - resolution: {integrity: sha512-6Sa+BVNJWhAV4QHvIqM73norNeGRWGC3ftN0Ix87cmMvI215I1wyJ44KUTt/9a0V9YimfGcg25AITaYVel71Og==} + '@tanstack/react-query@5.67.3': + resolution: {integrity: sha512-u/n2HsQeH1vpZIOzB/w2lqKlXUDUKo6BxTdGXSMvNzIq5MHYFckRMVuFABp+QB7RN8LFXWV6X1/oSkuDq+MPIA==} peerDependencies: react: ^18 || ^19 @@ -10501,7 +10501,7 @@ snapshots: '@babel/helper-module-imports@7.25.9': dependencies: '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 + '@babel/types': 7.26.9 transitivePeerDependencies: - supports-color @@ -10525,7 +10525,7 @@ snapshots: '@babel/helpers@7.26.0': dependencies: '@babel/template': 7.25.9 - '@babel/types': 7.26.0 + '@babel/types': 7.26.9 '@babel/parser@7.26.2': dependencies: @@ -10557,8 +10557,8 @@ snapshots: '@babel/template@7.25.9': dependencies: '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 '@babel/traverse@7.25.9': dependencies: @@ -12483,25 +12483,25 @@ snapshots: dependencies: remove-accents: 0.5.0 - '@tanstack/query-core@5.67.2': {} + '@tanstack/query-core@5.67.3': {} '@tanstack/query-devtools@5.67.2': {} - '@tanstack/react-query-devtools@5.67.2(@tanstack/react-query@5.67.2(react@19.0.0))(react@19.0.0)': + '@tanstack/react-query-devtools@5.67.3(@tanstack/react-query@5.67.3(react@19.0.0))(react@19.0.0)': dependencies: '@tanstack/query-devtools': 5.67.2 - '@tanstack/react-query': 5.67.2(react@19.0.0) + '@tanstack/react-query': 5.67.3(react@19.0.0) react: 19.0.0 - '@tanstack/react-query-next-experimental@5.67.2(@tanstack/react-query@5.67.2(react@19.0.0))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)': + '@tanstack/react-query-next-experimental@5.67.3(@tanstack/react-query@5.67.3(react@19.0.0))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)': dependencies: - '@tanstack/react-query': 5.67.2(react@19.0.0) + '@tanstack/react-query': 5.67.3(react@19.0.0) next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 - '@tanstack/react-query@5.67.2(react@19.0.0)': + '@tanstack/react-query@5.67.3(react@19.0.0)': dependencies: - '@tanstack/query-core': 5.67.2 + '@tanstack/query-core': 5.67.3 react: 19.0.0 '@tanstack/react-table@8.20.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': @@ -12748,7 +12748,7 @@ snapshots: '@trpc/server': 11.0.0-rc.828(typescript@5.8.2) typescript: 5.8.2 - '@trpc/next@11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/react-query@11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2)': + '@trpc/next@11.0.0-rc.828(@tanstack/react-query@5.67.3(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/react-query@11.0.0-rc.828(@tanstack/react-query@5.67.3(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2)': dependencies: '@trpc/client': 11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2) '@trpc/server': 11.0.0-rc.828(typescript@5.8.2) @@ -12757,12 +12757,12 @@ snapshots: react-dom: 19.0.0(react@19.0.0) typescript: 5.8.2 optionalDependencies: - '@tanstack/react-query': 5.67.2(react@19.0.0) - '@trpc/react-query': 11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) + '@tanstack/react-query': 5.67.3(react@19.0.0) + '@trpc/react-query': 11.0.0-rc.828(@tanstack/react-query@5.67.3(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2) - '@trpc/react-query@11.0.0-rc.828(@tanstack/react-query@5.67.2(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2)': + '@trpc/react-query@11.0.0-rc.828(@tanstack/react-query@5.67.3(react@19.0.0))(@trpc/client@11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2))(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.8.2)': dependencies: - '@tanstack/react-query': 5.67.2(react@19.0.0) + '@tanstack/react-query': 5.67.3(react@19.0.0) '@trpc/client': 11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2) '@trpc/server': 11.0.0-rc.828(typescript@5.8.2) react: 19.0.0 @@ -12837,16 +12837,16 @@ snapshots: '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.26.0 + '@babel/types': 7.26.9 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.26.0 + '@babel/types': 7.26.9 '@types/bcrypt@5.0.2': dependencies: From ba3f1e9eaab8a0b2fe779bc9393fce91c461defd Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Tue, 11 Mar 2025 18:42:18 +0100 Subject: [PATCH 36/60] chore(docs): update docs-sitemap --- .../src/docs/homarr-docs-sitemap.ts | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/packages/definitions/src/docs/homarr-docs-sitemap.ts b/packages/definitions/src/docs/homarr-docs-sitemap.ts index f05c9c63f..4d3228324 100644 --- a/packages/definitions/src/docs/homarr-docs-sitemap.ts +++ b/packages/definitions/src/docs/homarr-docs-sitemap.ts @@ -37,6 +37,178 @@ export type HomarrDocumentationPath = | "/blog/tags/version" | "/blog/translations" | "/search" + | "/docs/next/tags" + | "/docs/next/tags/active-directory" + | "/docs/next/tags/ad-guard" + | "/docs/next/tags/ad-guard-home" + | "/docs/next/tags/administration" + | "/docs/next/tags/advanced" + | "/docs/next/tags/analytics" + | "/docs/next/tags/api" + | "/docs/next/tags/apps" + | "/docs/next/tags/banner" + | "/docs/next/tags/blocking" + | "/docs/next/tags/boards" + | "/docs/next/tags/bookmark" + | "/docs/next/tags/bookmarks" + | "/docs/next/tags/caddy" + | "/docs/next/tags/certificates" + | "/docs/next/tags/checklist" + | "/docs/next/tags/code" + | "/docs/next/tags/community" + | "/docs/next/tags/configuration" + | "/docs/next/tags/connections" + | "/docs/next/tags/customization" + | "/docs/next/tags/data-sources" + | "/docs/next/tags/database" + | "/docs/next/tags/developer" + | "/docs/next/tags/development" + | "/docs/next/tags/dns" + | "/docs/next/tags/docker" + | "/docs/next/tags/donation" + | "/docs/next/tags/edit-mode" + | "/docs/next/tags/env" + | "/docs/next/tags/environment-variables" + | "/docs/next/tags/feeds" + | "/docs/next/tags/getting-started" + | "/docs/next/tags/google" + | "/docs/next/tags/grafana" + | "/docs/next/tags/groups" + | "/docs/next/tags/hardware" + | "/docs/next/tags/health" + | "/docs/next/tags/help" + | "/docs/next/tags/icon-picker" + | "/docs/next/tags/icon-repositories" + | "/docs/next/tags/icons" + | "/docs/next/tags/iframe" + | "/docs/next/tags/images" + | "/docs/next/tags/installation" + | "/docs/next/tags/integrade" + | "/docs/next/tags/integration" + | "/docs/next/tags/integrations" + | "/docs/next/tags/interface" + | "/docs/next/tags/jellyserr" + | "/docs/next/tags/layout" + | "/docs/next/tags/ldap" + | "/docs/next/tags/links" + | "/docs/next/tags/lists" + | "/docs/next/tags/management" + | "/docs/next/tags/media" + | "/docs/next/tags/minecraft" + | "/docs/next/tags/monitoring" + | "/docs/next/tags/news" + | "/docs/next/tags/notebook" + | "/docs/next/tags/notes" + | "/docs/next/tags/oidc" + | "/docs/next/tags/open-collective" + | "/docs/next/tags/open-media-vault" + | "/docs/next/tags/overseerr" + | "/docs/next/tags/permissions" + | "/docs/next/tags/pgid" + | "/docs/next/tags/pi-hole" + | "/docs/next/tags/ping" + | "/docs/next/tags/programming" + | "/docs/next/tags/proxmox" + | "/docs/next/tags/proxy" + | "/docs/next/tags/puid" + | "/docs/next/tags/responsive" + | "/docs/next/tags/roles" + | "/docs/next/tags/rss" + | "/docs/next/tags/search" + | "/docs/next/tags/search-engines" + | "/docs/next/tags/security" + | "/docs/next/tags/self-signed" + | "/docs/next/tags/seo" + | "/docs/next/tags/server" + | "/docs/next/tags/settings" + | "/docs/next/tags/sinkhole" + | "/docs/next/tags/sso" + | "/docs/next/tags/system" + | "/docs/next/tags/table" + | "/docs/next/tags/technical-documentation" + | "/docs/next/tags/text" + | "/docs/next/tags/torrent" + | "/docs/next/tags/traefik" + | "/docs/next/tags/translations" + | "/docs/next/tags/unraid" + | "/docs/next/tags/uploads" + | "/docs/next/tags/usenet" + | "/docs/next/tags/users" + | "/docs/next/tags/variables" + | "/docs/next/tags/widgets" + | "/docs/next/advanced/command-line" + | "/docs/next/advanced/command-line/fix-usernames" + | "/docs/next/advanced/command-line/password-recovery" + | "/docs/next/advanced/development/getting-started" + | "/docs/next/advanced/development/kubernetes" + | "/docs/next/advanced/environment-variables" + | "/docs/next/advanced/icons" + | "/docs/next/advanced/keyboard-shortcuts" + | "/docs/next/advanced/proxy" + | "/docs/next/advanced/running-as-different-user" + | "/docs/next/advanced/single-sign-on" + | "/docs/next/category/advanced" + | "/docs/next/category/community" + | "/docs/next/category/developer-guides" + | "/docs/next/category/getting-started" + | "/docs/next/category/installation" + | "/docs/next/category/installation-1" + | "/docs/next/category/integrations" + | "/docs/next/category/management" + | "/docs/next/category/widgets" + | "/docs/next/community/donate" + | "/docs/next/community/faq" + | "/docs/next/community/get-in-touch" + | "/docs/next/community/license" + | "/docs/next/community/translations" + | "/docs/next/getting-started" + | "/docs/next/getting-started/after-the-installation" + | "/docs/next/getting-started/glossary" + | "/docs/next/getting-started/installation/docker" + | "/docs/next/getting-started/installation/easy-panel" + | "/docs/next/getting-started/installation/helm" + | "/docs/next/getting-started/installation/home-assistant" + | "/docs/next/getting-started/installation/portainer" + | "/docs/next/getting-started/installation/qnap" + | "/docs/next/getting-started/installation/railway" + | "/docs/next/getting-started/installation/saltbox" + | "/docs/next/getting-started/installation/source" + | "/docs/next/getting-started/installation/synology" + | "/docs/next/getting-started/installation/unraid" + | "/docs/next/integrations/containers" + | "/docs/next/integrations/dns" + | "/docs/next/integrations/hardware" + | "/docs/next/integrations/kubernetes" + | "/docs/next/integrations/media-requester" + | "/docs/next/integrations/media-server" + | "/docs/next/integrations/servarr" + | "/docs/next/integrations/torrent" + | "/docs/next/integrations/usenet" + | "/docs/next/management/api" + | "/docs/next/management/apps" + | "/docs/next/management/boards" + | "/docs/next/management/certificates" + | "/docs/next/management/integrations" + | "/docs/next/management/media" + | "/docs/next/management/search-engines" + | "/docs/next/management/settings" + | "/docs/next/management/users" + | "/docs/next/widgets/bookmarks" + | "/docs/next/widgets/calendar" + | "/docs/next/widgets/clock" + | "/docs/next/widgets/dns-hole" + | "/docs/next/widgets/downloads" + | "/docs/next/widgets/health-monitoring" + | "/docs/next/widgets/home-assistant" + | "/docs/next/widgets/iframe" + | "/docs/next/widgets/indexer-manager" + | "/docs/next/widgets/media-requests" + | "/docs/next/widgets/media-server" + | "/docs/next/widgets/minecraft-server-status" + | "/docs/next/widgets/notebook" + | "/docs/next/widgets/rss" + | "/docs/next/widgets/video" + | "/docs/next/widgets/weather" | "/docs/tags" | "/docs/tags/active-directory" | "/docs/tags/ad-guard" From 2135f9980b4eb9e682fd19d2a1536f50201a1bee Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 19:53:42 +0000 Subject: [PATCH 37/60] fix(deps): update dependency zod-form-data to ^2.0.6 (#2572) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- packages/old-import/package.json | 2 +- packages/validation/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/old-import/package.json b/packages/old-import/package.json index 1e0ca26da..e9b6d7864 100644 --- a/packages/old-import/package.json +++ b/packages/old-import/package.json @@ -45,7 +45,7 @@ "react-dom": "19.0.0", "superjson": "2.2.2", "zod": "^3.24.2", - "zod-form-data": "^2.0.5" + "zod-form-data": "^2.0.6" }, "devDependencies": { "@homarr/eslint-config": "workspace:^0.2.0", diff --git a/packages/validation/package.json b/packages/validation/package.json index c7e438637..a5b842057 100644 --- a/packages/validation/package.json +++ b/packages/validation/package.json @@ -26,7 +26,7 @@ "@homarr/definitions": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0", "zod": "^3.24.2", - "zod-form-data": "^2.0.5" + "zod-form-data": "^2.0.6" }, "devDependencies": { "@homarr/eslint-config": "workspace:^0.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ebb03acc7..6104c1350 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1564,8 +1564,8 @@ importers: specifier: ^3.24.2 version: 3.24.2 zod-form-data: - specifier: ^2.0.5 - version: 2.0.5(zod@3.24.2) + specifier: ^2.0.6 + version: 2.0.6(zod@3.24.2) devDependencies: '@homarr/eslint-config': specifier: workspace:^0.2.0 @@ -1991,8 +1991,8 @@ importers: specifier: ^3.24.2 version: 3.24.2 zod-form-data: - specifier: ^2.0.5 - version: 2.0.5(zod@3.24.2) + specifier: ^2.0.6 + version: 2.0.6(zod@3.24.2) devDependencies: '@homarr/eslint-config': specifier: workspace:^0.2.0 @@ -10392,8 +10392,8 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} - zod-form-data@2.0.5: - resolution: {integrity: sha512-T7dV6lTBCwkd8PyvJVCnjXKpgXomU8gEm/TcvEZY7qNdRhIo9T17HrdlHIK68PzTAYaV2HxR9rgwpTSWv0L+QQ==} + zod-form-data@2.0.6: + resolution: {integrity: sha512-D+4A2q/w7BEO3h4o7uB8FFrAjnmAlNjqh3vIwVadGqFg3jHUIFsr/kxP+iSVp2/fIEtbLVec+2yDDHw2xSWyQA==} peerDependencies: zod: '>= 3.11.0' @@ -19372,7 +19372,7 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.5.2 - zod-form-data@2.0.5(zod@3.24.2): + zod-form-data@2.0.6(zod@3.24.2): dependencies: zod: 3.24.2 From 6c9fbd6c09b481b24dad849cc8d367d0c5591cdb Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 20:36:28 +0000 Subject: [PATCH 38/60] fix(deps): update dependency zod-form-data to ^2.0.7 (#2573) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- packages/old-import/package.json | 2 +- packages/validation/package.json | 2 +- pnpm-lock.yaml | 20 +++++++++++++------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/old-import/package.json b/packages/old-import/package.json index e9b6d7864..982706d76 100644 --- a/packages/old-import/package.json +++ b/packages/old-import/package.json @@ -45,7 +45,7 @@ "react-dom": "19.0.0", "superjson": "2.2.2", "zod": "^3.24.2", - "zod-form-data": "^2.0.6" + "zod-form-data": "^2.0.7" }, "devDependencies": { "@homarr/eslint-config": "workspace:^0.2.0", diff --git a/packages/validation/package.json b/packages/validation/package.json index a5b842057..5cf9b4134 100644 --- a/packages/validation/package.json +++ b/packages/validation/package.json @@ -26,7 +26,7 @@ "@homarr/definitions": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0", "zod": "^3.24.2", - "zod-form-data": "^2.0.6" + "zod-form-data": "^2.0.7" }, "devDependencies": { "@homarr/eslint-config": "workspace:^0.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6104c1350..e205ba162 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1564,8 +1564,8 @@ importers: specifier: ^3.24.2 version: 3.24.2 zod-form-data: - specifier: ^2.0.6 - version: 2.0.6(zod@3.24.2) + specifier: ^2.0.7 + version: 2.0.7(zod@3.24.2) devDependencies: '@homarr/eslint-config': specifier: workspace:^0.2.0 @@ -1991,8 +1991,8 @@ importers: specifier: ^3.24.2 version: 3.24.2 zod-form-data: - specifier: ^2.0.6 - version: 2.0.6(zod@3.24.2) + specifier: ^2.0.7 + version: 2.0.7(zod@3.24.2) devDependencies: '@homarr/eslint-config': specifier: workspace:^0.2.0 @@ -4075,6 +4075,9 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@rvf/set-get@7.0.1': + resolution: {integrity: sha512-GkTSn9K1GrTYoTUqlUs36k6nJnzjQaFBTTEIqUYmzBcsGsoJM8xG7EAx2WLHWAA4QzFjcwWUSHQ3vM3Fbw50Tg==} + '@scarf/scarf@1.4.0': resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} @@ -10392,8 +10395,8 @@ packages: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} - zod-form-data@2.0.6: - resolution: {integrity: sha512-D+4A2q/w7BEO3h4o7uB8FFrAjnmAlNjqh3vIwVadGqFg3jHUIFsr/kxP+iSVp2/fIEtbLVec+2yDDHw2xSWyQA==} + zod-form-data@2.0.7: + resolution: {integrity: sha512-O27uzKMx7qc7z51KXER326Fp966jqHGvZX3i18CbvElF/QqVsQQN6Q7BnzepkzeBzTJnU3golibVSagf4dp7RQ==} peerDependencies: zod: '>= 3.11.0' @@ -11988,6 +11991,8 @@ snapshots: '@rtsao/scc@1.1.0': {} + '@rvf/set-get@7.0.1': {} + '@scarf/scarf@1.4.0': {} '@sec-ant/readable-stream@0.4.1': {} @@ -19372,8 +19377,9 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.5.2 - zod-form-data@2.0.6(zod@3.24.2): + zod-form-data@2.0.7(zod@3.24.2): dependencies: + '@rvf/set-get': 7.0.1 zod: 3.24.2 zod-openapi@2.19.0(zod@3.24.2): From e774b06fc2173eb094e2b698a93624a54cd37dff Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Tue, 11 Mar 2025 22:13:03 +0100 Subject: [PATCH 39/60] fix(dns-hole-summary): remove inconsistency for position of text (#2568) --- packages/widgets/src/dns-hole/summary/component.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/widgets/src/dns-hole/summary/component.tsx b/packages/widgets/src/dns-hole/summary/component.tsx index 32504a70d..b0636ff44 100644 --- a/packages/widgets/src/dns-hole/summary/component.tsx +++ b/packages/widgets/src/dns-hole/summary/component.tsx @@ -152,6 +152,7 @@ interface StatCardProps { const StatCard = ({ item, data, usePiHoleColors, t }: StatCardProps) => { const { ref, height, width } = useElementSize(); const isLong = width > height + 20; + const canStackText = height > 32; const hideLabel = (height <= 32 && width <= 256) || (height <= 64 && width <= 92); const tooltip = item.tooltip?.(data, t); const board = useRequiredBoard(); @@ -182,7 +183,7 @@ const StatCard = ({ item, data, usePiHoleColors, t }: StatCardProps) => { className="summary-card-texts" justify="center" align="center" - direction={isLong ? "row" : "column"} + direction={isLong && !canStackText ? "row" : "column"} style={{ flex: isLong ? 1 : undefined, }} From fbbfe9af293961afcb686f3e7a559b67b37f6743 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Tue, 11 Mar 2025 22:13:17 +0100 Subject: [PATCH 40/60] fix(calendar): dropdown spans over whole screen (#2569) --- packages/widgets/src/calendar/calender-day.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/widgets/src/calendar/calender-day.tsx b/packages/widgets/src/calendar/calender-day.tsx index 597719a35..122601157 100644 --- a/packages/widgets/src/calendar/calender-day.tsx +++ b/packages/widgets/src/calendar/calender-day.tsx @@ -64,7 +64,7 @@ export const CalendarDay = ({ date, events, disabled, rootHeight, rootWidth }: C {/* Popover has some offset on the left side, padding is removed because of scrollarea paddings */} - + From a53e7aaee5207ab563b6e0144f3154db917f7da1 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Tue, 11 Mar 2025 22:14:35 +0100 Subject: [PATCH 41/60] fix(notebook): css for checkboxes not working (#2570) --- packages/widgets/src/notebook/component.tsx | 2 - packages/widgets/src/notebook/notebook.css | 68 +++++++++++++++++++++ packages/widgets/src/notebook/notebook.tsx | 2 + 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 packages/widgets/src/notebook/notebook.css diff --git a/packages/widgets/src/notebook/component.tsx b/packages/widgets/src/notebook/component.tsx index a9847eceb..84f3b1085 100644 --- a/packages/widgets/src/notebook/component.tsx +++ b/packages/widgets/src/notebook/component.tsx @@ -2,8 +2,6 @@ import dynamic from "next/dynamic"; -import "@mantine/tiptap/styles.css"; - import type { WidgetComponentProps } from "../definition"; const Notebook = dynamic(() => import("./notebook").then((module) => module.Notebook), { diff --git a/packages/widgets/src/notebook/notebook.css b/packages/widgets/src/notebook/notebook.css new file mode 100644 index 000000000..83919bf39 --- /dev/null +++ b/packages/widgets/src/notebook/notebook.css @@ -0,0 +1,68 @@ +.tiptap hr { + border-top-style: double; +} + +.tiptap ul[data-type="taskList"] { + padding-left: 17px; +} + +.tiptap ul[data-type="taskList"] li { + list-style-type: none; + display: flex; + gap: 8px; +} + +.tiptap img { + max-width: 100%; +} + +.tiptap img.ProseMirror-selectednode { + outline: 3px solid rgba(0, 65, 198, 0.8); +} + +.tiptap table { + border-collapse: collapse; + margin: 0; + overflow: hidden; + table-layout: fixed; + width: 100%; +} + +.tiptap table td { + border-color: var(--mantine-color-gray-5) !important; + border-width: 1px !important; + border-style: solid !important; + box-sizing: border-box; + min-width: 1em; + padding: 3px 5px; + position: relative; + vertical-align: top; +} + +.tiptap table td > * { + margin-bottom: 0; +} + +.tiptap table .selectedCell:after { + background: hsla(0, 0%, 78%, 0.4); + content: ""; + left: 0; + right: 0; + top: 0; + bottom: 0; + pointer-events: none; + position: absolute; + z-index: 2; +} + +.tiptap table p { + margin: 0; +} + +.tiptap[contenteditable="true"].resize-cursor { + cursor: ew-resize; +} + +.tiptap[contenteditable="false"].resize-cursor { + pointer-events: none; +} diff --git a/packages/widgets/src/notebook/notebook.tsx b/packages/widgets/src/notebook/notebook.tsx index 741e4ac28..257dcfc50 100644 --- a/packages/widgets/src/notebook/notebook.tsx +++ b/packages/widgets/src/notebook/notebook.tsx @@ -65,6 +65,8 @@ import type { TablerIcon } from "@homarr/ui"; import type { WidgetComponentProps } from "../definition"; +import "./notebook.css"; + const iconProps = { size: 30, stroke: 1.5, From 268daee4a6e90052a19b9d2426c2cf8b2c8a0c00 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Tue, 11 Mar 2025 22:15:01 +0100 Subject: [PATCH 42/60] fix(system-health): improve responsive styles (#2566) --- .../cluster/cluster-health.tsx | 51 +-- .../cluster/resource-accordion-item.tsx | 10 +- .../cluster/resource-table.tsx | 45 ++- .../src/health-monitoring/component.tsx | 20 +- .../src/health-monitoring/rings/cpu-ring.tsx | 49 ++- .../health-monitoring/rings/cpu-temp-ring.tsx | 58 ++-- .../health-monitoring/rings/memory-ring.tsx | 51 ++- .../src/health-monitoring/system-health.tsx | 290 +++++++++--------- 8 files changed, 297 insertions(+), 277 deletions(-) diff --git a/packages/widgets/src/health-monitoring/cluster/cluster-health.tsx b/packages/widgets/src/health-monitoring/cluster/cluster-health.tsx index c2abec2b8..db9718990 100644 --- a/packages/widgets/src/health-monitoring/cluster/cluster-health.tsx +++ b/packages/widgets/src/health-monitoring/cluster/cluster-health.tsx @@ -31,6 +31,7 @@ const running = (total: number, current: Resource) => { export const ClusterHealthMonitoring = ({ integrationId, options, + width, }: WidgetComponentProps<"healthMonitoring"> & { integrationId: string }) => { const t = useI18n(); const [healthData] = clientApi.widget.healthMonitoring.getClusterHealthStatus.useSuspenseQuery( @@ -72,14 +73,15 @@ export const ClusterHealthMonitoring = ({ const cpuPercent = maxCpu ? (usedCpu / maxCpu) * 100 : 0; const memPercent = maxMem ? (usedMem / maxMem) * 100 : 0; + const isTiny = width < 256; return ( - - - + + + {formatUptime(uptime, t)} - + - + - + - + - + @@ -140,45 +146,50 @@ export const ClusterHealthMonitoring = ({ interface SummaryHeaderProps { cpu: number; memory: number; + isTiny: boolean; } -const SummaryHeader = ({ cpu, memory }: SummaryHeaderProps) => { +const SummaryHeader = ({ cpu, memory, isTiny }: SummaryHeaderProps) => { const t = useI18n(); return (
- + - +
} sections={[{ value: cpu, color: cpu > 75 ? "orange" : "green" }]} /> - {t("widget.healthMonitoring.cluster.summary.cpu")} - {cpu.toFixed(1)}% + + {t("widget.healthMonitoring.cluster.summary.cpu")} + + {cpu.toFixed(1)}% - +
} sections={[{ value: memory, color: memory > 75 ? "orange" : "green" }]} /> - {t("widget.healthMonitoring.cluster.summary.memory")} - {memory.toFixed(1)}% + + {t("widget.healthMonitoring.cluster.summary.memory")} + + {memory.toFixed(1)}%
diff --git a/packages/widgets/src/health-monitoring/cluster/resource-accordion-item.tsx b/packages/widgets/src/health-monitoring/cluster/resource-accordion-item.tsx index 717822e60..5c6aa9dc4 100644 --- a/packages/widgets/src/health-monitoring/cluster/resource-accordion-item.tsx +++ b/packages/widgets/src/health-monitoring/cluster/resource-accordion-item.tsx @@ -13,6 +13,7 @@ interface ResourceAccordionItemProps { activeCount: number; totalCount: number; }; + isTiny: boolean; } export const ResourceAccordionItem = ({ @@ -21,13 +22,14 @@ export const ResourceAccordionItem = ({ icon: Icon, badge, children, + isTiny, }: PropsWithChildren) => { return ( - }> - - {title} - + }> + + {title} + {badge.activeCount} / {badge.totalCount} diff --git a/packages/widgets/src/health-monitoring/cluster/resource-table.tsx b/packages/widgets/src/health-monitoring/cluster/resource-table.tsx index bc8226f37..8f3637f19 100644 --- a/packages/widgets/src/health-monitoring/cluster/resource-table.tsx +++ b/packages/widgets/src/health-monitoring/cluster/resource-table.tsx @@ -1,4 +1,4 @@ -import { Group, Indicator, Popover, Table, Text } from "@mantine/core"; +import { Group, Indicator, Popover, Table, TableTbody, TableThead, TableTr, Text } from "@mantine/core"; import type { Resource } from "@homarr/integrations/types"; import { useI18n } from "@homarr/translation/client"; @@ -8,36 +8,47 @@ import { ResourcePopover } from "./resource-popover"; interface ResourceTableProps { type: Resource["type"]; data: Resource[]; + isTiny: boolean; } -export const ResourceTable = ({ type, data }: ResourceTableProps) => { +export const ResourceTable = ({ type, data, isTiny }: ResourceTableProps) => { const t = useI18n(); return ( - - - {t("widget.healthMonitoring.cluster.table.header.name")} + + + + {t("widget.healthMonitoring.cluster.table.header.name")} + {type !== "storage" ? ( - {t("widget.healthMonitoring.cluster.table.header.cpu")} + + {t("widget.healthMonitoring.cluster.table.header.cpu")} + ) : null} {type !== "storage" ? ( - {t("widget.healthMonitoring.cluster.table.header.memory")} + + {t("widget.healthMonitoring.cluster.table.header.memory")} + ) : null} {type === "storage" ? ( - {t("widget.healthMonitoring.cluster.table.header.node")} + + {t("widget.healthMonitoring.cluster.table.header.node")} + ) : null} - - - + + + {data.map((item) => { return ( - + {item.type === "storage" ? ( @@ -50,12 +61,12 @@ export const ResourceTable = ({ type, data }: ResourceTableProps) => { )} - + ); })} - +
- - - {item.name} + + + + {item.name} +
); }; diff --git a/packages/widgets/src/health-monitoring/component.tsx b/packages/widgets/src/health-monitoring/component.tsx index 837e04504..d1ee3dd28 100644 --- a/packages/widgets/src/health-monitoring/component.tsx +++ b/packages/widgets/src/health-monitoring/component.tsx @@ -31,30 +31,20 @@ export default function HealthMonitoringWidget(props: WidgetComponentProps<"heal } return ( - + - + {t("widget.healthMonitoring.tab.system")} - + {t("widget.healthMonitoring.tab.cluster")} - + - + diff --git a/packages/widgets/src/health-monitoring/rings/cpu-ring.tsx b/packages/widgets/src/health-monitoring/rings/cpu-ring.tsx index 0069c6d96..ff1746eea 100644 --- a/packages/widgets/src/health-monitoring/rings/cpu-ring.tsx +++ b/packages/widgets/src/health-monitoring/rings/cpu-ring.tsx @@ -1,33 +1,30 @@ -import { Box, Center, RingProgress, Text } from "@mantine/core"; -import { useElementSize } from "@mantine/hooks"; +import { Center, RingProgress, Text } from "@mantine/core"; import { IconCpu } from "@tabler/icons-react"; import { progressColor } from "../system-health"; -export const CpuRing = ({ cpuUtilization }: { cpuUtilization: number }) => { - const { width, ref } = useElementSize(); - const fallbackWidth = width || 1; // See https://github.com/homarr-labs/homarr/issues/2196 - +export const CpuRing = ({ cpuUtilization, isTiny }: { cpuUtilization: number; isTiny: boolean }) => { return ( - - - {`${cpuUtilization.toFixed(2)}%`} - -
- } - sections={[ - { - value: Number(cpuUtilization.toFixed(2)), - color: progressColor(Number(cpuUtilization.toFixed(2))), - }, - ]} - /> - + + {`${cpuUtilization.toFixed(2)}%`} + + + } + sections={[ + { + value: Number(cpuUtilization.toFixed(2)), + color: progressColor(Number(cpuUtilization.toFixed(2))), + }, + ]} + /> ); }; diff --git a/packages/widgets/src/health-monitoring/rings/cpu-temp-ring.tsx b/packages/widgets/src/health-monitoring/rings/cpu-temp-ring.tsx index a70f26a90..2c6a2b254 100644 --- a/packages/widgets/src/health-monitoring/rings/cpu-temp-ring.tsx +++ b/packages/widgets/src/health-monitoring/rings/cpu-temp-ring.tsx @@ -1,39 +1,41 @@ -import { Box, Center, RingProgress, Text } from "@mantine/core"; -import { useElementSize } from "@mantine/hooks"; +import { Center, RingProgress, Text } from "@mantine/core"; import { IconCpu } from "@tabler/icons-react"; import { progressColor } from "../system-health"; -export const CpuTempRing = ({ fahrenheit, cpuTemp }: { fahrenheit: boolean; cpuTemp: number | undefined }) => { - const { width, ref } = useElementSize(); - const fallbackWidth = width || 1; // See https://github.com/homarr-labs/homarr/issues/2196 - +export const CpuTempRing = ({ + fahrenheit, + cpuTemp, + isTiny, +}: { + fahrenheit: boolean; + cpuTemp: number | undefined; + isTiny: boolean; +}) => { if (!cpuTemp) { return null; } return ( - - - - {fahrenheit ? `${(cpuTemp * 1.8 + 32).toFixed(1)}°F` : `${cpuTemp.toFixed(1)}°C`} - - - - } - sections={[ - { - value: cpuTemp, - color: progressColor(cpuTemp), - }, - ]} - /> - + + + {fahrenheit ? `${(cpuTemp * 1.8 + 32).toFixed(1)}°F` : `${cpuTemp.toFixed(1)}°C`} + + + + } + sections={[ + { + value: cpuTemp, + color: progressColor(cpuTemp), + }, + ]} + /> ); }; diff --git a/packages/widgets/src/health-monitoring/rings/memory-ring.tsx b/packages/widgets/src/health-monitoring/rings/memory-ring.tsx index 2d8ce4d68..e19ad0fe6 100644 --- a/packages/widgets/src/health-monitoring/rings/memory-ring.tsx +++ b/packages/widgets/src/health-monitoring/rings/memory-ring.tsx @@ -1,38 +1,33 @@ -import { Box, Center, RingProgress, Text } from "@mantine/core"; -import { useElementSize } from "@mantine/hooks"; +import { Center, RingProgress, Text } from "@mantine/core"; import { IconBrain } from "@tabler/icons-react"; import { progressColor } from "../system-health"; -export const MemoryRing = ({ available, used }: { available: string; used: string }) => { - const { width, ref } = useElementSize(); - const fallbackWidth = width || 1; // See https://github.com/homarr-labs/homarr/issues/2196 +export const MemoryRing = ({ available, used, isTiny }: { available: string; used: string; isTiny: boolean }) => { const memoryUsage = formatMemoryUsage(available, used); return ( - - - - {memoryUsage.memUsed.GB}GiB - - - - } - sections={[ - { - value: Number(memoryUsage.memUsed.percent), - color: progressColor(Number(memoryUsage.memUsed.percent)), - tooltip: `${memoryUsage.memUsed.percent}%`, - }, - ]} - /> - + + + {memoryUsage.memUsed.GB}GiB + + + + } + sections={[ + { + value: Number(memoryUsage.memUsed.percent), + color: progressColor(Number(memoryUsage.memUsed.percent)), + tooltip: `${memoryUsage.memUsed.percent}%`, + }, + ]} + /> ); }; diff --git a/packages/widgets/src/health-monitoring/system-health.tsx b/packages/widgets/src/health-monitoring/system-health.tsx index 82109f87a..e2f064ebd 100644 --- a/packages/widgets/src/health-monitoring/system-health.tsx +++ b/packages/widgets/src/health-monitoring/system-health.tsx @@ -44,7 +44,11 @@ import classes from "./system-health.module.css"; dayjs.extend(duration); -export const SystemHealthMonitoring = ({ options, integrationIds }: WidgetComponentProps<"healthMonitoring">) => { +export const SystemHealthMonitoring = ({ + options, + integrationIds, + width, +}: WidgetComponentProps<"healthMonitoring">) => { const t = useI18n(); const [healthData] = clientApi.widget.healthMonitoring.getSystemHealthStatus.useSuspenseQuery( { @@ -79,6 +83,8 @@ export const SystemHealthMonitoring = ({ options, integrationIds }: WidgetCompon }, ); + const isTiny = width < 256; + return ( {healthData.map(({ integrationId, integrationName, healthInfo, updatedAt }) => { @@ -91,95 +97,92 @@ export const SystemHealthMonitoring = ({ options, integrationIds }: WidgetCompon h="100%" className={`health-monitoring-information health-monitoring-${integrationName}`} p="sm" + pos="relative" > - - + 0 ? "blue" : "gray"} + position="top-end" + size={16} + label={healthInfo.availablePkgUpdates > 0 ? healthInfo.availablePkgUpdates : undefined} + disabled={!healthInfo.rebootRequired && healthInfo.availablePkgUpdates === 0} > - - 0 ? "blue" : "gray"} - position="top-end" - size="md" - label={healthInfo.availablePkgUpdates > 0 ? healthInfo.availablePkgUpdates : undefined} - disabled={!healthInfo.rebootRequired && healthInfo.availablePkgUpdates === 0} - > - - - - - - - - - }> - {t("widget.healthMonitoring.popover.processor", { cpuModelName: healthInfo.cpuModelName })} - - }> - {t("widget.healthMonitoring.popover.memory", { memory: memoryUsage.memTotal.GB })} - - }> - {t("widget.healthMonitoring.popover.memoryAvailable", { - memoryAvailable: memoryUsage.memFree.GB, - percent: memoryUsage.memFree.percent, - })} - - }> - {t("widget.healthMonitoring.popover.version", { - version: healthInfo.version, - })} - - }> - {formatUptime(healthInfo.uptime, t)} - - }> - {t("widget.healthMonitoring.popover.loadAverage")} - - }> - - {t("widget.healthMonitoring.popover.minute")} {healthInfo.loadAverage["1min"]}% - - - {t("widget.healthMonitoring.popover.minutes", { count: 5 })}{" "} - {healthInfo.loadAverage["5min"]}% - - - {t("widget.healthMonitoring.popover.minutes", { count: 15 })}{" "} - {healthInfo.loadAverage["15min"]}% - - - - - - - {options.cpu && } - {options.cpu && } - {options.memory && } - - { - - {t("widget.healthMonitoring.popover.lastSeen", { lastSeen: dayjs(updatedAt).fromNow() })} - - } + + + + + + + + + }> + {t("widget.healthMonitoring.popover.processor", { cpuModelName: healthInfo.cpuModelName })} + + }> + {t("widget.healthMonitoring.popover.memory", { memory: memoryUsage.memTotal.GB })} + + }> + {t("widget.healthMonitoring.popover.memoryAvailable", { + memoryAvailable: memoryUsage.memFree.GB, + percent: memoryUsage.memFree.percent, + })} + + }> + {t("widget.healthMonitoring.popover.version", { + version: healthInfo.version, + })} + + }> + {formatUptime(healthInfo.uptime, t)} + + }> + {t("widget.healthMonitoring.popover.loadAverage")} + + }> + + {t("widget.healthMonitoring.popover.minute")} {healthInfo.loadAverage["1min"]}% + + + {t("widget.healthMonitoring.popover.minutes", { count: 5 })} {healthInfo.loadAverage["5min"]}% + + + {t("widget.healthMonitoring.popover.minutes", { count: 15 })} {healthInfo.loadAverage["15min"]}% + + + + + + + {options.cpu && } + {options.cpu && ( + + )} + {options.memory && ( + + )} + + { + + {t("widget.healthMonitoring.popover.lastSeen", { lastSeen: dayjs(updatedAt).fromNow() })} + + } {options.fileSystem && disksData.map((disk) => { return ( @@ -188,63 +191,72 @@ export const SystemHealthMonitoring = ({ options, integrationIds }: WidgetCompon `health-monitoring-disk-card health-monitoring-disk-card-${integrationName}`, classes.card, )} + style={{ overflow: "visible" }} key={disk.deviceName} radius={board.itemRadius} - p="sm" + p="xs" > - - - - - {disk.deviceName} - - - - - - {options.fahrenheit - ? `${(disk.temperature * 1.8 + 32).toFixed(1)}°F` - : `${disk.temperature}°C`} - - - - - - {disk.overallStatus ? disk.overallStatus : "N/A"} - - - - - - - - {t("widget.healthMonitoring.popover.used")} - - - - - = 1 - ? `${(Number(disk.available) / 1024 ** 4).toFixed(2)} TiB` - : `${(Number(disk.available) / 1024 ** 3).toFixed(2)} GiB` - } + + - + + + {disk.deviceName} + + + + + + {options.fahrenheit + ? `${(disk.temperature * 1.8 + 32).toFixed(1)}°F` + : `${disk.temperature}°C`} + + + + + + {disk.overallStatus ? disk.overallStatus : "N/A"} + + +
+ + + + + {t("widget.healthMonitoring.popover.used")} + + + + + = 1 + ? `${(Number(disk.available) / 1024 ** 4).toFixed(2)} TiB` + : `${(Number(disk.available) / 1024 ** 3).toFixed(2)} GiB` + } > - - {t("widget.healthMonitoring.popover.available")} - - - - + + + {t("widget.healthMonitoring.popover.available")} + + + + + ); })} From 3d4d32f3773f006edc1d441ce419d7b97c26b526 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Tue, 11 Mar 2025 22:15:13 +0100 Subject: [PATCH 43/60] feat(logs): improve error logs with stacked causes (#2574) --- packages/log/src/index.ts | 44 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/packages/log/src/index.ts b/packages/log/src/index.ts index dcf41cb88..2da0b175e 100644 --- a/packages/log/src/index.ts +++ b/packages/log/src/index.ts @@ -4,8 +4,41 @@ import winston, { format, transports } from "winston"; import { env } from "./env"; import { RedisTransport } from "./redis-transport"; -const logMessageFormat = format.printf(({ level, message, timestamp }) => { - return `${timestamp as string} ${level}: ${message as string}`; +/** + * Formats the cause of an error in the format + * @example caused by Error: {message} + * {stack-trace} + * @param cause next cause in the chain + * @param iteration current iteration of the function + * @returns formatted and stacked causes + */ +const formatCause = (cause: unknown, iteration = 0): string => { + // Prevent infinite recursion + if (iteration > 5) { + return ""; + } + + if (cause instanceof Error) { + if (!cause.cause) { + return `\ncaused by ${cause.stack}`; + } + + return `\ncaused by ${cause.stack}${formatCause(cause.cause, iteration + 1)}`; + } + + return `\ncaused by ${cause as string}`; +}; + +const logMessageFormat = format.printf(({ level, message, timestamp, cause, stack }) => { + if (!cause && !stack) { + return `${timestamp as string} ${level}: ${message as string}`; + } + + if (!cause) { + return `${timestamp as string} ${level}: ${message as string}\n${stack as string}`; + } + + return `${timestamp as string} ${level}: ${message as string}\n${stack as string}${formatCause(cause)}`; }); const logTransports: Transport[] = [new transports.Console()]; @@ -16,7 +49,12 @@ if (!(Boolean(process.env.CI) || Boolean(process.env.DISABLE_REDIS_LOGS))) { } const logger = winston.createLogger({ - format: format.combine(format.colorize(), format.timestamp(), logMessageFormat), + format: format.combine( + format.colorize(), + format.timestamp(), + format.errors({ stack: true, cause: true }), + logMessageFormat, + ), transports: logTransports, level: env.LOG_LEVEL, }); From d669f99ac161697d6c3db81c51b7bf25532fbbfd Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 22:37:33 +0000 Subject: [PATCH 44/60] fix(deps): update testcontainers-node monorepo to ^10.19.0 (#2576) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- package.json | 2 +- packages/db/package.json | 2 +- pnpm-lock.yaml | 22 +++++++++++----------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index f35f7d1fe..2a0f132a9 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "jsdom": "^26.0.0", "prettier": "^3.5.3", "semantic-release": "^24.2.3", - "testcontainers": "^10.18.0", + "testcontainers": "^10.19.0", "turbo": "^2.4.4", "typescript": "^5.8.2", "vite-tsconfig-paths": "^5.1.4", diff --git a/packages/db/package.json b/packages/db/package.json index f5a5e95b4..bd0686355 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -46,7 +46,7 @@ "@homarr/server-settings": "workspace:^0.1.0", "@mantine/core": "^7.17.1", "@paralleldrive/cuid2": "^2.2.2", - "@testcontainers/mysql": "^10.18.0", + "@testcontainers/mysql": "^10.19.0", "better-sqlite3": "^11.8.1", "dotenv": "^16.4.7", "drizzle-kit": "^0.30.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e205ba162..935c447c3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,8 +65,8 @@ importers: specifier: ^24.2.3 version: 24.2.3(typescript@5.8.2) testcontainers: - specifier: ^10.18.0 - version: 10.18.0 + specifier: ^10.19.0 + version: 10.19.0 turbo: specifier: ^2.4.4 version: 2.4.4 @@ -1021,8 +1021,8 @@ importers: specifier: ^2.2.2 version: 2.2.2 '@testcontainers/mysql': - specifier: ^10.18.0 - version: 10.18.0 + specifier: ^10.19.0 + version: 10.19.0 better-sqlite3: specifier: ^11.8.1 version: 11.8.1 @@ -4330,8 +4330,8 @@ packages: '@tanstack/virtual-core@3.11.2': resolution: {integrity: sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw==} - '@testcontainers/mysql@10.18.0': - resolution: {integrity: sha512-btR1f1T3stQi6rrrivoG7cZTkVEC8rml6RWG91ExJYtLJNezPNeHFLwbZDqKfvA4ASw+2LUX5dZ4XISpHhiuAg==} + '@testcontainers/mysql@10.19.0': + resolution: {integrity: sha512-sEiEL0eRyjfm+Zl6b/OtCLRxc1Kyc3ESXVLOPUjMpQCy8tspJLbNqFjnU26wm+/NDKxeOPSsL3ORW8ak8iXoRQ==} '@tiptap/core@2.11.5': resolution: {integrity: sha512-jb0KTdUJaJY53JaN7ooY3XAxHQNoMYti/H6ANo707PsLXVeEqJ9o8+eBup1JU5CuwzrgnDc2dECt2WIGX9f8Jw==} @@ -9506,8 +9506,8 @@ packages: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} - testcontainers@10.18.0: - resolution: {integrity: sha512-MnwWsPjsN5QVe+lSU1LwLZVOyjgwSwv1INzkw8FekdwgvOtvJ7FThQEkbmzRcguQootgwmA9FG54NoTChZDRvA==} + testcontainers@10.19.0: + resolution: {integrity: sha512-/mbcCOaj6jj2IPMMmt+YrBi71MZ4BqEzqicjAInsfEox4pVVMnYIW4CkWOdCLiuZ9nVUkoBtxFSJDTqggJNB5A==} text-decoder@1.2.0: resolution: {integrity: sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==} @@ -12525,9 +12525,9 @@ snapshots: '@tanstack/virtual-core@3.11.2': {} - '@testcontainers/mysql@10.18.0': + '@testcontainers/mysql@10.19.0': dependencies: - testcontainers: 10.18.0 + testcontainers: 10.19.0 transitivePeerDependencies: - supports-color @@ -18438,7 +18438,7 @@ snapshots: glob: 10.4.5 minimatch: 9.0.5 - testcontainers@10.18.0: + testcontainers@10.19.0: dependencies: '@balena/dockerignore': 1.0.2 '@types/dockerode': 3.3.35 From 47ebc66c9e447fe1662bfaaa2ea09e0c9f43f367 Mon Sep 17 00:00:00 2001 From: "homarr-crowdin[bot]" <190541745+homarr-crowdin[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 00:46:48 +0000 Subject: [PATCH 45/60] chore(lang): updated translations from crowdin Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com> --- packages/translation/src/lang/fr.json | 388 +++++++++++++------------- 1 file changed, 194 insertions(+), 194 deletions(-) diff --git a/packages/translation/src/lang/fr.json b/packages/translation/src/lang/fr.json index 6eeb17603..96651bbb5 100644 --- a/packages/translation/src/lang/fr.json +++ b/packages/translation/src/lang/fr.json @@ -659,7 +659,7 @@ "message": "L'intégration a été supprimée avec succès" }, "error": { - "title": "", + "title": "Échec de la suppression", "message": "Impossible de supprimer l'intégration" } } @@ -999,37 +999,37 @@ "openAllInNewTabs": "Tout ouvrir dans des onglets" }, "create": { - "title": "", - "submit": "" + "title": "Nouvelle catégorie", + "submit": "Ajouter une catégorie" }, "remove": { - "title": "", - "message": "" + "title": "Supprimer la catégorie", + "message": "Êtes-vous sûr de vouloir supprimer la catégorie {name}?" }, "edit": { - "title": "", - "submit": "" + "title": "Renommer la catégorie", + "submit": "Renommer la catégorie" }, "menu": { "label": { - "create": "", + "create": "Nouvelle catégorie", "changePosition": "Modifier la position" } }, "openAllInNewTabs": { - "title": "", - "text": "" + "title": "Tout ouvrir dans des onglets", + "text": "Certains navigateurs peuvent bloquer l'ouverture en masse d'onglets pour des raisons de sécurité. Homarr n'a pas pu ouvrir toutes les fenêtres, car votre navigateur a bloqué cette action. Veuillez autoriser \"Ouvrir les fenêtres pop-ups\" et réessayer." } } }, "item": { "action": { - "create": "", - "import": "", - "edit": "", - "moveResize": "", - "duplicate": "", - "remove": "" + "create": "Nouvel élément", + "import": "Importer un élément", + "edit": "Editer l'élément", + "moveResize": "Déplacer / redimensionner l'élément", + "duplicate": "Dupliquer l'élément", + "remove": "Supprimer l'élément" }, "menu": { "label": { @@ -1037,12 +1037,12 @@ } }, "create": { - "title": "", - "search": "", - "addToBoard": "" + "title": "Choisissez un élément à ajouter", + "search": "Filtrer les éléments", + "addToBoard": "Ajouter au Tableau" }, "moveResize": { - "title": "", + "title": "Déplacer / redimensionner l'élément", "field": { "width": { "label": "Largeur" @@ -1051,70 +1051,70 @@ "label": "Hauteur" }, "xOffset": { - "label": "" + "label": "Décalage en X" }, "yOffset": { - "label": "" + "label": "Décalage en Y" } } }, "edit": { - "title": "", + "title": "Editer l'élément", "advancedOptions": { - "label": "", - "title": "" + "label": "Options avancées", + "title": "Options avancées de l'élément" }, "field": { "integrations": { - "label": "" + "label": "Intégrations" }, "customCssClasses": { - "label": "" + "label": "Classes CSS personnalisées" }, "borderColor": { - "label": "" + "label": "Couleur de la bordure" } } }, "remove": { - "title": "", - "message": "" + "title": "Supprimer l'élément", + "message": "Êtes-vous sûr de vouloir supprimer cet élément ?" } }, "widget": { "app": { "name": "App", - "description": "", + "description": "Intégre une application dans le tableau.", "option": { "appId": { - "label": "" + "label": "Choisir une application" }, "openInNewTab": { "label": "Ouvrir dans un nouvel onglet" }, "showTitle": { - "label": "" + "label": "Afficher le nom de l'application" }, "showDescriptionTooltip": { - "label": "" + "label": "Afficher l'info-bulle de description" }, "pingEnabled": { - "label": "" + "label": "Activer la vérification du statut" } }, "error": { "notFound": { - "label": "", - "tooltip": "" + "label": "Aucune application", + "tooltip": "Vous n'avez aucune application valide sélectionnée" } } }, "bookmarks": { - "name": "", - "description": "", + "name": "Signets", + "description": "Affiche les liens de plusieurs applications", "option": { "title": { - "label": "" + "label": "Titre" }, "layout": { "label": "Mise en page", @@ -1126,34 +1126,34 @@ "label": "Verticale" }, "grid": { - "label": "" + "label": "Grille" }, "gridHorizontal": { - "label": "" + "label": "Grille horizontale" } } }, "hideTitle": { - "label": "" + "label": "Cacher le titre" }, "hideIcon": { - "label": "" + "label": "Masquer les icônes" }, "hideHostname": { - "label": "" + "label": "Masquer les noms d'hôtes" }, "openNewTab": { - "label": "" + "label": "Ouvrir dans un nouvel onglet" }, "items": { - "label": "", - "add": "" + "label": "Signets", + "add": "Ajouter un signet" } } }, "dnsHoleSummary": { - "name": "", - "description": "", + "name": "Résumé du puit DNS", + "description": "Affiche le résumé de votre puit DNS", "option": { "layout": { "label": "Mise en page", @@ -1165,28 +1165,28 @@ "label": "Verticale" }, "grid": { - "label": "" + "label": "Grille" } } }, "usePiHoleColors": { - "label": "" + "label": "Utiliser les couleurs de Pi-Hole" } }, "error": { - "internalServerError": "", - "integrationsDisconnected": "" + "internalServerError": "Impossible de récupérer le résumé du puit DNS", + "integrationsDisconnected": "Aucune donnée disponible, toutes les intégrations sont déconnectées" }, "data": { "adsBlockedToday": "Bloqué aujourd'hui", "adsBlockedTodayPercentage": "Bloqué aujourd'hui", "dnsQueriesToday": "Requêtes aujourd'hui", - "domainsBeingBlocked": "" + "domainsBeingBlocked": "Domaines sur la liste noire" }, - "domainsTooltip": "" + "domainsTooltip": "En raison de multiples intégrations, Homarr ne peut pas calculer le nombre exact de domaines bloqués" }, "dnsHoleControls": { - "name": "", + "name": "Contrôles du puit DNS", "description": "Contrôlez PiHole ou AdGuard depuis votre tableau de bord", "option": { "layout": { @@ -1199,95 +1199,95 @@ "label": "Verticale" }, "grid": { - "label": "" + "label": "Grille" } } }, "showToggleAllButtons": { - "label": "" + "label": "Afficher le bouton \"Afficher tout\"" } }, "error": { - "internalServerError": "" + "internalServerError": "Impossible de contrôler le puit DNS" }, "controls": { - "enableAll": "", - "disableAll": "", - "setTimer": "", + "enableAll": "Tout activer", + "disableAll": "Tout désactiver", + "setTimer": "Définir le minuteur", "set": "Définir", "enabled": "Activé", "disabled": "Désactivé", - "processing": "", - "disconnected": "", + "processing": "Traitement en cours", + "disconnected": "Déconnecté", "hours": "Heures", - "minutes": "", - "unlimited": "" + "minutes": "Minutes", + "unlimited": "Laisser vide pour illimité" } }, "clock": { - "name": "", + "name": "Date et heure", "description": "Affiche la date et l'heure courante.", "option": { "customTitleToggle": { - "label": "", - "description": "" + "label": "Affichage du titre/de la ville personnalisé", + "description": "Afficher un titre personnalisé ou le nom de la ville/pays en haut de l'horloge." }, "customTitle": { - "label": "" + "label": "Titre" }, "is24HourFormat": { - "label": "", - "description": "" + "label": "Format 24 heures", + "description": "Utiliser le format 24 heures au lieu du format 12 heures" }, "showSeconds": { - "label": "" + "label": "Afficher les secondes" }, "useCustomTimezone": { - "label": "" + "label": "Utiliser un fuseau horaire fixe" }, "timezone": { "label": "Fuseau Horaire", - "description": "" + "description": "Choisissez le fuseau horaire selon le standard IANA" }, "showDate": { - "label": "" + "label": "Afficher la date" }, "dateFormat": { - "label": "", - "description": "" + "label": "Format de la date", + "description": "À quoi devrait ressembler la date" }, "customTimeFormat": { - "label": "", - "description": "" + "label": "Format de l'heure personnalisé", + "description": "Utiliser ISO 8601 pour formater l'heure (cela remplacera d'autres options)" }, "customDateFormat": { - "label": "", - "description": "" + "label": "Format de date personnalisé", + "description": "Utiliser ISO 8601 pour formater la date (cela remplacera les autres options)" } } }, "minecraftServerStatus": { - "name": "", - "description": "", + "name": "Statut du serveur Minecraft", + "description": "Affiche le statut d'un serveur Minecraft", "option": { "title": { - "label": "" + "label": "Titre" }, "domain": { - "label": "" + "label": "Adresse du serveur" }, "isBedrockServer": { - "label": "" + "label": "Serveur Bedrock" } }, "status": { - "online": "", - "offline": "" + "online": "En ligne", + "offline": "Hors ligne" } }, "notebook": { "name": "Bloc-notes", - "description": "", + "description": "Un simple widget bloc-notes qui supporte le markdown", "option": { "showToolbar": { "label": "Afficher la barre d'outils pour vous aider à écrire du markdown" @@ -1306,7 +1306,7 @@ "underline": "Souligner", "colorText": "Colorer le texte", "colorHighlight": "Surligner en couleur", - "code": "", + "code": "Code", "clear": "Effacer la mise en forme", "heading": "Titre {level}", "align": "Aligner le texte : {position}", @@ -1338,7 +1338,7 @@ }, "popover": { "clearColor": "Enlever la couleur", - "source": "", + "source": "Source", "widthPlaceholder": "Valeur en % ou en pixels", "columns": "Colonnes", "rows": "Lignes", @@ -1347,7 +1347,7 @@ } }, "iframe": { - "name": "", + "name": "iFrame", "description": "Intégrer n'importe quel contenu à partir d'Internet. Certains sites Web peuvent restreindre l'accès.", "option": { "embedUrl": { @@ -1379,32 +1379,32 @@ } }, "error": { - "noUrl": "", - "unsupportedProtocol": "", + "noUrl": "Aucune URL iFrame fournie", + "unsupportedProtocol": "L'URL fournie utilise un protocole non pris en charge. Veuillez utiliser l'un des ({supportedProtocols})", "noBrowerSupport": "Votre navigateur internet ne prend pas en charge les iframes. Merci de le mettre à jour." } }, "smartHome-entityState": { - "name": "", - "description": "", + "name": "Etat de l'entité", + "description": "Affichez l'état d'une entité et optionnellement activez la", "option": { "entityId": { "label": "ID de l’entité" }, "displayName": { - "label": "" + "label": "Nom d'affichage" }, "entityUnit": { - "label": "" + "label": "Unité d'Entité" }, "clickable": { - "label": "" + "label": "Cliquable" } } }, "smartHome-executeAutomation": { - "name": "", - "description": "", + "name": "Exécuter l'automatisation", + "description": "Déclencher une automatisation en un seul clic", "option": { "displayName": { "label": "Nom d'affichage" @@ -1414,29 +1414,29 @@ } }, "spotlightAction": { - "run": "" + "run": "Exécuter {name}" } }, "calendar": { "name": "Calendrier", - "description": "", + "description": "Afficher les événements de vos intégrations dans une vue calendrier pendant une certaine période de temps relative", "option": { "releaseType": { "label": "Type de sortie Radarr", "options": { - "inCinemas": "", - "digitalRelease": "", - "physicalRelease": "" + "inCinemas": "En salle", + "digitalRelease": "Sortie numérique", + "physicalRelease": "Sortie physique" } }, "filterPastMonths": { - "label": "" + "label": "À partir de" }, "filterFutureMonths": { - "label": "" + "label": "Fini le" }, "showUnmonitored": { - "label": "" + "label": "Afficher les messages non surveillés" } } }, @@ -1445,39 +1445,39 @@ "description": "Affiche la météo actuelle d'un emplacement préconfiguré.", "option": { "isFormatFahrenheit": { - "label": "" + "label": "Température en Fahrenheit" }, "disableTemperatureDecimals": { - "label": "" + "label": "Désactiver les décimales pour la température" }, "showCurrentWindSpeed": { - "label": "", - "description": "" + "label": "Afficher la vitesse actuelle du vent", + "description": "Uniquement sur la météo actuelle" }, "location": { "label": "Lieu de la météo" }, "showCity": { - "label": "" + "label": "Afficher la ville" }, "hasForecast": { - "label": "" + "label": "Afficher les prévisions" }, "forecastDayCount": { - "label": "", - "description": "" + "label": "Nombre de jours de prévisions", + "description": "Lorsque le widget n'est pas assez large, moins de jours sont affichés" }, "dateFormat": { - "label": "", - "description": "" + "label": "Format de la date", + "description": "À quoi devrait ressembler la date" } }, - "currentWindSpeed": "", + "currentWindSpeed": "{currentWindSpeed} km/h", "dailyForecast": { - "sunrise": "", - "sunset": "", - "maxWindSpeed": "", - "maxWindGusts": "" + "sunrise": "Lever du Soleil", + "sunset": "Coucher du soleil", + "maxWindSpeed": "Vitesse maximale du vent : {maxWindSpeed} km/h", + "maxWindGusts": "Rafales de vent maximales : {maxWindGusts} km/h" }, "kind": { "clear": "Clair", @@ -1498,24 +1498,24 @@ }, "indexerManager": { "name": "Statut du gestionnaire d’indexeur", - "description": "", + "description": "État de vos indexeurs", "option": { "openIndexerSiteInNewTab": { - "label": "" + "label": "Ouvrir le site de l'indexeur dans un nouvel onglet" } }, "title": "Gestionnaire d’indexeur", "testAll": "Tout tester", "error": { - "internalServerError": "" + "internalServerError": "Impossible de récupérer le statut des indexeurs" } }, "healthMonitoring": { "name": "Surveillance de l'état du système", "description": "Affiche des informations sur l'état et la santé de votre (vos) système(s).", "tab": { - "system": "", - "cluster": "" + "system": "Système", + "cluster": "Cluster" }, "option": { "fahrenheit": { @@ -1531,94 +1531,94 @@ "label": "Afficher les infos sur le système de fichiers" }, "defaultTab": { - "label": "" + "label": "Onglet par défaut" }, "sectionIndicatorRequirement": { - "label": "" + "label": "Exigence de l'indicateur de section" } }, "popover": { - "information": "", - "processor": "", - "memory": "", - "memoryAvailable": "", - "version": "", - "uptime": "", - "loadAverage": "", - "minute": "", - "minutes": "", - "used": "", + "information": "Information", + "processor": "Processeur : {cpuModelName}", + "memory": "Mémoire: {memory}GiB", + "memoryAvailable": "Disponible: {memoryAvailable}GiB ({percent}%)", + "version": "Version : {version}", + "uptime": "Disponibilité: {months} Mois, {days} Jours, {hours} Heures, {minutes} Minutes", + "loadAverage": "Charge moyenne:", + "minute": "1 minute", + "minutes": "{count} minutes", + "used": "Utilisé ", "available": "Disponible", - "lastSeen": "" + "lastSeen": "Dernière mise à jour de statut: {lastSeen}" }, "memory": {}, "error": { - "internalServerError": "" + "internalServerError": "Impossible de récupérer l'état de santé" }, "cluster": { "summary": { - "cpu": "", - "memory": "" + "cpu": "CPU", + "memory": "RAM" }, "resource": { "node": { - "name": "" + "name": "Nœuds" }, "qemu": { - "name": "" + "name": "VMs" }, "lxc": { - "name": "" + "name": "LXCs" }, "storage": { - "name": "" + "name": "Stockage" } }, "popover": { "rightSection": { - "node": "", - "vmId": "", - "plugin": "" + "node": "Noeud", + "vmId": "VM ID", + "plugin": "Plugin" }, "detail": { - "cpu": "", - "memory": "", - "storage": "", - "uptime": "", - "haState": "", + "cpu": "Coeurs", + "memory": "Mémoire", + "storage": "Stockage", + "uptime": "Disponibilité", + "haState": "Etat HA", "storageType": { - "local": "", - "shared": "" + "local": "Stockage local", + "shared": "Stockage partagé" } } }, "table": { "header": { - "name": "", - "cpu": "", - "memory": "", - "node": "" + "name": "Nom", + "cpu": "CPU", + "memory": "RAM", + "node": "Noeud" } } } }, "common": { "location": { - "query": "", - "latitude": "", - "longitude": "", - "disabledTooltip": "", - "unknownLocation": "", + "query": "Ville / Code Postal", + "latitude": "Latitude", + "longitude": "Longitude", + "disabledTooltip": "Veuillez saisir une ville ou un code postal.", + "unknownLocation": "Lieu inconnu", "search": "Rechercher", "table": { "header": { - "city": "", - "country": "", - "coordinates": "", - "population": "" + "city": "Ville", + "country": "Pays", + "coordinates": "Coordonnées", + "population": "Population" }, "action": { - "select": "" + "select": "Sélectionnez {city}, {countryCode}" }, "population": { "fallback": "Inconnu" @@ -1626,17 +1626,17 @@ } }, "integration": { - "noData": "", - "description": "" + "noData": "Aucune intégration trouvée.", + "description": "Cliquez sur pour créer une nouvelle intégration" }, "app": { - "noData": "", - "description": "", - "quickCreate": "" + "noData": "Aucune application trouvée", + "description": "Cliquez sur pour créer une nouvelle application", + "quickCreate": "Créer une application à la volée" }, "error": { - "noIntegration": "", - "noData": "" + "noIntegration": "Aucune intégration sélectionnée", + "noData": "Aucune donnée d’interaction disponible" }, "option": {} }, @@ -1649,33 +1649,33 @@ }, "hasAutoPlay": { "label": "Lecture automatique", - "description": "" + "description": "La lecture automatique ne fonctionne que si elle est mise en sourdine en raison des restrictions du navigateur" }, "isMuted": { - "label": "" + "label": "Muet" }, "hasControls": { - "label": "" + "label": "Afficher les controles" } }, "error": { - "noUrl": "", - "forYoutubeUseIframe": "" + "noUrl": "Aucune URL de vidéo fournie", + "forYoutubeUseIframe": "Pour les vidéos YouTube, utilisez l'option iFrame" } }, "mediaServer": { - "name": "", - "description": "", + "name": "Flux du serveur multimédia actuel", + "description": "Afficher les flux en cours sur vos serveurs de multimédia", "option": {}, "items": { - "currentlyPlaying": "", - "user": "", - "name": "", - "id": "" + "currentlyPlaying": "En cours de lecture", + "user": "Utilisateur", + "name": "Nom", + "id": "Id" } }, "downloads": { - "name": "", + "name": "Client de téléchargement", "description": "", "option": { "columns": { From f55d8a9c2ebbc612775d66b1f073605fb9e151f3 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:37:43 +0100 Subject: [PATCH 46/60] fix(deps): update dependency next-intl to v4 (#2580) * fix(deps): update dependency next-intl to v4 * fix: typecheck issue * refactor: implement improvements for next-intl v4 * fix: typecheck issues * fix: typecheck issue --------- Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> Co-authored-by: Meier Lukas --- .gitignore | 3 ++ apps/nextjs/next.config.ts | 7 +++- .../app/[locale]/auth/invite/[id]/page.tsx | 3 +- apps/nextjs/src/app/[locale]/layout.tsx | 4 +-- .../src/app/[locale]/manage/about/page.tsx | 6 ++-- .../manage/apps/_app-delete-button.tsx | 4 ++- .../_search-engine-delete-button.tsx | 4 ++- .../manage/tools/docker/docker-table.tsx | 6 ++-- .../configmaps/configmaps-table.tsx | 2 +- .../kubernetes/ingresses/ingresses-table.tsx | 2 +- .../namespaces/namespaces-table.tsx | 2 +- .../tools/kubernetes/nodes/nodes-table.tsx | 2 +- .../tools/kubernetes/pods/pods-table.tsx | 2 +- .../kubernetes/secrets/secrets-table.tsx | 2 +- .../kubernetes/services/services-table.tsx | 2 +- .../kubernetes/volumes/volumes-table.tsx | 2 +- .../_components/_delete-user-button.tsx | 3 +- .../manage/users/[userId]/general/page.tsx | 3 +- .../src/components/user-avatar-menu.tsx | 5 ++- .../src/icon-picker/icon-picker.tsx | 2 +- .../initial/board-selection-card.tsx | 2 +- packages/translation/package.json | 2 +- packages/translation/src/client/index.ts | 12 +++++-- .../src/client/use-current-locale.ts | 4 +-- packages/translation/src/lang/en.json | 2 +- packages/translation/src/request.ts | 2 +- packages/translation/src/routing.ts | 2 ++ packages/translation/src/server.ts | 10 ++++++ packages/validation/src/form/i18n.ts | 3 +- .../src/_inputs/widget-location-input.tsx | 2 +- .../src/health-monitoring/system-health.tsx | 14 +++++--- .../src/media-transcoding/component.tsx | 6 ++-- packages/widgets/src/notebook/notebook.tsx | 8 ++--- packages/widgets/src/weather/component.tsx | 2 +- packages/widgets/src/weather/icon.tsx | 12 +++++-- pnpm-lock.yaml | 34 +++++++++++++------ tooling/typescript/base.json | 20 +++-------- 37 files changed, 127 insertions(+), 76 deletions(-) diff --git a/.gitignore b/.gitignore index 76c8f08fc..0aa3ed4c7 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,6 @@ e2e/shared/tmp #personal backgrounds apps/nextjs/public/images/background.png + +# next-intl +en.d.json.ts \ No newline at end of file diff --git a/apps/nextjs/next.config.ts b/apps/nextjs/next.config.ts index a8a022a60..d88dac644 100644 --- a/apps/nextjs/next.config.ts +++ b/apps/nextjs/next.config.ts @@ -10,7 +10,12 @@ import MillionLint from "@million/lint"; import createNextIntlPlugin from "next-intl/plugin"; // Package path does not work... so we need to use relative path -const withNextIntl = createNextIntlPlugin("../../packages/translation/src/request.ts"); +const withNextIntl = createNextIntlPlugin({ + experimental: { + createMessagesDeclaration: "../../packages/translation/src/lang/en.json", + }, + requestConfig: "../../packages/translation/src/request.ts", +}); interface WebpackConfig { module: { diff --git a/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx b/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx index 7de11ff0f..cc6535703 100644 --- a/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx +++ b/apps/nextjs/src/app/[locale]/auth/invite/[id]/page.tsx @@ -63,7 +63,8 @@ export default async function InviteUsagePage(props: InviteUsagePageProps) { - {t("description", { username: invite.creator.name })} + {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} + {t("description", { username: invite.creator.name! })} diff --git a/apps/nextjs/src/app/[locale]/layout.tsx b/apps/nextjs/src/app/[locale]/layout.tsx index b988647bc..5fbd3c3f7 100644 --- a/apps/nextjs/src/app/[locale]/layout.tsx +++ b/apps/nextjs/src/app/[locale]/layout.tsx @@ -20,7 +20,6 @@ import { SettingsProvider } from "@homarr/settings"; import { SpotlightProvider } from "@homarr/spotlight"; import type { SupportedLanguage } from "@homarr/translation"; import { isLocaleRTL, isLocaleSupported } from "@homarr/translation"; -import { getI18nMessages } from "@homarr/translation/server"; import { Analytics } from "~/components/layout/analytics"; import { SearchEngineOptimization } from "~/components/layout/search-engine-optimization"; @@ -81,7 +80,6 @@ export default async function Layout(props: { const serverSettings = await getServerSettingsAsync(db); const colorScheme = await getCurrentColorSchemeAsync(); const direction = isLocaleRTL((await props.params).locale) ? "rtl" : "ltr"; - const i18nMessages = await getI18nMessages(); const StackedProvider = composeWrappers([ (innerProps) => { @@ -105,7 +103,7 @@ export default async function Layout(props: { (innerProps) => , (innerProps) => , (innerProps) => , - (innerProps) => , + (innerProps) => , (innerProps) => , (innerProps) => , (innerProps) => , diff --git a/apps/nextjs/src/app/[locale]/manage/about/page.tsx b/apps/nextjs/src/app/[locale]/manage/about/page.tsx index 024267be2..ece275534 100644 --- a/apps/nextjs/src/app/[locale]/manage/about/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/about/page.tsx @@ -80,7 +80,7 @@ export default async function AboutPage() { {t("accordion.contributors.title")} {t("accordion.contributors.subtitle", { - count: githubContributors.length, + count: String(githubContributors.length), })} @@ -104,7 +104,7 @@ export default async function AboutPage() { {t("accordion.translators.title")} {t("accordion.translators.subtitle", { - count: crowdinContributors.length, + count: String(crowdinContributors.length), })} @@ -128,7 +128,7 @@ export default async function AboutPage() { {t("accordion.libraries.title")} {t("accordion.libraries.subtitle", { - count: Object.keys(attributes.dependencies).length, + count: String(Object.keys(attributes.dependencies).length), })} diff --git a/apps/nextjs/src/app/[locale]/manage/apps/_app-delete-button.tsx b/apps/nextjs/src/app/[locale]/manage/apps/_app-delete-button.tsx index bdc520579..2fb1dce56 100644 --- a/apps/nextjs/src/app/[locale]/manage/apps/_app-delete-button.tsx +++ b/apps/nextjs/src/app/[locale]/manage/apps/_app-delete-button.tsx @@ -23,7 +23,9 @@ export const AppDeleteButton = ({ app }: AppDeleteButtonProps) => { const onClick = useCallback(() => { openConfirmModal({ title: t("title"), - children: t("message", app), + children: t("message", { + name: app.name, + }), onConfirm: () => { mutate( { id: app.id }, diff --git a/apps/nextjs/src/app/[locale]/manage/search-engines/_search-engine-delete-button.tsx b/apps/nextjs/src/app/[locale]/manage/search-engines/_search-engine-delete-button.tsx index b8df69619..6857c4714 100644 --- a/apps/nextjs/src/app/[locale]/manage/search-engines/_search-engine-delete-button.tsx +++ b/apps/nextjs/src/app/[locale]/manage/search-engines/_search-engine-delete-button.tsx @@ -23,7 +23,9 @@ export const SearchEngineDeleteButton = ({ searchEngine }: SearchEngineDeleteBut const onClick = useCallback(() => { openConfirmModal({ title: t("title"), - children: t("message", searchEngine), + children: t("message", { + name: searchEngine.name, + }), onConfirm: () => { mutate( { id: searchEngine.id }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx index b2478d5d9..e94d2be6a 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/docker/docker-table.tsx @@ -104,7 +104,7 @@ export function DockerTable(initialData: RouterOutputs["docker"]["getContainers" enableBottomToolbar: false, positionGlobalFilter: "right", mantineSearchTextInputProps: { - placeholder: tDocker("table.search", { count: data.containers.length }), + placeholder: tDocker("table.search", { count: String(data.containers.length) }), style: { minWidth: 300 }, autoFocus: true, }, @@ -146,8 +146,8 @@ export function DockerTable(initialData: RouterOutputs["docker"]["getContainers" {groupedAlert} {tDocker("table.selected", { - selectCount: table.getSelectedRowModel().rows.length, - totalCount: table.getRowCount(), + selectCount: String(table.getSelectedRowModel().rows.length), + totalCount: String(table.getRowCount()), })} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx index ac144ee15..9723171eb 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table.tsx @@ -62,7 +62,7 @@ export function ConfigmapsTable(initialData: ConfigMapsTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tConfigMaps("table.search", { count: data.length }), + placeholder: tConfigMaps("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx index e53e492eb..fbb250806 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table.tsx @@ -95,7 +95,7 @@ export function IngressesTable(initialData: IngressesTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tIngresses("table.search", { count: data.length }), + placeholder: tIngresses("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx index 9ef0e4a5b..2486a4ad0 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table.tsx @@ -79,7 +79,7 @@ export function NamespacesTable(initialData: NamespacesTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tNamespaces("table.search", { count: data.length }), + placeholder: tNamespaces("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx index b7b17d984..2fc69d51f 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/nodes/nodes-table.tsx @@ -105,7 +105,7 @@ export function NodesTable(initialData: NodesListComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tNodes("table.search", { count: data.length }), + placeholder: tNodes("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx index 3a1e10820..dd600b387 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/pods/pods-table.tsx @@ -70,7 +70,7 @@ export function PodsTable(initialData: PodsTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true, expanded: true }, mantineSearchTextInputProps: { - placeholder: tPods("table.search", { count: data.length }), + placeholder: tPods("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx index 3c24ad0f1..d0a902f22 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/secrets/secrets-table.tsx @@ -65,7 +65,7 @@ export function SecretsTable(initialData: SecretsTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tSecrets("table.search", { count: data.length }), + placeholder: tSecrets("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx index 7e13a630a..04a2924d7 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/services/services-table.tsx @@ -84,7 +84,7 @@ export function ServicesTable(initialData: ServicesTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tServices("table.search", { count: data.length }), + placeholder: tServices("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx index be217d314..e911ee7a6 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/volumes/volumes-table.tsx @@ -89,7 +89,7 @@ export function VolumesTable(initialData: VolumesTableComponentProps) { positionGlobalFilter: "right", initialState: { density: "xs", showGlobalFilter: true }, mantineSearchTextInputProps: { - placeholder: tVolumes("table.search", { count: data.length }), + placeholder: tVolumes("table.search", { count: String(data.length) }), style: { minWidth: 300 }, autoFocus: true, }, diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_delete-user-button.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_delete-user-button.tsx index ebaf1b0cb..0b93f2388 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_delete-user-button.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_delete-user-button.tsx @@ -28,7 +28,8 @@ export const DeleteUserButton = ({ user }: DeleteUserButtonProps) => { () => openConfirmModal({ title: t("user.action.delete.label"), - children: t("user.action.delete.confirm", { username: user.name }), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + children: t("user.action.delete.confirm", { username: user.name! }), // eslint-disable-next-line no-restricted-syntax async onConfirm() { await mutateUserDeletionAsync({ diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx index 48a2e8aa3..add232243 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx @@ -41,7 +41,8 @@ export async function generateMetadata(props: Props) { const t = await getScopedI18n("management.page.user.edit"); return { - title: createMetaTitle(t("metaTitle", { username: user.name })), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + title: createMetaTitle(t("metaTitle", { username: user.name! })), }; } diff --git a/apps/nextjs/src/components/user-avatar-menu.tsx b/apps/nextjs/src/components/user-avatar-menu.tsx index d7a53f901..cc676ee09 100644 --- a/apps/nextjs/src/components/user-avatar-menu.tsx +++ b/apps/nextjs/src/components/user-avatar-menu.tsx @@ -74,7 +74,10 @@ export const UserAvatarMenu = ({ children, availableUpdates }: UserAvatarMenuPro leftSection={} > - {t("updateAvailable", { countUpdates: availableUpdates.length, tag: availableUpdates[0].tagName })} + {t("updateAvailable", { + countUpdates: String(availableUpdates.length), + tag: availableUpdates[0].tagName, + })} diff --git a/packages/forms-collection/src/icon-picker/icon-picker.tsx b/packages/forms-collection/src/icon-picker/icon-picker.tsx index d3abda661..9dbfb55f7 100644 --- a/packages/forms-collection/src/icon-picker/icon-picker.tsx +++ b/packages/forms-collection/src/icon-picker/icon-picker.tsx @@ -148,7 +148,7 @@ export const IconPicker = ({ value: propsValue, onChange, error, onFocus, onBlur withAsterisk error={error} label={tCommon("iconPicker.label")} - placeholder={tCommon("iconPicker.header", { countIcons: data?.countIcons ?? 0 })} + placeholder={tCommon("iconPicker.header", { countIcons: String(data?.countIcons ?? 0) })} /> {session?.user.permissions.includes("media-upload") && ( - {tBoardSelection("title", { count: selections.size })} + {tBoardSelection("title", { count: String(selections.size) })} {areAllChecked ? tBoardSelection("action.unselectAll") : tBoardSelection("action.selectAll")} diff --git a/packages/translation/package.json b/packages/translation/package.json index 45c65045d..461ddde18 100644 --- a/packages/translation/package.json +++ b/packages/translation/package.json @@ -33,7 +33,7 @@ "deepmerge": "4.3.1", "mantine-react-table": "2.0.0-beta.9", "next": "15.1.7", - "next-intl": "3.26.5", + "next-intl": "4.0.0", "react": "19.0.0", "react-dom": "19.0.0" }, diff --git a/packages/translation/src/client/index.ts b/packages/translation/src/client/index.ts index 16d73330b..5c6755883 100644 --- a/packages/translation/src/client/index.ts +++ b/packages/translation/src/client/index.ts @@ -2,18 +2,26 @@ import { useMessages, useTranslations } from "next-intl"; -import type { TranslationObject } from "../type"; +import type { SupportedLanguage } from "../config"; +import type englishTranslation from "../lang/en.json"; export { useChangeLocale } from "./use-change-locale"; export { useCurrentLocale } from "./use-current-locale"; +declare module "next-intl" { + interface AppConfig { + Messages: typeof englishTranslation; + Locale: SupportedLanguage; + } +} + export const { useI18n, useScopedI18n } = { useI18n: useTranslations, useScopedI18n: useTranslations, }; export const { useI18nMessages } = { - useI18nMessages: () => useMessages() as TranslationObject, + useI18nMessages: () => useMessages(), }; export { useTranslations }; diff --git a/packages/translation/src/client/use-current-locale.ts b/packages/translation/src/client/use-current-locale.ts index f05eff7e5..a0e796010 100644 --- a/packages/translation/src/client/use-current-locale.ts +++ b/packages/translation/src/client/use-current-locale.ts @@ -1,5 +1,3 @@ import { useLocale } from "next-intl"; -import type { SupportedLanguage } from "../config"; - -export const useCurrentLocale = () => useLocale() as SupportedLanguage; +export const useCurrentLocale = useLocale; diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 320abee21..57eca7c72 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -3594,7 +3594,7 @@ }, "delete": { "title": "Delete search engine", - "message": "Are you sure you want to delete the search engine '{name}'?", + "message": "Are you sure you want to delete the search engine {name}?", "notification": { "success": { "title": "Search engine deleted", diff --git a/packages/translation/src/request.ts b/packages/translation/src/request.ts index 9b901d2ba..1d680e50b 100644 --- a/packages/translation/src/request.ts +++ b/packages/translation/src/request.ts @@ -22,7 +22,7 @@ export default getRequestConfig(async ({ requestLocale }) => { if (currentLocale !== fallbackLocale) { const fallbackMessages = (await languageMap[fallbackLocale]()).default; return { - locale: currentLocale, + locale: typedLocale, messages: deepmerge(fallbackMessages, currentMessages), }; } diff --git a/packages/translation/src/routing.ts b/packages/translation/src/routing.ts index db81f0228..e6f268690 100644 --- a/packages/translation/src/routing.ts +++ b/packages/translation/src/routing.ts @@ -11,6 +11,8 @@ export const createRouting = (defaultLocale: SupportedLanguage) => defaultLocale, localeCookie: { name: localeCookieKey, + // 1 year + maxAge: 60 * 60 * 24 * 365, }, localePrefix: { mode: "never", // Rewrite the URL with locale parameter but without shown in url diff --git a/packages/translation/src/server.ts b/packages/translation/src/server.ts index bfab90719..ebcc6442b 100644 --- a/packages/translation/src/server.ts +++ b/packages/translation/src/server.ts @@ -1,5 +1,15 @@ import { getTranslations } from "next-intl/server"; +import type { SupportedLanguage } from "./config"; +import type englishTranslation from "./lang/en.json"; + +declare module "next-intl" { + interface AppConfig { + Messages: typeof englishTranslation; + Locale: SupportedLanguage; + } +} + export const { getI18n, getScopedI18n } = { getI18n: getTranslations, getScopedI18n: getTranslations, diff --git a/packages/validation/src/form/i18n.ts b/packages/validation/src/form/i18n.ts index db53d1e95..e1f01041a 100644 --- a/packages/validation/src/form/i18n.ts +++ b/packages/validation/src/form/i18n.ts @@ -12,7 +12,8 @@ export const zodErrorMap = (t: TFunction) }; } return { - message: t(error.key ? `common.zod.${error.key}` : "common.zod.errors.default", error.params ?? {}), + // use never to make ts happy + message: t(error.key ? `common.zod.${error.key}` : "common.zod.errors.default", (error.params ?? {}) as never), }; }; }; diff --git a/packages/widgets/src/_inputs/widget-location-input.tsx b/packages/widgets/src/_inputs/widget-location-input.tsx index a27be85cb..37d26cf2e 100644 --- a/packages/widgets/src/_inputs/widget-location-input.tsx +++ b/packages/widgets/src/_inputs/widget-location-input.tsx @@ -224,7 +224,7 @@ const LocationSelectTableRow = ({ city, onLocationSelect, closeModal }: Location diff --git a/packages/widgets/src/health-monitoring/system-health.tsx b/packages/widgets/src/health-monitoring/system-health.tsx index e2f064ebd..6e4aa2ed4 100644 --- a/packages/widgets/src/health-monitoring/system-health.tsx +++ b/packages/widgets/src/health-monitoring/system-health.tsx @@ -140,7 +140,7 @@ export const SystemHealthMonitoring = ({ }> {t("widget.healthMonitoring.popover.memoryAvailable", { memoryAvailable: memoryUsage.memFree.GB, - percent: memoryUsage.memFree.percent, + percent: String(memoryUsage.memFree.percent), })} }> @@ -159,10 +159,11 @@ export const SystemHealthMonitoring = ({ {t("widget.healthMonitoring.popover.minute")} {healthInfo.loadAverage["1min"]}% - {t("widget.healthMonitoring.popover.minutes", { count: 5 })} {healthInfo.loadAverage["5min"]}% + {t("widget.healthMonitoring.popover.minutes", { count: "5" })} {healthInfo.loadAverage["5min"]}% - {t("widget.healthMonitoring.popover.minutes", { count: 15 })} {healthInfo.loadAverage["15min"]}% + {t("widget.healthMonitoring.popover.minutes", { count: "15" })}{" "} + {healthInfo.loadAverage["15min"]}% @@ -274,7 +275,12 @@ export const formatUptime = (uptimeInSeconds: number, t: TranslationFunction) => const hours = uptimeDuration.hours(); const minutes = uptimeDuration.minutes(); - return t("widget.healthMonitoring.popover.uptime", { months, days, hours, minutes }); + return t("widget.healthMonitoring.popover.uptime", { + months: String(months), + days: String(days), + hours: String(hours), + minutes: String(minutes), + }); }; export const progressColor = (percentage: number) => { diff --git a/packages/widgets/src/media-transcoding/component.tsx b/packages/widgets/src/media-transcoding/component.tsx index cad468681..d66da98e6 100644 --- a/packages/widgets/src/media-transcoding/component.tsx +++ b/packages/widgets/src/media-transcoding/component.tsx @@ -95,9 +95,9 @@ export default function MediaTranscodingWidget({ {t("currentIndex", { - start: transcodingData.data.queue.startIndex + 1, - end: transcodingData.data.queue.endIndex + 1, - total: transcodingData.data.queue.totalCount, + start: String(transcodingData.data.queue.startIndex + 1), + end: String(transcodingData.data.queue.endIndex + 1), + total: String(transcodingData.data.queue.totalCount), })} diff --git a/packages/widgets/src/notebook/notebook.tsx b/packages/widgets/src/notebook/notebook.tsx index 257dcfc50..a30048427 100644 --- a/packages/widgets/src/notebook/notebook.tsx +++ b/packages/widgets/src/notebook/notebook.tsx @@ -280,10 +280,10 @@ export function Notebook({ options, isEditMode, boardId, itemId }: WidgetCompone - - - - + + + + diff --git a/packages/widgets/src/weather/component.tsx b/packages/widgets/src/weather/component.tsx index fb1fecdc9..88df5cce5 100644 --- a/packages/widgets/src/weather/component.tsx +++ b/packages/widgets/src/weather/component.tsx @@ -75,7 +75,7 @@ const DailyWeather = ({ options, weather }: WeatherProps) => { {options.showCurrentWindSpeed && ( - {t("currentWindSpeed", { currentWindSpeed: weather.current.windspeed })} + {t("currentWindSpeed", { currentWindSpeed: String(weather.current.windspeed) })} )} diff --git a/packages/widgets/src/weather/icon.tsx b/packages/widgets/src/weather/icon.tsx index f93eba241..17e9c03c5 100644 --- a/packages/widgets/src/weather/icon.tsx +++ b/packages/widgets/src/weather/icon.tsx @@ -94,8 +94,16 @@ export const WeatherDescription = ({ }>{`${tCommon("information.min")}: ${minTemp}`} }>{`${t("dailyForecast.sunrise")}: ${sunrise}`} }>{`${t("dailyForecast.sunset")}: ${sunset}`} - }>{t("dailyForecast.maxWindSpeed", { maxWindSpeed })} - }>{t("dailyForecast.maxWindGusts", { maxWindGusts })} + {maxWindSpeed !== undefined && ( + }> + {t("dailyForecast.maxWindSpeed", { maxWindSpeed: String(maxWindSpeed) })} + + )} + {maxWindGusts !== undefined && ( + }> + {t("dailyForecast.maxWindGusts", { maxWindGusts: String(maxWindGusts) })} + + )} ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 935c447c3..7ca1e920c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1893,8 +1893,8 @@ importers: specifier: 15.1.7 version: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) next-intl: - specifier: 3.26.5 - version: 3.26.5(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0) + specifier: 4.0.0 + version: 4.0.0(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2) react: specifier: 19.0.0 version: 19.0.0 @@ -4081,6 +4081,9 @@ packages: '@scarf/scarf@1.4.0': resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} + '@schummar/icu-type-parser@1.21.5': + resolution: {integrity: sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==} + '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -7850,11 +7853,15 @@ packages: nodemailer: optional: true - next-intl@3.26.5: - resolution: {integrity: sha512-EQlCIfY0jOhRldiFxwSXG+ImwkQtDEfQeSOEQp6ieAGSLWGlgjdb/Ck/O7wMfC430ZHGeUKVKax8KGusTPKCgg==} + next-intl@4.0.0: + resolution: {integrity: sha512-l+I1PLAFrjzYzrc340n1vssDJ7pP1gtYT1jOWlRWIHkyrPdyosEIHPC+LiqJP4vWvWtCZzzqTn9AaBF+x5Ja8g==} peerDependencies: - next: ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 + next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true next@15.1.7: resolution: {integrity: sha512-GNeINPGS9c6OZKCvKypbL8GTsT5GhWPp4DM0fzkXJuXMilOO2EeFxuAY6JZbtk6XIl6Ws10ag3xRINDjSO5+wg==} @@ -9977,10 +9984,10 @@ packages: peerDependencies: react: '>=16.13' - use-intl@3.26.5: - resolution: {integrity: sha512-OdsJnC/znPvHCHLQH/duvQNXnP1w0hPfS+tkSi3mAbfjYBGh4JnyfdwkQBfIVf7t8gs9eSX/CntxUMvtKdG2MQ==} + use-intl@4.0.0: + resolution: {integrity: sha512-/fmC7haEMVNa0isXGRGUir56fD4I9LRnOgbeBmji+bow6U8pE7WD+2X2sjqh+0h3yJ0T36PA6JXZ6PlVeRyt8w==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 use-isomorphic-layout-effect@1.1.2: resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} @@ -11995,6 +12002,8 @@ snapshots: '@scarf/scarf@1.4.0': {} + '@schummar/icu-type-parser@1.21.5': {} + '@sec-ant/readable-stream@0.4.1': {} '@semantic-release/changelog@6.0.3(semantic-release@24.2.3(typescript@5.8.2))': @@ -16501,13 +16510,15 @@ snapshots: next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 - next-intl@3.26.5(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0): + next-intl@4.0.0(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2): dependencies: '@formatjs/intl-localematcher': 0.5.5 negotiator: 1.0.0 next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 - use-intl: 3.26.5(react@19.0.0) + use-intl: 4.0.0(react@19.0.0) + optionalDependencies: + typescript: 5.8.2 next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1): dependencies: @@ -18934,9 +18945,10 @@ snapshots: dequal: 2.0.3 react: 19.0.0 - use-intl@3.26.5(react@19.0.0): + use-intl@4.0.0(react@19.0.0): dependencies: '@formatjs/fast-memoize': 2.2.1 + '@schummar/icu-type-parser': 1.21.5 intl-messageformat: 10.7.1 react: 19.0.0 diff --git a/tooling/typescript/base.json b/tooling/typescript/base.json index 37f6290fb..ae235642b 100644 --- a/tooling/typescript/base.json +++ b/tooling/typescript/base.json @@ -2,11 +2,7 @@ "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { "target": "ES2022", - "lib": [ - "dom", - "dom.iterable", - "ES2022" - ], + "lib": ["dom", "dom.iterable", "ES2022"], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -15,6 +11,7 @@ "module": "esnext", "moduleResolution": "Bundler", "resolveJsonModule": true, + "allowArbitraryExtensions": true, "isolatedModules": true, "moduleDetection": "force", "jsx": "preserve", @@ -23,15 +20,8 @@ "strictNullChecks": true, "baseUrl": ".", "paths": { - "*": [ - "node_modules/*" - ] + "*": ["node_modules/*"] } }, - "exclude": [ - "node_modules", - "build", - "dist", - ".next" - ] -} \ No newline at end of file + "exclude": ["node_modules", "build", "dist", ".next"] +} From c94159388d27c765695ede3f1b8d7cda7c7c21ec Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:21:16 +0000 Subject: [PATCH 47/60] chore(deps): update dependency proxmox-api>undici to v7.5.0 (#2582) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- package.json | 2 +- pnpm-lock.yaml | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2a0f132a9..45d4a2b21 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ ], "allowNonAppliedPatches": true, "overrides": { - "proxmox-api>undici": "7.4.0" + "proxmox-api>undici": "7.5.0" }, "patchedDependencies": { "pretty-print-error": "patches/pretty-print-error.patch" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ca1e920c..6d1a8ec6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - proxmox-api>undici: 7.4.0 + proxmox-api>undici: 7.5.0 patchedDependencies: pretty-print-error: @@ -9876,6 +9876,10 @@ packages: resolution: {integrity: sha512-PUQM3/es3noM24oUn10u3kNNap0AbxESOmnssmW+dOi9yGwlUSi5nTNYl3bNbTkWOF8YZDkx2tCmj9OtQ3iGGw==} engines: {node: '>=20.18.1'} + undici@7.5.0: + resolution: {integrity: sha512-NFQG741e8mJ0fLQk90xKxFdaSM7z4+IQpAgsFI36bCDY9Z2+aXXZjVy2uUksMouWfMI9+w5ejOq5zYYTBCQJDQ==} + engines: {node: '>=20.18.1'} + unenv@1.10.0: resolution: {integrity: sha512-wY5bskBQFL9n3Eca5XnhH6KbUo/tfvkwm9OpcdCvLaeA7piBNbavbOKJySEwQ1V0RH6HvNlSAFRTpvTqgKRQXQ==} @@ -17279,7 +17283,7 @@ snapshots: proxmox-api@1.1.1: dependencies: - undici: 7.4.0 + undici: 7.5.0 proxy-agent@6.4.0: dependencies: @@ -18832,6 +18836,8 @@ snapshots: undici@7.4.0: {} + undici@7.5.0: {} + unenv@1.10.0: dependencies: consola: 3.2.3 From 56fe8dd9e9ff14dc0c10a93f6798df11c2ef5761 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:23:39 +0000 Subject: [PATCH 48/60] fix(deps): update dependency undici to v7.5.0 (#2583) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- apps/tasks/package.json | 2 +- packages/certificates/package.json | 2 +- packages/common/package.json | 2 +- packages/integrations/package.json | 2 +- pnpm-lock.yaml | 16 ++++++++-------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/tasks/package.json b/apps/tasks/package.json index 6e440a553..2fd2390e0 100644 --- a/apps/tasks/package.json +++ b/apps/tasks/package.json @@ -38,7 +38,7 @@ "dayjs": "^1.11.13", "dotenv": "^16.4.7", "superjson": "2.2.2", - "undici": "7.4.0" + "undici": "7.5.0" }, "devDependencies": { "@homarr/eslint-config": "workspace:^0.2.0", diff --git a/packages/certificates/package.json b/packages/certificates/package.json index 56a257b3b..6b3fae919 100644 --- a/packages/certificates/package.json +++ b/packages/certificates/package.json @@ -23,7 +23,7 @@ "prettier": "@homarr/prettier-config", "dependencies": { "@homarr/common": "workspace:^0.1.0", - "undici": "7.4.0" + "undici": "7.5.0" }, "devDependencies": { "@homarr/eslint-config": "workspace:^0.2.0", diff --git a/packages/common/package.json b/packages/common/package.json index fe5cafdc3..dd2b1e377 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -33,7 +33,7 @@ "next": "15.1.7", "react": "19.0.0", "react-dom": "19.0.0", - "undici": "7.4.0", + "undici": "7.5.0", "zod": "^3.24.2" }, "devDependencies": { diff --git a/packages/integrations/package.json b/packages/integrations/package.json index 677a0f27d..88fcc468f 100644 --- a/packages/integrations/package.json +++ b/packages/integrations/package.json @@ -39,7 +39,7 @@ "node-ical": "^0.20.1", "proxmox-api": "1.1.1", "tsdav": "^2.1.3", - "undici": "7.4.0", + "undici": "7.5.0", "xml2js": "^0.6.2", "zod": "^3.24.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6d1a8ec6d..7a16504ae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -396,8 +396,8 @@ importers: specifier: 2.2.2 version: 2.2.2 undici: - specifier: 7.4.0 - version: 7.4.0 + specifier: 7.5.0 + version: 7.5.0 devDependencies: '@homarr/eslint-config': specifier: workspace:^0.2.0 @@ -750,8 +750,8 @@ importers: specifier: workspace:^0.1.0 version: link:../common undici: - specifier: 7.4.0 - version: 7.4.0 + specifier: 7.5.0 + version: 7.5.0 devDependencies: '@homarr/eslint-config': specifier: workspace:^0.2.0 @@ -824,8 +824,8 @@ importers: specifier: 19.0.0 version: 19.0.0(react@19.0.0) undici: - specifier: 7.4.0 - version: 7.4.0 + specifier: 7.5.0 + version: 7.5.0 zod: specifier: ^3.24.2 version: 3.24.2 @@ -1307,8 +1307,8 @@ importers: specifier: ^2.1.3 version: 2.1.3 undici: - specifier: 7.4.0 - version: 7.4.0 + specifier: 7.5.0 + version: 7.5.0 xml2js: specifier: ^0.6.2 version: 0.6.2 From d8247f2dc9a4aaa45d8e193db04295f51c44d4aa Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 19:16:10 +0000 Subject: [PATCH 49/60] fix(deps): update dependency next-intl to v4.0.1 (#2585) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- packages/translation/package.json | 2 +- pnpm-lock.yaml | 24 +++++++++--------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/packages/translation/package.json b/packages/translation/package.json index 461ddde18..9a5aaa734 100644 --- a/packages/translation/package.json +++ b/packages/translation/package.json @@ -33,7 +33,7 @@ "deepmerge": "4.3.1", "mantine-react-table": "2.0.0-beta.9", "next": "15.1.7", - "next-intl": "4.0.0", + "next-intl": "4.0.1", "react": "19.0.0", "react-dom": "19.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a16504ae..00081f4b8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1893,8 +1893,8 @@ importers: specifier: 15.1.7 version: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) next-intl: - specifier: 4.0.0 - version: 4.0.0(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2) + specifier: 4.0.1 + version: 4.0.1(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2) react: specifier: 19.0.0 version: 19.0.0 @@ -7853,8 +7853,8 @@ packages: nodemailer: optional: true - next-intl@4.0.0: - resolution: {integrity: sha512-l+I1PLAFrjzYzrc340n1vssDJ7pP1gtYT1jOWlRWIHkyrPdyosEIHPC+LiqJP4vWvWtCZzzqTn9AaBF+x5Ja8g==} + next-intl@4.0.1: + resolution: {integrity: sha512-6lqw8vv3GsjQ13lxEfgjBj7GW6kdmotiqRzDH4gQ18CGhvCwbJoj1kc5szViZH0iQZ0g8GJUque2xt7WOwqT9Q==} peerDependencies: next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 @@ -9872,10 +9872,6 @@ packages: resolution: {integrity: sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==} engines: {node: '>=14.0'} - undici@7.4.0: - resolution: {integrity: sha512-PUQM3/es3noM24oUn10u3kNNap0AbxESOmnssmW+dOi9yGwlUSi5nTNYl3bNbTkWOF8YZDkx2tCmj9OtQ3iGGw==} - engines: {node: '>=20.18.1'} - undici@7.5.0: resolution: {integrity: sha512-NFQG741e8mJ0fLQk90xKxFdaSM7z4+IQpAgsFI36bCDY9Z2+aXXZjVy2uUksMouWfMI9+w5ejOq5zYYTBCQJDQ==} engines: {node: '>=20.18.1'} @@ -9988,8 +9984,8 @@ packages: peerDependencies: react: '>=16.13' - use-intl@4.0.0: - resolution: {integrity: sha512-/fmC7haEMVNa0isXGRGUir56fD4I9LRnOgbeBmji+bow6U8pE7WD+2X2sjqh+0h3yJ0T36PA6JXZ6PlVeRyt8w==} + use-intl@4.0.1: + resolution: {integrity: sha512-UdwGqRI6M0asJK3E0+GtwJI8zrwr2yRQLtcHALMlDwUUTlGZNSCLtr2G/E4aoDfXiODbSBQwQFNco0iItp1mIA==} peerDependencies: react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 @@ -16514,13 +16510,13 @@ snapshots: next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 - next-intl@4.0.0(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2): + next-intl@4.0.1(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2): dependencies: '@formatjs/intl-localematcher': 0.5.5 negotiator: 1.0.0 next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 - use-intl: 4.0.0(react@19.0.0) + use-intl: 4.0.1(react@19.0.0) optionalDependencies: typescript: 5.8.2 @@ -18834,8 +18830,6 @@ snapshots: dependencies: '@fastify/busboy': 2.1.1 - undici@7.4.0: {} - undici@7.5.0: {} unenv@1.10.0: @@ -18951,7 +18945,7 @@ snapshots: dequal: 2.0.3 react: 19.0.0 - use-intl@4.0.0(react@19.0.0): + use-intl@4.0.1(react@19.0.0): dependencies: '@formatjs/fast-memoize': 2.2.1 '@schummar/icu-type-parser': 1.21.5 From 83eacb23b98bda967260bbb58e1f49ea4859714d Mon Sep 17 00:00:00 2001 From: "homarr-crowdin[bot]" <190541745+homarr-crowdin[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 00:47:42 +0000 Subject: [PATCH 50/60] chore(lang): updated translations from crowdin Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com> --- packages/translation/src/lang/zh.json | 198 +++++++++++++------------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/packages/translation/src/lang/zh.json b/packages/translation/src/lang/zh.json index 37dd9d49f..8dcda78d6 100644 --- a/packages/translation/src/lang/zh.json +++ b/packages/translation/src/lang/zh.json @@ -1072,7 +1072,7 @@ "label": "自定義 CSS html" }, "borderColor": { - "label": "" + "label": "邊框顏色" } } }, @@ -1129,12 +1129,12 @@ "label": "網格" }, "gridHorizontal": { - "label": "" + "label": "網格水平間距" } } }, "hideTitle": { - "label": "" + "label": "隱藏標題" }, "hideIcon": { "label": "隱藏 icons" @@ -1436,7 +1436,7 @@ "label": "終止於" }, "showUnmonitored": { - "label": "" + "label": "顯示未監控項目" } } }, @@ -1668,7 +1668,7 @@ "description": "顯示當前多媒體伺服器的串流", "option": {}, "items": { - "currentlyPlaying": "", + "currentlyPlaying": "目前播放中", "user": "使用者", "name": "名稱", "id": "ID" @@ -2325,7 +2325,7 @@ "label": "工具", "items": { "docker": "Docker", - "kubernetes": "", + "kubernetes": "Kubernetes", "logs": "Logs", "api": "API", "certificates": "憑證", @@ -2874,242 +2874,242 @@ }, "kubernetes": { "cluster": { - "title": "", - "label": "", - "providers": "", - "version": "", - "architecture": "", + "title": "叢集儀表板", + "label": "叢集", + "providers": "提供者", + "version": "版本", + "architecture": "架構", "capacity": { - "title": "", + "title": "容量", "resource": { - "reserved": "", - "used": "" + "reserved": "已保留", + "used": "已使用" } }, "resources": { - "title": "", - "nodes": "", - "namespaces": "", - "ingresses": "", - "services": "", - "pods": "", - "configmaps": "", - "secrets": "", - "volumes": "" + "title": "資源", + "nodes": "節點", + "namespaces": "命名空間", + "ingresses": "進入點", + "services": "服務", + "pods": "容器組", + "configmaps": "配置映射", + "secrets": "密鑰", + "volumes": "卷" } }, "nodes": { - "label": "", + "label": "節點", "field": { "name": { - "label": "" + "label": "名稱" }, "state": { - "label": "", + "label": "狀態", "option": { - "ready": "", - "NotReady": "" + "ready": "準備", + "NotReady": "未準備" } }, "cpu": { - "label": "" + "label": "處理器" }, "memory": { - "label": "" + "label": "記憶體" }, "pods": { - "label": "" + "label": "容器組" }, "operatingSystem": { - "label": "" + "label": "系統" }, "architecture": { - "label": "" + "label": "架構" }, "kubernetesVersion": { - "label": "" + "label": "Kubernetes 版本" }, "creationTimestamp": { - "label": "" + "label": "已創建" } }, "table": { - "search": "" + "search": "搜尋 {count} 節點" } }, "namespaces": { - "label": "", + "label": "命名空間", "field": { "name": { - "label": "" + "label": "名稱" }, "state": { - "label": "", + "label": "狀態", "option": { - "active": "", - "terminating": "" + "active": "活動中", + "terminating": "終止中" } }, "creationTimestamp": { - "label": "" + "label": "已創建" } }, "table": { - "search": "" + "search": "搜尋 {count} 命名空間" } }, "ingresses": { - "label": "", + "label": "進入點", "field": { "name": { - "label": "" + "label": "名稱" }, "namespace": { - "label": "" + "label": "命名空間" }, "className": { - "label": "" + "label": "類別名稱" }, "rulesAndPaths": { - "label": "" + "label": "規則與路徑" }, "creationTimestamp": { - "label": "" + "label": "已創建" } }, "table": { - "search": "" + "search": "搜尋 {count} 進入點" } }, "services": { - "label": "", + "label": "服務", "field": { "name": { - "label": "" + "label": "名稱" }, "namespace": { - "label": "" + "label": "命名空間" }, "type": { - "label": "" + "label": "類別" }, "ports": { - "label": "" + "label": "Ports" }, "targetPorts": { - "label": "" + "label": "目標 Ports" }, "clusterIP": { - "label": "" + "label": "叢集 IP" }, "creationTimestamp": { - "label": "" + "label": "已創建" } }, "table": { - "search": "" + "search": "搜尋 {count} 服務" } }, "pods": { - "label": "", + "label": "容器組", "field": { "name": { - "label": "" + "label": "名稱" }, "namespace": { - "label": "" + "label": "命名空間" }, "image": { - "label": "" + "label": "Image" }, "applicationType": { - "label": "" + "label": "應用程式類別" }, "status": { - "label": "" + "label": "狀態" }, "creationTimestamp": { - "label": "" + "label": "已創建" } }, "table": { - "search": "" + "search": "搜尋 {count} 容器組" } }, "secrets": { - "label": "", + "label": "密鑰", "field": { "name": { - "label": "" + "label": "名稱" }, "namespace": { - "label": "" + "label": "命名空間" }, "type": { - "label": "" + "label": "類別" }, "creationTimestamp": { - "label": "" + "label": "已創建" } }, "table": { - "search": "" + "search": "搜尋 {count} 密鑰" } }, "configmaps": { - "label": "", + "label": "配置映射", "field": { "name": { - "label": "" + "label": "名稱" }, "namespace": { - "label": "" + "label": "命名空間" }, "creationTimestamp": { - "label": "" + "label": "已創建" } }, "table": { - "search": "" + "search": "搜尋 {count} 配置映射" } }, "volumes": { - "label": "", + "label": "卷", "field": { "name": { - "label": "" + "label": "名稱" }, "namespace": { - "label": "" + "label": "命名空間" }, "accessModes": { - "label": "" + "label": "存取模式" }, "storage": { - "label": "" + "label": "儲存容量" }, "storageClassName": { - "label": "" + "label": "儲存類別名稱" }, "volumeMode": { - "label": "" + "label": "卷模式" }, "volumeName": { - "label": "" + "label": "卷名稱" }, "status": { - "label": "" + "label": "狀態" }, "creationTimestamp": { - "label": "" + "label": "已創建" } }, "table": { - "search": "" + "search": "搜尋 {count} 卷" } }, "error": { - "internalServerError": "" + "internalServerError": "無法擷取 Kubernetes 資料" } }, "permission": { @@ -3198,30 +3198,30 @@ "label": "Docker" }, "kubernetes": { - "label": "", + "label": "Kubernetes", "nodes": { - "label": "" + "label": "節點" }, "namespaces": { - "label": "" + "label": "命名空間" }, "ingresses": { - "label": "" + "label": "進入點" }, "services": { - "label": "" + "label": "服務" }, "pods": { - "label": "" + "label": "容器組" }, "configmaps": { - "label": "" + "label": "配置映射" }, "secrets": { - "label": "" + "label": "密鑰" }, "volumes": { - "label": "" + "label": "卷" } }, "logs": { From b607c5702fd2bf86be8b56d7b7b00435363095e0 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 14:18:13 +0000 Subject: [PATCH 51/60] fix(deps): update dependency next-intl to v4.0.2 (#2589) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- packages/translation/package.json | 2 +- pnpm-lock.yaml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/translation/package.json b/packages/translation/package.json index 9a5aaa734..550ffc5cf 100644 --- a/packages/translation/package.json +++ b/packages/translation/package.json @@ -33,7 +33,7 @@ "deepmerge": "4.3.1", "mantine-react-table": "2.0.0-beta.9", "next": "15.1.7", - "next-intl": "4.0.1", + "next-intl": "4.0.2", "react": "19.0.0", "react-dom": "19.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 00081f4b8..76ea6a5ab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1893,8 +1893,8 @@ importers: specifier: 15.1.7 version: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) next-intl: - specifier: 4.0.1 - version: 4.0.1(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2) + specifier: 4.0.2 + version: 4.0.2(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2) react: specifier: 19.0.0 version: 19.0.0 @@ -7853,8 +7853,8 @@ packages: nodemailer: optional: true - next-intl@4.0.1: - resolution: {integrity: sha512-6lqw8vv3GsjQ13lxEfgjBj7GW6kdmotiqRzDH4gQ18CGhvCwbJoj1kc5szViZH0iQZ0g8GJUque2xt7WOwqT9Q==} + next-intl@4.0.2: + resolution: {integrity: sha512-3cKVflwdrqxCOvAL+DtGN68qR802i0PEj0dttkAD5IK5XxOjugQs4yU8aSakvPMbkOrhEJ+89z5lG2EAqi7Gkw==} peerDependencies: next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 @@ -9984,8 +9984,8 @@ packages: peerDependencies: react: '>=16.13' - use-intl@4.0.1: - resolution: {integrity: sha512-UdwGqRI6M0asJK3E0+GtwJI8zrwr2yRQLtcHALMlDwUUTlGZNSCLtr2G/E4aoDfXiODbSBQwQFNco0iItp1mIA==} + use-intl@4.0.2: + resolution: {integrity: sha512-6RAP/5KJMRzLMLS25/BVh2u09cRK8S6HRGc1RnZvqR547qAKZCpjYylOqMPU9eNIirAiKoGmsoUPa7JrlaA/yg==} peerDependencies: react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 @@ -16510,13 +16510,13 @@ snapshots: next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 - next-intl@4.0.1(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2): + next-intl@4.0.2(next@15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1))(react@19.0.0)(typescript@5.8.2): dependencies: '@formatjs/intl-localematcher': 0.5.5 negotiator: 1.0.0 next: 15.1.7(@babel/core@7.26.0)(@playwright/test@1.49.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.85.1) react: 19.0.0 - use-intl: 4.0.1(react@19.0.0) + use-intl: 4.0.2(react@19.0.0) optionalDependencies: typescript: 5.8.2 @@ -18945,7 +18945,7 @@ snapshots: dequal: 2.0.3 react: 19.0.0 - use-intl@4.0.1(react@19.0.0): + use-intl@4.0.2(react@19.0.0): dependencies: '@formatjs/fast-memoize': 2.2.1 '@schummar/icu-type-parser': 1.21.5 From bb20999bf39518a12837cdd5fa66e22e34624d4d Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 14:37:46 +0000 Subject: [PATCH 52/60] chore(deps): update pnpm to v10.6.3 (#2590) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45d4a2b21..863e076c7 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.8" }, - "packageManager": "pnpm@10.6.2", + "packageManager": "pnpm@10.6.3", "engines": { "node": ">=22.14.0" }, From 8a02c656488bf0f239b8f394d73ed63ade8f61ed Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 15:19:00 +0000 Subject: [PATCH 53/60] fix(deps): update dependency @kubernetes/client-node to ^1.1.0 (#2591) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- packages/api/package.json | 2 +- pnpm-lock.yaml | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index 31667a3a4..66b56ddf6 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -40,7 +40,7 @@ "@homarr/request-handler": "workspace:^0.1.0", "@homarr/server-settings": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0", - "@kubernetes/client-node": "^1.0.0", + "@kubernetes/client-node": "^1.1.0", "@trpc/client": "next", "@trpc/react-query": "next", "@trpc/server": "next", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76ea6a5ab..66a1da2a9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -579,8 +579,8 @@ importers: specifier: workspace:^0.1.0 version: link:../validation '@kubernetes/client-node': - specifier: ^1.0.0 - version: 1.0.0 + specifier: ^1.1.0 + version: 1.1.0 '@trpc/client': specifier: next version: 11.0.0-rc.828(@trpc/server@11.0.0-rc.828(typescript@5.8.2))(typescript@5.8.2) @@ -3503,8 +3503,8 @@ packages: peerDependencies: jsep: ^0.4.0||^1.0.0 - '@kubernetes/client-node@1.0.0': - resolution: {integrity: sha512-a8NSvFDSHKFZ0sR1hbPSf8IDFNJwctEU5RodSCNiq/moRXWmrdmqhb1RRQzF+l+TSBaDgHw3YsYNxxE92STBzw==} + '@kubernetes/client-node@1.1.0': + resolution: {integrity: sha512-6Sp7ekNfMmDH2HvEQLb8vuPu+mX0xNkPElQLX5N/mjxeMimFWfecZeiFfIaG+Q9S1v+snZfTNJjvpOwNUVO7RA==} '@libsql/client-wasm@0.14.0': resolution: {integrity: sha512-gB/jtz0xuwrqAHApBv9e9JSew2030Fhj2edyZ83InZ4yPj/Q2LTUlEhaspEYT0T0xsAGqPy38uGrmq/OGS+DdQ==} @@ -6866,6 +6866,10 @@ packages: resolution: {integrity: sha512-sYKnA7eGln5ov8T8gnYlkSOxFJvywzEx9BueN6xo/GKO8PGiI6uK6xx+DIGe45T3bdVjLAQDQW1aicT8z8JwQg==} engines: {node: ^18.17.0 || >=20.5.0} + hpagent@1.2.0: + resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==} + engines: {node: '>=14'} + html-encoding-sniffer@4.0.0: resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} engines: {node: '>=18'} @@ -11378,7 +11382,7 @@ snapshots: dependencies: jsep: 1.4.0 - '@kubernetes/client-node@1.0.0': + '@kubernetes/client-node@1.1.0': dependencies: '@types/js-yaml': 4.0.9 '@types/node': 22.13.10 @@ -11387,20 +11391,22 @@ snapshots: '@types/tar': 6.1.13 '@types/ws': 8.18.0 form-data: 4.0.1 + hpagent: 1.2.0 isomorphic-ws: 5.0.0(ws@8.18.1) js-yaml: 4.1.0 jsonpath-plus: 10.3.0 node-fetch: 2.7.0 openid-client: 6.3.3 rfc4648: 1.5.3 + socks-proxy-agent: 8.0.4 stream-buffers: 3.0.3 tar: 7.4.3 tmp-promise: 3.0.3 - tslib: 2.8.1 ws: 8.18.1 transitivePeerDependencies: - bufferutil - encoding + - supports-color - utf-8-validate '@libsql/client-wasm@0.14.0': @@ -15550,6 +15556,8 @@ snapshots: dependencies: lru-cache: 10.4.3 + hpagent@1.2.0: {} + html-encoding-sniffer@4.0.0: dependencies: whatwg-encoding: 3.1.1 From 22f91666908c6a140fadd89f52f57a57a51cd935 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Thu, 13 Mar 2025 23:23:54 +0100 Subject: [PATCH 54/60] feat(integrations): add checkbox to add app (#2463) --- .../new/_integration-new-form.tsx | 86 ++++++++++++++++--- packages/translation/src/lang/en.json | 7 ++ 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx index cb286217e..ed93ba822 100644 --- a/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx +++ b/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx @@ -1,16 +1,27 @@ "use client"; -import { useCallback } from "react"; +import { useCallback, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; -import { Alert, Button, Checkbox, Fieldset, Group, SegmentedControl, Stack, Text, TextInput } from "@mantine/core"; +import { + Alert, + Button, + Checkbox, + Collapse, + Fieldset, + Group, + SegmentedControl, + Stack, + Text, + TextInput, +} from "@mantine/core"; import { IconInfoCircle } from "@tabler/icons-react"; -import type { z } from "zod"; +import { z } from "zod"; import { clientApi } from "@homarr/api/client"; import { revalidatePathActionAsync } from "@homarr/common/client"; import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions"; -import { getAllSecretKindOptions, getIntegrationName, integrationDefs } from "@homarr/definitions"; +import { getAllSecretKindOptions, getIconUrl, getIntegrationName, integrationDefs } from "@homarr/definitions"; import type { UseFormReturnType } from "@homarr/form"; import { useZodForm } from "@homarr/form"; import { convertIntegrationTestConnectionError } from "@homarr/integrations/client"; @@ -26,11 +37,19 @@ interface NewIntegrationFormProps { }; } +const formSchema = validation.integration.create.omit({ kind: true }).and( + z.object({ + createApp: z.boolean(), + appHref: validation.app.manage.shape.href, + }), +); + export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) => { const t = useI18n(); const secretKinds = getAllSecretKindOptions(searchParams.kind); const router = useRouter(); - const form = useZodForm(validation.integration.create.omit({ kind: true }), { + const [opened, setOpened] = useState(false); + const form = useZodForm(formSchema, { initialValues: { name: searchParams.name ?? getIntegrationName(searchParams.kind), url: searchParams.url ?? "", @@ -39,23 +58,60 @@ export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) => value: "", })), attemptSearchEngineCreation: true, + createApp: false, + appHref: "", + }, + onValuesChange(values, previous) { + if (values.createApp !== previous.createApp) { + setOpened(values.createApp); + } }, }); - const { mutateAsync, isPending } = clientApi.integration.create.useMutation(); + + const { mutateAsync: createIntegrationAsync, isPending: isPendingIntegration } = + clientApi.integration.create.useMutation(); + const { mutateAsync: createAppAsync, isPending: isPendingApp } = clientApi.app.create.useMutation(); + const isPending = isPendingIntegration || isPendingApp; const handleSubmitAsync = async (values: FormType) => { - await mutateAsync( + await createIntegrationAsync( { kind: searchParams.kind, ...values, }, { - onSuccess: () => { + async onSuccess() { showSuccessNotification({ title: t("integration.page.create.notification.success.title"), message: t("integration.page.create.notification.success.message"), }); - void revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations")); + + if (!values.createApp) { + await revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations")); + return; + } + + const hasCustomHref = values.appHref !== null && values.appHref.trim().length >= 1; + await createAppAsync( + { + name: values.name, + href: hasCustomHref ? values.appHref : values.url, + iconUrl: getIconUrl(searchParams.kind), + description: null, + pingUrl: values.url, + }, + { + async onSettled() { + await revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations")); + }, + onError() { + showErrorNotification({ + title: t("app.page.create.notification.error.title"), + message: t("app.page.create.notification.error.message"), + }); + }, + }, + ); }, onError: (error) => { const testConnectionError = convertIntegrationTestConnectionError(error.data?.error); @@ -117,6 +173,16 @@ export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) => /> )} + + + + + +