diff --git a/plugins/file-manager/locales/en.json b/plugins/file-manager/locales/en.json index 04d10bddb..dc86761ce 100644 --- a/plugins/file-manager/locales/en.json +++ b/plugins/file-manager/locales/en.json @@ -379,7 +379,11 @@ "dragFilesToDesktop": "Dragging {{count}} files to the desktop", "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", "saveToDesktopFailed": "Save failed: {{error}}", - "dragFailedDetail": "Drag failed: {{error}}" + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." }, "sftpTransfer": { "title": "SFTP", diff --git a/plugins/file-manager/src/frontend/components/FileViewer.tsx b/plugins/file-manager/src/frontend/components/FileViewer.tsx index 3bc4339cb..741a3f68e 100644 --- a/plugins/file-manager/src/frontend/components/FileViewer.tsx +++ b/plugins/file-manager/src/frontend/components/FileViewer.tsx @@ -790,10 +790,7 @@ export function FileViewer({
-

- Your browser does not support video playback for this - format. -

+

{t("fileManager.videoUnsupported")}

{onDownload && ( )}
@@ -918,11 +915,10 @@ export function FileViewer({

- Cannot preview this file type + {t("fileManager.cannotPreviewType")}

- This file type is not supported for preview. You can download - it to view in an external application. + {t("fileManager.cannotPreviewTypeHint")}

{onDownload && (
diff --git a/plugins/homepage/src/frontend/widgets/BookmarkListWidget.tsx b/plugins/homepage/src/frontend/widgets/BookmarkListWidget.tsx index b3d573ee8..2d8212876 100644 --- a/plugins/homepage/src/frontend/widgets/BookmarkListWidget.tsx +++ b/plugins/homepage/src/frontend/widgets/BookmarkListWidget.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from "@termix/plugin-sdk/frontend"; import { Bookmark, ExternalLink } from "lucide-react"; import { registerWidget } from "./WidgetRegistry"; import type { BookmarkListConfig, WidgetComponentProps } from "../types.js"; @@ -8,6 +9,7 @@ function BookmarkListWidget({ widget, isReadOnly, }: WidgetComponentProps) { + const { t } = useTranslation(); const { links } = config; return ( @@ -23,7 +25,7 @@ function BookmarkListWidget({
{links.length === 0 && ( - No bookmarks + {t("homepage.noBookmarks")} )} {links.map((link, i) => diff --git a/plugins/homepage/src/frontend/widgets/IframeWidget.tsx b/plugins/homepage/src/frontend/widgets/IframeWidget.tsx index 33309bc89..9b8cd8f72 100644 --- a/plugins/homepage/src/frontend/widgets/IframeWidget.tsx +++ b/plugins/homepage/src/frontend/widgets/IframeWidget.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from "@termix/plugin-sdk/frontend"; import { Globe } from "lucide-react"; import { registerWidget } from "./WidgetRegistry"; import type { IframeConfig, WidgetComponentProps } from "../types.js"; @@ -9,13 +10,14 @@ function IframeWidget({ config, isReadOnly, }: WidgetComponentProps) { + const { t } = useTranslation(); const { url, scrolling } = config; if (!url) { return (
- Configure a URL in widget settings + {t("homepage.configureUrl")}
); } @@ -29,7 +31,7 @@ function IframeWidget({ sandbox="allow-scripts allow-same-origin allow-forms allow-popups" scrolling={scrolling ? "yes" : "no"} className="w-full h-full border-0" - title="Embedded content" + title={t("homepage.embeddedContent")} /> {/* Block interaction in read-only mode so the canvas can still pan */} {isReadOnly &&
} diff --git a/plugins/homepage/src/frontend/widgets/LinkTreeWidget.tsx b/plugins/homepage/src/frontend/widgets/LinkTreeWidget.tsx index 050bafc13..e53a33be1 100644 --- a/plugins/homepage/src/frontend/widgets/LinkTreeWidget.tsx +++ b/plugins/homepage/src/frontend/widgets/LinkTreeWidget.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from "@termix/plugin-sdk/frontend"; import { useRef } from "react"; import { List, ExternalLink } from "lucide-react"; import { registerWidget } from "./WidgetRegistry"; @@ -72,12 +73,13 @@ function LinkTreeWidget({ config, isReadOnly, }: WidgetComponentProps) { + const { t } = useTranslation(); const { sections, compact } = config; if (sections.length === 0) { return (
- No sections configured + {t("homepage.noSections")}
); } diff --git a/plugins/homepage/src/frontend/widgets/ServiceGridWidget.tsx b/plugins/homepage/src/frontend/widgets/ServiceGridWidget.tsx index bf02cad90..af3e2f512 100644 --- a/plugins/homepage/src/frontend/widgets/ServiceGridWidget.tsx +++ b/plugins/homepage/src/frontend/widgets/ServiceGridWidget.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from "@termix/plugin-sdk/frontend"; import { useRef, useState, useEffect } from "react"; import { Grid3x3, ExternalLink } from "lucide-react"; import { registerWidget } from "./WidgetRegistry"; @@ -107,12 +108,13 @@ function ServiceGridWidget({ config, isReadOnly, }: WidgetComponentProps) { + const { t } = useTranslation(); const { services, columns, showLabels, iconSize } = config; if (services.length === 0) { return (
- No services configured + {t("homepage.noServices")}
); } diff --git a/plugins/homepage/src/frontend/widgets/TextBannerWidget.tsx b/plugins/homepage/src/frontend/widgets/TextBannerWidget.tsx index b1c450b3a..b3bfb80d0 100644 --- a/plugins/homepage/src/frontend/widgets/TextBannerWidget.tsx +++ b/plugins/homepage/src/frontend/widgets/TextBannerWidget.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from "@termix/plugin-sdk/frontend"; import { Type } from "lucide-react"; import { registerWidget } from "./WidgetRegistry"; import type { TextBannerConfig, WidgetComponentProps } from "../types.js"; @@ -23,6 +24,7 @@ const TEXT_ALIGN_MAP = { }; function TextBannerWidget({ config }: WidgetComponentProps) { + const { t } = useTranslation(); const { text, fontSize, textAlign, fontWeight, backgroundColor } = config; return ( @@ -31,7 +33,7 @@ function TextBannerWidget({ config }: WidgetComponentProps) { style={backgroundColor ? { background: backgroundColor } : undefined} > - {text || "Banner text"} + {text || t("homepage.bannerTextPlaceholder")}
); diff --git a/plugins/homepage/src/frontend/widgets/WeatherWidget.tsx b/plugins/homepage/src/frontend/widgets/WeatherWidget.tsx index 1017cdd70..c1d813e50 100644 --- a/plugins/homepage/src/frontend/widgets/WeatherWidget.tsx +++ b/plugins/homepage/src/frontend/widgets/WeatherWidget.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from "@termix/plugin-sdk/frontend"; import { useEffect, useState } from "react"; import { Cloud, @@ -54,6 +55,7 @@ function WeatherWidget({ widget, config, }: WidgetComponentProps) { + const { t } = useTranslation(); const { location, unit, showForecast } = config; const [data, setData] = useState(null); const [error, setError] = useState(false); @@ -90,7 +92,7 @@ function WeatherWidget({ if (!location) { return (
- Configure a location in widget settings + {t("homepage.configureLocation")}
); } diff --git a/plugins/host-metrics/locales/en.json b/plugins/host-metrics/locales/en.json index b355fd3df..fc32b9c85 100644 --- a/plugins/host-metrics/locales/en.json +++ b/plugins/host-metrics/locales/en.json @@ -177,7 +177,8 @@ "wgAllowedIPs": "Allowed IPs", "wgLastHandshake": "Last handshake", "wgHandshakeNever": "Never", - "wgTransfer": "Transfer" + "wgTransfer": "Transfer", + "wgNoPeers": "No peers" } }, "metricsHistory": { diff --git a/plugins/host-metrics/src/frontend/cards/managers/WireGuardManagerCard.tsx b/plugins/host-metrics/src/frontend/cards/managers/WireGuardManagerCard.tsx index 5540c4526..ac53ea1db 100644 --- a/plugins/host-metrics/src/frontend/cards/managers/WireGuardManagerCard.tsx +++ b/plugins/host-metrics/src/frontend/cards/managers/WireGuardManagerCard.tsx @@ -162,7 +162,7 @@ export function WireGuardManagerCard({ hostId }: { hostId: number | null }) {
{iface.peers.length === 0 ? ( - No peers + {t("hostMetrics.managers.wgNoPeers")} ) : ( iface.peers.map((peer) => ( diff --git a/plugins/remote-desktop/locales/en.json b/plugins/remote-desktop/locales/en.json index 2bd8eb375..0cb1161b4 100644 --- a/plugins/remote-desktop/locales/en.json +++ b/plugins/remote-desktop/locales/en.json @@ -208,7 +208,8 @@ "colorScheme": "Color Scheme", "backspaceKey": "Backspace Key", "colorDepth": "Color Depth", - "resizeMethod": "Resize Method" + "resizeMethod": "Resize Method", + "driveNamePlaceholder": "Termix Drive" }, "remoteDesktop": "Remote Desktop", "tabRdp": "RDP", diff --git a/plugins/remote-desktop/src/frontend/HostEditorGuacamoleTabs.tsx b/plugins/remote-desktop/src/frontend/HostEditorGuacamoleTabs.tsx index e5e655726..4795bef1d 100644 --- a/plugins/remote-desktop/src/frontend/HostEditorGuacamoleTabs.tsx +++ b/plugins/remote-desktop/src/frontend/HostEditorGuacamoleTabs.tsx @@ -523,7 +523,7 @@ export function HostEditorRdpTab({ {t("hosts.guac.driveName")} setGuacField("drive-name", e.target.value)} /> diff --git a/plugins/session-recording/locales/en.json b/plugins/session-recording/locales/en.json index 9933a7b4f..015542edd 100644 --- a/plugins/session-recording/locales/en.json +++ b/plugins/session-recording/locales/en.json @@ -45,5 +45,9 @@ "loadError": "Failed to load session logs", "deleteError": "Failed to delete session log", "filterByHost": "Filter by host..." + }, + "player": { + "timeline": "Recording timeline", + "speed": "Playback speed" } } diff --git a/plugins/session-recording/src/frontend/SessionRecordingPlayer.tsx b/plugins/session-recording/src/frontend/SessionRecordingPlayer.tsx index 6bfe04244..899100d0c 100644 --- a/plugins/session-recording/src/frontend/SessionRecordingPlayer.tsx +++ b/plugins/session-recording/src/frontend/SessionRecordingPlayer.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from "@termix/plugin-sdk/frontend"; import { useCallback, useEffect, useRef, useState } from "react"; import { Pause, Play } from "lucide-react"; import { Terminal } from "@xterm/xterm"; @@ -36,6 +37,7 @@ function PlaybackControls({ onSeek: (position: number) => void; onSpeed: (speed: number) => void; }) { + const { t } = useTranslation(); return (