fix(i18n): resolve build/type errors, sync main, and address CodeRabbit items

This commit is contained in:
sakuradairong
2026-06-24 17:40:30 +08:00
parent 2ce9f9020d
commit 7e4e2f0169
11 changed files with 25 additions and 29 deletions

View File

@@ -10,12 +10,14 @@ import useFetchApi from "@utils/api";
import { isNetBirdCloud } from "@utils/netbird"; import { isNetBirdCloud } from "@utils/netbird";
import { ExternalLinkIcon, User2 } from "lucide-react"; import { ExternalLinkIcon, User2 } from "lucide-react";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import React, { lazy, Suspense } from "react"; import { lazy, Suspense } from "react";
import TeamIcon from "@/assets/icons/TeamIcon"; import TeamIcon from "@/assets/icons/TeamIcon";
import { useGroups } from "@/contexts/GroupsProvider"; import { useGroups } from "@/contexts/GroupsProvider";
import { usePermissions } from "@/contexts/PermissionsProvider"; import { usePermissions } from "@/contexts/PermissionsProvider";
import { User } from "@/interfaces/User"; import { User } from "@/interfaces/User";
import PageContainer from "@/layouts/PageContainer"; import PageContainer from "@/layouts/PageContainer";
import { AccountMfaCard } from "@/cloud/mfa/AccountMFACard";
import { IdentityProviderCard } from "@/modules/integrations/idp-sync/IdentityProviderCard";
const UsersTable = lazy(() => import("@/modules/users/UsersTable")); const UsersTable = lazy(() => import("@/modules/users/UsersTable"));

View File

@@ -79,6 +79,7 @@ interface MultiSelectProps {
showRoutes?: boolean; showRoutes?: boolean;
disabledGroups?: Group[]; disabledGroups?: Group[];
"data-testid"?: string; "data-testid"?: string;
dataCy?: string;
showResourceCounter?: boolean; showResourceCounter?: boolean;
showResources?: boolean; showResources?: boolean;
showPeers?: boolean; showPeers?: boolean;
@@ -120,6 +121,7 @@ export function PeerGroupSelector({
showRoutes = false, showRoutes = false,
disabledGroups, disabledGroups,
"data-testid": dataTestId = "group-selector-dropdown", "data-testid": dataTestId = "group-selector-dropdown",
dataCy,
showResourceCounter = true, showResourceCounter = true,
showResources = false, showResources = false,
showPeers = false, showPeers = false,
@@ -394,6 +396,7 @@ export function PeerGroupSelector({
)} )}
disabled={disabled} disabled={disabled}
data-testid={dataTestId} data-testid={dataTestId}
data-cy={dataCy}
ref={inputRef} ref={inputRef}
> >
<div <div

View File

@@ -14,15 +14,9 @@ import { cn } from "@utils/helpers";
import { CheckIcon, GlobeIcon } from "lucide-react"; import { CheckIcon, GlobeIcon } from "lucide-react";
import { useState } from "react"; import { useState } from "react";
import { useLocale } from "@/contexts/LocaleProvider"; import { useLocale } from "@/contexts/LocaleProvider";
import { locales, type Locale } from "@/i18n/config"; import { locales, type Locale, LOCALE_LABELS } from "@/i18n/config";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
/** Human-readable label for each locale, shown in the switcher. */
const LOCALE_LABELS: Record<Locale, string> = {
en: "English",
zh: "中文",
};
/** /**
* Header control that switches the active locale. Writes the choice to the * Header control that switches the active locale. Writes the choice to the
* `NEXT_LOCALE` cookie (via {@link useLocale}) so it persists across reloads * `NEXT_LOCALE` cookie (via {@link useLocale}) so it persists across reloads

View File

@@ -25,10 +25,16 @@ export type Locale = (typeof locales)[number];
/** Locale used when no preference is stored or detectable. */ /** Locale used when no preference is stored or detectable. */
export const defaultLocale: Locale = "en"; export const defaultLocale: Locale = "en";
/** Human-readable label for each locale, shown in selectors and switchers. */
export const LOCALE_LABELS: Record<Locale, string> = {
en: "English",
zh: "中文",
};
/** Message catalog keyed by locale. */ /** Message catalog keyed by locale. */
export const messages: Record<Locale, typeof en> = { export const messages: Record<Locale, typeof en> = {
en, en,
zh: zh as unknown as typeof en, zh,
}; };
/** Cookie name used to persist the user's locale choice. */ /** Cookie name used to persist the user's locale choice. */

View File

@@ -65,8 +65,8 @@ type Props = {
}; };
function createAccessControlTableColumns( function createAccessControlTableColumns(
t: (key: string, params?: Record<string, unknown>) => string, t: ReturnType<typeof useTranslations<"policies">>,
tCommon: (key: string) => string, tCommon: ReturnType<typeof useTranslations<"common">>,
): ColumnDef<Policy>[] { ): ColumnDef<Policy>[] {
return [ return [
{ {

View File

@@ -864,10 +864,7 @@ export default function ActivityDescription({ event }: Props) {
ip: m?.ip, ip: m?.ip,
platform: m?.platform, platform: m?.platform,
original_reason: m?.original_reason original_reason: m?.original_reason
? t.rich("desc_compliance_original_reason", { ? ` (original non-compliant reason: ${m.original_reason})`
reason: m?.original_reason,
Value: (chunks) => <Value>{chunks}</Value>,
})
: "", : "",
Value: (chunks) => <Value>{chunks}</Value>, Value: (chunks) => <Value>{chunks}</Value>,
})} })}

View File

@@ -40,7 +40,6 @@ type Props = {
onCanceled?: () => void; onCanceled?: () => void;
}; };
export const PeerMultiSelect = ({ selectedPeers = {}, onCanceled }: Props) => { export const PeerMultiSelect = ({ selectedPeers = {}, onCanceled }: Props) => {
const t = useTranslations("peers");
return ( return (
<AnimatePresence> <AnimatePresence>
{Object.keys(selectedPeers).length > 0 && ( {Object.keys(selectedPeers).length > 0 && (
@@ -57,6 +56,7 @@ const PeerGroupMassAssignmentContent = ({
selectedPeers = {}, selectedPeers = {},
onCanceled, onCanceled,
}: Props) => { }: Props) => {
const t = useTranslations("peers");
const { mutate } = useSWRConfig(); const { mutate } = useSWRConfig();
const { confirm } = useDialog(); const { confirm } = useDialog();
const { permission } = usePermissions(); const { permission } = usePermissions();

View File

@@ -8,7 +8,7 @@ import { notify } from "@components/Notification";
import * as Tabs from "@radix-ui/react-tabs"; import * as Tabs from "@radix-ui/react-tabs";
import { useApiCall } from "@utils/api"; import { useApiCall } from "@utils/api";
import { cn } from "@utils/helpers"; import { cn } from "@utils/helpers";
import { isLocalDev, isNetBirdHosted } from "@utils/netbird"; import { isLocalDev, isNetBirdCloud } from "@utils/netbird";
import { AnimatePresence, motion } from "framer-motion"; import { AnimatePresence, motion } from "framer-motion";
import { isEmpty } from "lodash"; import { isEmpty } from "lodash";
import { import {
@@ -175,7 +175,7 @@ export default function GroupsSettings({ account }: Props) {
helpText={t("groupPropagationHelp")} helpText={t("groupPropagationHelp")}
disabled={!permission.settings.update} disabled={!permission.settings.update}
/> />
{(!isNetBirdHosted() || isLocalDev()) && ( {(!isNetBirdCloud() || isLocalDev()) && (
<FancyToggleSwitch <FancyToggleSwitch
value={jwtGroupSync} value={jwtGroupSync}
onChange={setJwtGroupSync} onChange={setJwtGroupSync}
@@ -191,7 +191,7 @@ export default function GroupsSettings({ account }: Props) {
)} )}
</div> </div>
{(!isNetBirdHosted() || isLocalDev()) && ( {(!isNetBirdCloud() || isLocalDev()) && (
<AnimatePresence> <AnimatePresence>
{jwtGroupSync && ( {jwtGroupSync && (
<div className={"overflow-hidden -top-4 relative z-0"}> <div className={"overflow-hidden -top-4 relative z-0"}>

View File

@@ -12,13 +12,7 @@ import { LanguagesIcon } from "lucide-react";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import React from "react"; import React from "react";
import { useLocale } from "@/contexts/LocaleProvider"; import { useLocale } from "@/contexts/LocaleProvider";
import { locales, type Locale } from "@/i18n/config"; import { locales, type Locale, LOCALE_LABELS } from "@/i18n/config";
/** Human-readable label for each locale, shown in the selector. */
const LOCALE_LABELS: Record<Locale, string> = {
en: "English",
zh: "中文",
};
const options: SelectOption[] = locales.map((locale) => ({ const options: SelectOption[] = locales.map((locale) => ({
value: locale, value: locale,

View File

@@ -11,7 +11,7 @@ import { useHasChanges } from "@hooks/useHasChanges";
import * as Tabs from "@radix-ui/react-tabs"; import * as Tabs from "@radix-ui/react-tabs";
import { useApiCall } from "@utils/api"; import { useApiCall } from "@utils/api";
import { validator } from "@utils/helpers"; import { validator } from "@utils/helpers";
import { isNetBirdHosted } from "@utils/netbird"; import { isNetBirdCloud } from "@utils/netbird";
import cidr from "ip-cidr"; import cidr from "ip-cidr";
import { ExternalLinkIcon, GlobeIcon, NetworkIcon } from "lucide-react"; import { ExternalLinkIcon, GlobeIcon, NetworkIcon } from "lucide-react";
import React, { useMemo, useState } from "react"; import React, { useMemo, useState } from "react";
@@ -234,7 +234,7 @@ function NetworkSettingsTabContent({ account }: Readonly<Props>) {
<div className={"w-full"}> <div className={"w-full"}>
<Input <Input
placeholder={ placeholder={
isNetBirdHosted() isNetBirdCloud()
? t("dnsDomainHostedPlaceholder") ? t("dnsDomainHostedPlaceholder")
: t("dnsDomainSelfhostedPlaceholder") : t("dnsDomainSelfhostedPlaceholder")
} }

View File

@@ -22,7 +22,7 @@ export const UserResendInviteButton = ({ user }: Props) => {
setIsLoading(true); setIsLoading(true);
notify({ notify({
title: t("resendInviteNotify"), title: t("resendInviteNotify"),
description: t("resendingInviteTo", { email: user.email }), description: t("resendingInviteTo", { email: user.email || "" }),
promise: userRequest promise: userRequest
.post("", `/${user.id}/invite`) .post("", `/${user.id}/invite`)
.finally(() => setIsLoading(false)), .finally(() => setIsLoading(false)),