No comments.
+
{comments.map((comment) => (
@@ -111,20 +127,29 @@ export function AzureDevOpsFeedbackDialog({
feedback: AzureDevOpsPullRequestFeedback | null;
onOpenChange: (open: boolean) => void;
}) {
+ const { t } = useTranslation();
return (
);
diff --git a/apps/web/components/azure-devops/azure-devops-pull-request-pagination.tsx b/apps/web/components/azure-devops/azure-devops-pull-request-pagination.tsx
index 772116a977..7d521034bc 100644
--- a/apps/web/components/azure-devops/azure-devops-pull-request-pagination.tsx
+++ b/apps/web/components/azure-devops/azure-devops-pull-request-pagination.tsx
@@ -1,5 +1,6 @@
import { IconChevronLeft, IconChevronRight } from "@tabler/icons-react";
import { Button } from "@kandev/ui/button";
+import { useTranslation } from "react-i18next";
type Props = {
skip: number;
@@ -16,6 +17,7 @@ export function AzureDevOpsPullRequestPagination({
pageSize,
onPage,
}: Props) {
+ const { t } = useTranslation();
if (skip === 0 && count < pageSize) return null;
return (
@@ -30,7 +32,7 @@ export function AzureDevOpsPullRequestPagination({
onClick={() => onPage(Math.max(0, skip - pageSize))}
disabled={loading || skip === 0}
className="cursor-pointer"
- aria-label="Previous pull request page"
+ aria-label={t("azuredevops:previousPullRequestPage")}
>
@@ -41,7 +43,7 @@ export function AzureDevOpsPullRequestPagination({
onClick={() => onPage(skip + pageSize)}
disabled={loading || count < pageSize}
className="cursor-pointer"
- aria-label="Next pull request page"
+ aria-label={t("azuredevops:nextPullRequestPage")}
>
diff --git a/apps/web/components/azure-devops/azure-devops-results.tsx b/apps/web/components/azure-devops/azure-devops-results.tsx
index 3c8a92738e..5f7c9280f7 100644
--- a/apps/web/components/azure-devops/azure-devops-results.tsx
+++ b/apps/web/components/azure-devops/azure-devops-results.tsx
@@ -19,29 +19,46 @@ import type {
AzureDevOpsPullRequest,
AzureDevOpsWorkItem,
} from "@/lib/types/azure-devops";
+import { useTranslation } from "react-i18next";
function EmptyResult({ loading, error }: { loading: boolean; error: string | null }) {
- if (loading) return
Loading results...
;
+ const { t } = useTranslation();
+ if (loading)
+ return (
+
{t("azuredevops:loadingResults")}
+ );
if (error)
return (
{error}
);
- return
No matching results.
;
+ return (
+
{t("azuredevops:noMatchingResults")}
+ );
}
+// A discriminant, not copy: the aria-label is a whole sentence per kind, because
+// interpolating an English noun into a translated sentence is untranslatable.
+type TaskActionsItemKind = "workItem" | "pullRequest";
+
+const TASK_ACTIONS_LABEL_KEYS: Record
= {
+ workItem: "azuredevops:taskActionsForWorkItem",
+ pullRequest: "azuredevops:taskActionsForPullRequest",
+};
+
function TaskActionsMenu({
item,
- itemLabel,
+ itemKind,
actions,
onSelect,
}: {
item: T;
- itemLabel: string;
+ itemKind: TaskActionsItemKind;
actions: AzureDevOpsActionPreset[];
onSelect: (item: T, action: AzureDevOpsActionPreset) => void;
}) {
+ const { t } = useTranslation();
return (
@@ -50,9 +67,10 @@ function TaskActionsMenu({
size="sm"
variant="outline"
className="cursor-pointer"
- aria-label={`Task actions for ${itemLabel} ${item.id}`}
+ aria-label={t(TASK_ACTIONS_LABEL_KEYS[itemKind], { id: item.id })}
>
- Task
+ {t("azuredevops:task")}{" "}
+
@@ -86,6 +104,7 @@ export function AzureDevOpsWorkItemResults({
quickActions?: AzureDevOpsActionPreset[];
onQuickAction?: (item: AzureDevOpsWorkItem, action: AzureDevOpsActionPreset) => void;
}) {
+ const { t } = useTranslation();
if (loading || error || items.length === 0)
return ;
return (
@@ -112,7 +131,7 @@ export function AzureDevOpsWorkItemResults({
- {item.assignedTo || "Unassigned"}
+ {item.assignedTo || t("azuredevops:unassigned")}
{item.areaPath ? ` · ${item.areaPath}` : ""}