refactor: consolidate English translations (#6640)
This commit is contained in:
1 parent
81aa704537
commit
9e14a07e64
449 files changed
+3515
-3922
No files matched your search
@@ -3,7 +3,7 @@
|
||||
import { Badge, Group, Paper, Stack, Table, Text, ThemeIcon, Title } from "@mantine/core";
|
||||
import { IconCheck, IconDatabase, IconGitBranch } from "@tabler/icons-react";
|
||||
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { BackupAnalysis } from "./types";
|
||||
import { PREVIEW_TABLE_KEYS } from "./types";
|
||||
@@ -13,10 +13,25 @@ interface BackupPreviewPanelProps {
|
||||
}
|
||||
|
||||
export const BackupPreviewPanel = ({ analysis }: BackupPreviewPanelProps) => {
|
||||
const t = useScopedI18n("management.page.tool.backup.restore.preview");
|
||||
const t = useI18n("management.page.tool.backup.restore.preview");
|
||||
const tEntities = useI18n("common.entity");
|
||||
const exportDate = new Date(analysis.metadata.exportedAt).toLocaleString();
|
||||
const pendingCount = analysis.migrations.pending.length;
|
||||
const hasPendingMigrations = pendingCount > 0;
|
||||
const entityKeys = {
|
||||
app: "apps",
|
||||
board: "boards",
|
||||
integration: "integrations",
|
||||
item: undefined,
|
||||
media: "media",
|
||||
search_engine: "searchEngines",
|
||||
user: "users",
|
||||
} as const;
|
||||
const getEntityLabel = (key: (typeof PREVIEW_TABLE_KEYS)[number]) => {
|
||||
const entityKey = entityKeys[key];
|
||||
if (entityKey) return tEntities(entityKey);
|
||||
return t(`entities.${key}` as never);
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap="md">
|
||||
@@ -47,7 +62,7 @@ export const BackupPreviewPanel = ({ analysis }: BackupPreviewPanelProps) => {
|
||||
<Table.Tbody>
|
||||
{PREVIEW_TABLE_KEYS.map((key) => (
|
||||
<Table.Tr key={key}>
|
||||
<Table.Td>{t(`entities.${key}` as never)}</Table.Td>
|
||||
<Table.Td>{getEntityLabel(key)}</Table.Td>
|
||||
<Table.Td ta="right">
|
||||
<Group gap={4} justify="flex-end">
|
||||
{(analysis.counts[key] ?? 0) > 0 && <IconCheck size={14} color="var(--mantine-color-green-6)" />}
|
||||
@@ -64,7 +79,7 @@ export const BackupPreviewPanel = ({ analysis }: BackupPreviewPanelProps) => {
|
||||
{analysis.boardNames.length > 0 && (
|
||||
<Group gap="xs" wrap="wrap">
|
||||
<Text size="sm" fw={500}>
|
||||
{t("boards")}:
|
||||
{tEntities("boards")}:
|
||||
</Text>
|
||||
{analysis.boardNames.map((name) => (
|
||||
<Badge key={name} variant="light" size="sm">
|
||||
|
||||
@@ -8,7 +8,7 @@ import { IconAlertTriangle, IconArrowRight, IconFileZip, IconUpload, IconX } fro
|
||||
|
||||
import "@mantine/dropzone/styles.css"; // oxlint-disable-line import/no-unassigned-import
|
||||
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { RestoreStep } from "./types";
|
||||
import { BackupPreviewPanel } from "./backup-preview-panel";
|
||||
@@ -103,7 +103,8 @@ export const waitForServerReadinessAsync = async ({
|
||||
};
|
||||
|
||||
export const DatabaseRestoreFlow = ({ variant = "card", onRestoreComplete }: DatabaseRestoreFlowProps) => {
|
||||
const t = useScopedI18n("management.page.tool.backup.restore");
|
||||
const t = useI18n("management.page.tool.backup.restore");
|
||||
const tCommon = useI18n("common");
|
||||
const [file, setFile] = useState<FileWithPath | null>(null);
|
||||
const [step, setStep] = useState<RestoreStep>("upload");
|
||||
const [importError, setImportError] = useState<string | null>(null);
|
||||
@@ -330,7 +331,7 @@ export const DatabaseRestoreFlow = ({ variant = "card", onRestoreComplete }: Dat
|
||||
</Alert>
|
||||
<Group>
|
||||
<Button variant="subtle" onClick={handleClear}>
|
||||
{t("tryAgain")}
|
||||
{tCommon("action.tryAgain")}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Box, Group, Loader, Paper, Stack, Text, ThemeIcon, Timeline } from "@mantine/core";
|
||||
import { IconCheck, IconDatabase, IconLoader } from "@tabler/icons-react";
|
||||
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { MigrationProgress } from "./use-backup-analysis";
|
||||
|
||||
@@ -12,7 +12,7 @@ interface MigrationProgressPanelProps {
|
||||
}
|
||||
|
||||
export const MigrationProgressPanel = ({ progress }: MigrationProgressPanelProps) => {
|
||||
const t = useScopedI18n("management.page.tool.backup.restore.migration");
|
||||
const t = useI18n("management.page.tool.backup.restore.migration");
|
||||
|
||||
return (
|
||||
<Paper p="md" radius="md" bg="var(--mantine-color-dark-7)">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { IconDatabaseImport } from "@tabler/icons-react";
|
||||
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
|
||||
import { DangerousActionConfirmation } from "./dangerous-action-confirmation";
|
||||
|
||||
@@ -13,17 +13,19 @@ interface RestoreConfirmationProps {
|
||||
}
|
||||
|
||||
export const RestoreConfirmation = ({ onConfirm, onCancel, disabled }: RestoreConfirmationProps) => {
|
||||
const t = useScopedI18n("management.page.tool.backup.restore.confirm");
|
||||
const t = useI18n("management.page.tool.backup.restore.confirm");
|
||||
const tBackup = useI18n("management.page.tool.backup");
|
||||
const tCommon = useI18n("common");
|
||||
|
||||
return (
|
||||
<DangerousActionConfirmation
|
||||
title={t("title")}
|
||||
warningTitle={t("warningTitle")}
|
||||
warningBody={t("warningBody")}
|
||||
typePrompt={t("typePrompt", { phrase: "I understand" })}
|
||||
typePrompt={tBackup("confirm.typePrompt", { phrase: "I understand" })}
|
||||
submitLabel={t("submit")}
|
||||
submitIcon={<IconDatabaseImport size={16} />}
|
||||
cancelLabel={t("cancel")}
|
||||
cancelLabel={tCommon("action.cancel")}
|
||||
onConfirm={onConfirm}
|
||||
onCancel={onCancel}
|
||||
disabled={disabled}
|
||||
|
||||
@@ -7,16 +7,18 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("@homarr/translation/client", () => {
|
||||
const translations: Record<string, string> = {
|
||||
"progress.title": "Restoring database...",
|
||||
"progress.restarting": "Restarting server",
|
||||
"timeout.title": "Server did not come back online",
|
||||
"timeout.message": "Retry the connection check or refresh this page manually.",
|
||||
tryAgain: "Try again",
|
||||
"docker.action.refresh.label": "Refresh",
|
||||
"management.page.tool.backup.restore.progress.title": "Restoring database...",
|
||||
"management.page.tool.backup.restore.progress.restarting": "Restarting server",
|
||||
"management.page.tool.backup.restore.timeout.title": "Server did not come back online",
|
||||
"management.page.tool.backup.restore.timeout.message": "Retry the connection check or refresh this page manually.",
|
||||
"common.action.tryAgain": "Try again",
|
||||
"common.action.refresh": "Refresh",
|
||||
};
|
||||
return {
|
||||
useScopedI18n: () => (key: string) => translations[key] ?? key,
|
||||
useI18n: () => (key: string) => translations[key] ?? key,
|
||||
useI18n: (namespace?: string) => (key: string) => {
|
||||
const fullKey = namespace ? `${namespace}.${key}` : key;
|
||||
return translations[fullKey] ?? key;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Button, Group, Loader, Paper, Stack, Text, ThemeIcon } from "@mantine/c
|
||||
import { useReducedMotion } from "@mantine/hooks";
|
||||
import { IconAlertTriangle, IconCheck, IconDatabaseImport, IconRefresh } from "@tabler/icons-react";
|
||||
|
||||
import { useI18n, useScopedI18n } from "@homarr/translation/client";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
|
||||
export type RestoreProgressStatus = "restoring" | "restarting" | "timedOut";
|
||||
|
||||
@@ -16,8 +16,8 @@ interface RestoreProgressPanelProps {
|
||||
}
|
||||
|
||||
export const RestoreProgressPanel = ({ active, status, onRetry, onReload }: RestoreProgressPanelProps) => {
|
||||
const t = useScopedI18n("management.page.tool.backup.restore");
|
||||
const tRoot = useI18n();
|
||||
const t = useI18n("management.page.tool.backup.restore");
|
||||
const tCommon = useI18n("common");
|
||||
const reduceMotion = useReducedMotion();
|
||||
|
||||
if (!active) return null;
|
||||
@@ -66,10 +66,10 @@ export const RestoreProgressPanel = ({ active, status, onRetry, onReload }: Rest
|
||||
{isTimedOut ? (
|
||||
<Group>
|
||||
<Button variant="light" onClick={onRetry} leftSection={<IconRefresh size={16} />}>
|
||||
{t("tryAgain")}
|
||||
{tCommon("action.tryAgain")}
|
||||
</Button>
|
||||
<Button variant="default" onClick={onReload}>
|
||||
{tRoot("docker.action.refresh.label")}
|
||||
{tCommon("action.refresh")}
|
||||
</Button>
|
||||
</Group>
|
||||
) : null}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
import { useTiks } from "@rexa-developer/tiks/react";
|
||||
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { BackupAnalysis, MigrationFile, MigrationStatus } from "./types";
|
||||
import { PREVIEW_TABLE_KEYS } from "./types";
|
||||
@@ -60,7 +60,7 @@ export interface MigrationProgress {
|
||||
}
|
||||
|
||||
export const useBackupAnalysis = () => {
|
||||
const t = useScopedI18n("management.page.tool.backup.restore");
|
||||
const t = useI18n("management.page.tool.backup.restore");
|
||||
const sounds = useTiks({ theme: "soft", volume: 0.12, respectReducedMotion: true });
|
||||
const [analysis, setAnalysis] = useState<BackupAnalysis | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
Reference in new issue
Block a user