-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WEB-2870]feat: language support #6215
base: preview
Are you sure you want to change the base?
Conversation
WalkthroughThis pull request introduces a comprehensive internationalization (i18n) framework for the Plane application. The changes span multiple packages and components, establishing a robust translation system using the newly created Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 26
🔭 Outside diff range comments (6)
web/core/components/workspace/sidebar/help-section.tsx (1)
Line range hint
153-153
: Add missing translationsSome text strings remain untranslated:
- "Discord" in the Discord community link
- "Expand"/"Hide" in the sidebar toggle tooltip
Consider translating these strings for complete internationalization support.
- <span className="text-xs">Discord</span> + <span className="text-xs">{t("discord_community")}</span> - <Tooltip tooltipContent={`${isCollapsed ? "Expand" : "Hide"}`} isMobile={isMobile}> + <Tooltip tooltipContent={`${isCollapsed ? t("expand") : t("hide")}`} isMobile={isMobile}>Also applies to: 171-171
web/next.config.js (2)
Line range hint
89-103
: Improve URL construction for god-mode routingThe current URL construction using string concatenation (
ADMIN_BASE_URL + ADMIN_BASE_PATH
) could lead to issues if the environment variables contain trailing or leading slashes. Consider using URL manipulation utilities to ensure proper URL formation.Here's a suggested improvement:
- const GOD_MODE_BASE_URL = ADMIN_BASE_URL + ADMIN_BASE_PATH; + const GOD_MODE_BASE_URL = new URL(ADMIN_BASE_PATH, ADMIN_BASE_URL).toString().replace(/\/$/, '');Also, consider adding validation for the environment variables to ensure they contain valid URL components.
Security headers removal requires attention - potential security risk
The SECURITY.md explicitly states that "Missing [...] CSP headers" are out of scope, but makes no mention of the commented-out security headers (Referrer-Policy, COOP, COEP). These headers are important security controls:
- Referrer-Policy: Controls how much referrer information is sent in requests
- Cross-Origin-Opener-Policy (COOP): Isolates window references to prevent attacks
- Cross-Origin-Embedder-Policy (COEP): Controls which resources can be loaded cross-origin
Since:
- There's no documentation justifying their removal
- These headers aren't implemented elsewhere in the codebase
- They're not listed as out-of-scope in SECURITY.md
- Their removal could impact the security posture
Please restore these security headers unless there's a specific technical requirement preventing their use. If they must remain disabled, document the reasoning and any compensating controls.
[security]
🔗 Analysis chain
Line range hint
15-21
: Security headers have been commented out - please verify if this is intentionalSeveral important security headers have been commented out:
Referrer-Policy
Cross-Origin-Opener-Policy
Cross-Origin-Embedder-Policy
These headers help protect against various security vulnerabilities. Please verify if removing these headers is intentional and doesn't compromise security.
Let me check the content of SECURITY.md to see if it provides any context about these headers.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check if these headers are defined elsewhere in the codebase # or if there's any documentation explaining their removal # Search for these headers in other configuration files echo "Searching for security headers in other files..." rg -i "referrer-policy|cross-origin-opener-policy|cross-origin-embedder-policy" --type yaml --type js # Check for security-related documentation echo "Checking for security documentation..." fd -e md -e txt -H "security|headers"Length of output: 598
Script:
#!/bin/bash # Check the content of SECURITY.md cat SECURITY.md # Also check for any recent commits or PRs that might have commented out these headers git log -p --grep="header" web/next.config.jsLength of output: 3357
web/core/constants/profile.ts (2)
Line range hint
51-55
: Replace hardcoded label with translation keyThe label "Summary" should be internationalized to support multiple languages as per the PR objectives.
Replace the hardcoded string with a translation key:
{ key: "summary", route: "", - label: "Summary", + label: "profile.tabs.summary", selected: "/", },
Based on the investigation of the codebase, I can now provide a final response:
Translation keys need to be added to the i18n system
The review comment is correct about internationalizing the labels, but the suggested translation keys don't exist yet. The translation file at
packages/i18n/src/locales/en/translations.json
shows that:
- The i18n system is properly set up with support for multiple languages
- The file already contains some profile-related translations but doesn't have the specific tab labels yet
- The translation pattern used in the project is flat keys (not nested)
You'll need to:
- Add these translations to
packages/i18n/src/locales/en/translations.json
:{ "profile_tab_assigned": "Assigned", "profile_tab_created": "Created", "profile_tab_subscribed": "Subscribed", "profile_tab_activity": "Activity" }
- Update the code to use these keys:
{ key: "assigned", route: "assigned", - label: "Assigned", + label: "profile_tab_assigned", selected: "/assigned/", }, { route: "created", - label: "Created", + label: "profile_tab_created", selected: "/created/", }, { key: "subscribed", route: "subscribed", - label: "Subscribed", + label: "profile_tab_subscribed", selected: "/subscribed/", }, { key: "activity", route: "activity", - label: "Activity", + label: "profile_tab_activity", selected: "/activity/", },🔗 Analysis chain
Line range hint
60-80
: Internationalize tab labels for multi-language supportThe labels "Assigned", "Subscribed", and "Activity" need to be internationalized to support French, Spanish, and Japanese as specified in the PR objectives.
Apply these changes to support multiple languages:
{ key: "assigned", route: "assigned", - label: "Assigned", + label: "profile.tabs.assigned", selected: "/assigned/", }, { route: "created", - label: "Created", + label: "profile.tabs.created", selected: "/created/", }, { key: "subscribed", route: "subscribed", - label: "Subscribed", + label: "profile.tabs.subscribed", selected: "/subscribed/", }, { key: "activity", route: "activity", - label: "Activity", + label: "profile.tabs.activity", selected: "/activity/", },Let's verify if translation keys are defined in the translation files:
The previous search might have failed because we didn't know the exact location or format of translation files. This script will help us locate translation-related files and understand the project structure better.
This will help us verify if the translation keys already exist and if the file is set up to use translations.
This will help us understand the translation structure and patterns used in the project.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for the translation keys in the translation files rg "profile\.tabs\." -A 1Length of output: 27
Script:
#!/bin/bash # Let's first check if there are any translation files in the repository fd -e json -e yaml -e yml "translation|locale|i18n|lang" # Also check for common translation file patterns fd "en\.json|fr\.json|es\.json|ja\.json" # Let's also check the directory structure to understand the project organization fd -t d . -d 2Length of output: 940
Script:
#!/bin/bash # Let's check the content of the English translation file to see if these keys exist cat packages/i18n/src/locales/en/translations.json | jq '.profile.tabs // empty' # Let's also verify if the component is using the translation system rg -A 2 "useTranslation|Trans|Translation" "web/core/constants/profile.ts" # Check if there are any existing translation patterns in the profile.ts file rg "\.t\(|i18n\." "web/core/constants/profile.ts"Length of output: 274
Script:
#!/bin/bash # Let's examine the actual content of the English translation file cat packages/i18n/src/locales/en/translations.json # Let's also check how translations are used in other parts of the web application rg -A 2 "useTranslation|Trans|Translation" "web/core/" # Check for any existing translation keys in the profile section rg "profile\." "packages/i18n/src/locales/en/translations.json"Length of output: 66323
web/app/profile/activity/page.tsx (1)
Line range hint
52-52
: Add translation support for page titleThe PageHead title is still hardcoded. Consider using the translation function for consistency.
- <PageHead title="Profile - Activity" /> + <PageHead title={`${t("profile")} - ${t("activity")}`} />
🧹 Nitpick comments (60)
web/core/components/workspace/sidebar/dropdown.tsx (3)
33-51
: Consider adding type safety for translation keysThe translation integration looks good, with proper useMemo optimization. However, consider using a type-safe approach for translation keys to prevent potential runtime errors.
// Consider adding a type for translation keys type TranslationKey = 'workspace_invites' | 'workspace_settings' | /* other keys */; // Then use it in the t function const t = useTranslation<TranslationKey>();
129-129
: Consider consolidating duplicate translationsThe UI text translations are properly implemented, but there are duplicate translation keys for "sign_out" (lines 259 and 314). Consider using a constant for frequently used translation keys to maintain consistency and ease maintenance.
// At the top of the component const TRANSLATIONS = { SIGN_OUT: 'sign_out', // other common translations... } as const; // Then use it consistently {t(TRANSLATIONS.SIGN_OUT)}Also applies to: 185-185, 225-225, 259-259, 301-301, 314-314, 322-322
Line range hint
32-322
: Consider implementing a translation loading stateWhile the translations are well-implemented, consider adding a loading state for translations to prevent potential flash of untranslated content (FOUC) when the translations are being loaded. This could be particularly important for users with slower connections.
Consider implementing a translation loading wrapper:
const TranslationLoader: FC<{ children: ReactNode }> = ({ children }) => { const { ready } = useTranslation(); if (!ready) return <LoadingSpinner />; return <>{children}</>; };web/core/components/workspace/create-workspace-form.tsx (4)
39-47
: Consider adding type safety for translation keysWhile the translation implementation is correct, consider creating a type-safe approach for translation keys to prevent potential runtime errors from typos or missing translations.
// Create a type for your translation keys type WorkspaceTranslationKey = | "creating_workspace" | "create_workspace" // ... other keys // Use it in the component const { t } = useTranslation<WorkspaceTranslationKey>();
Line range hint
81-103
: Consider centralizing error handling logicThe error handling is scattered across multiple catch blocks with similar toast notifications. Consider extracting this into a reusable function.
const handleWorkspaceError = (eventElement: string) => { captureWorkspaceEvent({ eventName: WORKSPACE_CREATED, payload: { state: "FAILED", element: t(eventElement), }, }); setToast({ type: TOAST_TYPE.ERROR, title: t("error"), message: t("workspace_could_not_be_created_please_try_again"), }); };
Line range hint
191-198
: Extract URL validation logic into a reusable utilityThe URL validation logic is currently embedded in the onChange handler. Consider extracting it into a reusable utility function for better maintainability and potential reuse across the application.
// utils/validation.ts export const isValidWorkspaceUrl = (url: string): boolean => /^[a-zA-Z0-9_-]+$/.test(url); // In component onChange={(e) => { const newValue = e.target.value.toLowerCase(); setInvalidSlug(!isValidWorkspaceUrl(newValue)); onChange(newValue); }}
138-144
: Extract validation constantsConsider extracting the validation rules' magic numbers into named constants for better maintainability and documentation.
const WORKSPACE_VALIDATION = { NAME_MAX_LENGTH: 80, SLUG_MAX_LENGTH: 48, NAME_PATTERN: /^[\w\s-]*$/, } as const; // Use in validation rules maxLength: { value: WORKSPACE_VALIDATION.NAME_MAX_LENGTH, message: t("limit_your_name_to_80_characters"), }web/app/profile/appearance/page.tsx (1)
64-64
: Consider translating the page titleThe page title "Profile - Appearance" is still hardcoded. Consider using the translation function for consistency with the rest of the internationalized content.
-<PageHead title="Profile - Appearance" /> +<PageHead title={`${t("profile")} - ${t("appearance")}`} />web/core/components/workspace/sidebar/help-section.tsx (2)
99-99
: Maintain consistent translation key naming conventionThe translation key
message_support
uses snake_case while other keys use different conventions. Consider standardizing the naming convention across all translation keys for better maintainability.
144-144
: Consider standardizing special character handling in translation keysThe translation key
whats_new
is missing an apostrophe. Consider establishing guidelines for handling special characters in translation keys for consistency.web/core/components/global/product-updates/modal.tsx (1)
31-41
: Add type safety and fallback handling for translationsConsider implementing type safety for translation keys and adding fallback handling for missing translations to improve reliability.
Example implementation:
// Define translation key types type ProductUpdatesTranslationKeys = { 'product_updates.error.fetch_failed': string; 'product_updates.changelog.visit_prefix': string; 'product_updates.changelog.link_text': string; 'product_updates.changelog.visit_suffix': string; }; // Use with fallback const { t } = useTranslation<ProductUpdatesTranslationKeys>(); t('product_updates.error.fetch_failed', 'Unable to fetch updates') // With fallbackweb/core/components/workspace/sidebar/favorites/new-fav-folder.tsx (2)
47-48
: Consider using namespaced translation keys.While the translations are correctly implemented, consider using namespaced keys to avoid potential conflicts and improve maintainability. For example:
error
→common.error
folder_already_exists
→favorites.folder.errors.already_exists
- title: t("error"), - message: t("folder_already_exists"), + title: t("common.error"), + message: t("favorites.folder.errors.already_exists"),Also applies to: 61-62, 69-70, 76-77
137-137
: Consider adding aria-label for better accessibility.The input field could benefit from an aria-label to improve accessibility for screen readers.
- render={({ field }) => <Input className="w-full" placeholder={t("new_folder")} {...field} />} + render={({ field }) => ( + <Input + className="w-full" + placeholder={t("new_folder")} + aria-label={t("new_folder")} + {...field} + /> + )}web/ce/components/projects/create/attributes.tsx (2)
46-46
: Consider translating network optionsWhile the placeholder is correctly translated, consider also translating the network labels and descriptions from
NETWORK_CHOICES
.Example implementation:
<CustomSelect.Option key={network.key} value={network.key}> <div className="flex items-start gap-2"> <network.icon className="h-3.5 w-3.5" /> <div className="-mt-1"> - <p>{network.label}</p> - <p className="text-xs text-custom-text-400">{network.description}</p> + <p>{t(`network.${network.key}.label`)}</p> + <p className="text-xs text-custom-text-400">{t(`network.${network.key}.description`)}</p> </div> </div> </CustomSelect.Option>
82-82
: Consider using a more descriptive translation keyThe translation key "lead" is quite generic and could lead to naming conflicts. Consider using a more specific key that includes the context.
-placeholder={t("lead")} +placeholder={t("project.create.lead_placeholder")}web/core/constants/profile.ts (1)
Line range hint
1-82
: Consider adding type safety for translation keysTo ensure type safety and prevent typos in translation keys, consider defining an interface or type for the translation keys.
Add a type definition at the top of the file:
type ProfileTabTranslationKey = | "profile.tabs.summary" | "profile.tabs.assigned" | "profile.tabs.created" | "profile.tabs.subscribed" | "profile.tabs.activity"; interface ProfileTab { key: string; route: string; label: ProfileTabTranslationKey; selected: string; }web/core/components/workspace/sidebar/workspace-menu.tsx (2)
10-10
: Add fallback handling for translationsWhile the translation implementation is good, we should add fallback handling for missing translations to prevent potential runtime issues.
- <span>{t("workspace").toUpperCase()}</span> + <span>{(t("workspace") || "Workspace").toUpperCase()}</span> - <span>{t("archives")}</span> + <span>{t("archives") || "Archives"}</span> - <span>{t("settings")}</span> + <span>{t("settings") || "Settings"}</span>Also applies to: 41-41, 89-89, 116-116, 126-126
166-166
: Optimize rendering performanceThe menu item rendering logic can be optimized to prevent unnecessary re-renders and improve performance:
- Memoize the translation function calls
- Extract the menu item component for better re-render control
+ const MenuItemComponent = React.memo(({ link, sidebarCollapsed, t }) => { + const translatedLabel = React.useMemo(() => t(link.key), [t, link.key]); + return ( <SidebarNavItem key={link.value} className={`${sidebarCollapsed ? "p-0 size-8 aspect-square justify-center mx-auto" : ""}`} isActive={link.highlight(pathname, `/${workspaceSlug}`)} > <div className="flex items-center gap-1.5 py-[1px]"> <link.Icon className={cn("size-4", { "rotate-180": link.value === "active-cycles", })} /> - {!sidebarCollapsed && <p className="text-sm leading-5 font-medium">{t(link.key)}</p>} + {!sidebarCollapsed && <p className="text-sm leading-5 font-medium">{translatedLabel}</p>} </div> {!sidebarCollapsed && link.value === "active-cycles" && indicatorElement} </SidebarNavItem> + ); + });Also applies to: 170-171, 177-177, 179-179, 189-189, 191-191
web/ce/components/global/version-number.tsx (1)
2-2
: Consider adding type safety for translation keys.While the implementation works, consider using a type-safe approach for translation keys to catch potential typos or missing translations at compile time.
- const { t } = useTranslation(); - return <span>{t("version")}: v{packageJson.version}</span>; + type TranslationKey = "version"; // Define allowed keys + const { t } = useTranslation<TranslationKey>(); + return <span>{t("version", "Version")}: v{packageJson.version}</span>; // Add fallbackAlso applies to: 6-7
packages/i18n/src/config/index.ts (1)
22-39
: Internationalize language labels.The language labels themselves should be translatable to provide a fully localized experience.
export const SUPPORTED_LANGUAGES = [ { - label: "English", + labelKey: "language_english", // Add these keys to translation files value: "en", }, { - label: "French", + labelKey: "language_french", value: "fr", }, // ... similar changes for other languages ];packages/i18n/src/components/index.tsx (1)
7-7
: Consider making translationStore configurable.The translationStore is created as a singleton, which might make testing and configuration difficult.
-const translationStore = new TranslationStore(); +export const createTranslationStore = (config?: TranslationConfig) => new TranslationStore(config); +const defaultTranslationStore = createTranslationStore(); -export const TranslationContext = createContext<TranslationStore>(translationStore); +export const TranslationContext = createContext<TranslationStore>(defaultTranslationStore); -export const TranslationProvider = observer(({ children }: { children: React.ReactNode }) => { +export const TranslationProvider = observer(({ + children, + store = defaultTranslationStore +}: { + children: React.ReactNode; + store?: TranslationStore; +}) => {web/core/components/project/create/project-create-buttons.tsx (1)
2-2
: Consider using namespaced and type-safe translation keys.While the translation implementation works, consider these improvements for better maintainability:
- Use namespaced keys (e.g., "project.create.button.cancel") to avoid key conflicts
- Add type safety for translation keys to catch missing translations at compile time
Example implementation:
// types/i18n.ts export const PROJECT_TRANSLATIONS = { create: { button: { cancel: 'cancel', create: 'create_project', creating: 'creating' } } } as const; type TranslationKeys = typeof PROJECT_TRANSLATIONS;Also applies to: 17-17, 28-28, 31-31
packages/i18n/src/components/store.ts (1)
1-38
: Add type safety and validation for translations.Consider adding:
- Type-safe translation keys
- Runtime validation of translation completeness
- Unit tests for the translation store
Create a translation validator:
type TranslationSchema = Record<string, string>; function validateTranslations(translations: Record<Language, TranslationSchema>) { const baseKeys = Object.keys(translations[fallbackLng]); for (const lang of languages) { const missingKeys = baseKeys.filter( key => !translations[lang][key] ); if (missingKeys.length > 0) { console.warn(`Missing translations in ${lang}:`, missingKeys); } } }web/app/profile/notifications/page.tsx (1)
28-32
: Consider breaking down long translation keyThe translation key
stay_in_the_loop_on_issues_you_are_subscribed_to_enable_this_to_get_notified
is quite long. Consider breaking it into smaller, more manageable segments or using a shorter key name for better maintainability.-description={t("stay_in_the_loop_on_issues_you_are_subscribed_to_enable_this_to_get_notified")} +description={t("notification_settings.subscription_description")}web/core/constants/themes.ts (1)
4-4
: Consider internationalizing theme labelsWhile adding the
key
property is good for unique identification, consider also internationalizing the theme labels for consistent language support across the application.{ key: "system_preference", value: "system", - label: "System preference", + label: t("themes.system_preference"), type: "light", // ... rest of the properties }This would require:
- Moving the theme options to a component or hook where
useTranslation
is available- Adding corresponding translation keys to the i18n files
Also applies to: 17-17, 28-28, 39-39, 50-50, 61-61, 72-72
web/core/components/global/product-updates/footer.tsx (1)
Line range hint
15-50
: Consider extracting URLs to constants.The hardcoded URLs should be moved to a constants file for better maintainability.
Create a new file
constants/external-links.ts
:export const EXTERNAL_LINKS = { DOCS: "https://go.plane.so/p-docs", CHANGELOG: "https://go.plane.so/p-changelog", SUPPORT_EMAIL: "mailto:[email protected]", DISCORD: "https://go.plane.so/p-discord", PLANE_PAGES: "https://plane.so/pages" } as const;Then update the component to use these constants:
- href="https://go.plane.so/p-docs" + href={EXTERNAL_LINKS.DOCS}web/core/components/core/theme/theme-switch.tsx (1)
76-76
: Consider adding fallback textConsider adding fallback text when translations are missing to ensure graceful degradation.
- {t(themeOption.key)} + {t(themeOption.key) || themeOption.label}web/core/components/account/password-strength-meter.tsx (1)
62-62
: Optimize strengthBars memoizationThe
t
function in the dependency array might cause unnecessary re-renders as it could change on every render. Consider wrapping the component withReact.memo
or moving the translation logic outside the memoization.- }, [strength,t]); + }, [strength]);web/ce/constants/project/settings/features.tsx (2)
7-7
: Enhance type safety for translation keysConsider creating a type-safe approach for translation keys to prevent typos and ensure all keys are defined in translation files.
type TranslationKey = keyof typeof translations; // Define in i18n package export type TProperties = { key: TranslationKey; // Use strict type instead of string // ... other properties };Also applies to: 27-27
41-41
: Maintain consistency between keys and propertiesSome feature keys don't match their corresponding properties, which could lead to confusion. Consider aligning them for better maintainability.
Example for inbox feature:
- key: "intake", - property: "inbox_view", + key: "inbox", + property: "inbox_view",Also applies to: 50-50, 59-59, 68-68, 77-77
web/ce/components/active-cycles/workspace-active-cycles-upgrade.tsx (1)
38-39
: Simplify translation keysThe current translation keys are quite verbose. Consider using shorter, hierarchical keys.
- <h2 className="text-2xl font-semibold">{t("on_demand_snapshots_of_all_your_cycles")}</h2> - <p className="text-base font-medium text-custom-text-300">{t("active_cycles_description")}</p> + <h2 className="text-2xl font-semibold">{t("cycles.snapshots.title")}</h2> + <p className="text-base font-medium text-custom-text-300">{t("cycles.snapshots.description")}</p>web/core/components/workspace/sidebar/user-menu.tsx (2)
72-73
: Consider using distinct translation keys for tooltips and labelsUsing the same translation key (
link.key
) for both tooltip and visible text might be limiting when different wording is needed for tooltips vs labels in some languages.- tooltipContent={t(link.key)} + tooltipContent={t(`${link.key}_tooltip`)} - {!sidebarCollapsed && <p className="text-sm leading-5 font-medium">{t(link.key)}</p>} + {!sidebarCollapsed && <p className="text-sm leading-5 font-medium">{t(`${link.key}_label`)}</p>}Also applies to: 86-86, 88-88
26-26
: Consider memoizing translation hookThe
useTranslation
hook at component level could cause unnecessary re-renders. Consider memoizing the translation function or moving it to a more specific component scope.+ const memoizedT = React.useMemo(() => t, [t]);
web/core/components/project/create/header.tsx (2)
38-38
: Consider using constant translation keysUsing hardcoded string literals for translation keys can lead to maintenance issues. Consider defining these in a constants file.
// constants/translations.ts export const TRANSLATION_KEYS = { PROJECT: { COVER_IMAGE_ALT: 'project_cover_image_alt', CHANGE_COVER: 'change_cover' } } as const; // Usage in component alt={t(TRANSLATION_KEYS.PROJECT.COVER_IMAGE_ALT)}Also applies to: 53-53
25-25
: Add translations for error states and aria labelsWhile basic text is translated, consider adding translations for error messages and accessibility attributes.
+ aria-label={t("project_cover_image_aria_label")}
Also applies to: 38-38, 53-53
web/app/[workspaceSlug]/(projects)/profile/[userId]/layout.tsx (2)
84-84
: Consider shorter, hierarchical translation keysThe current translation key is very long. Consider using a more structured, hierarchical approach for better maintainability.
- {t("you_do_not_have_the_permission_to_access_this_page")} + {t("errors.permissions.page_access_denied")}
36-36
: Add translations for loading and error statesWhile the permission error is translated, consider adding translations for loading states and other potential error conditions.
// Add translations for loading and error states {isLoading ? ( <div>{t("common.loading")}</div> ) : error ? ( <div>{t("errors.generic")}</div> ) : ( // ... existing content )}Also applies to: 84-84
web/core/components/workspace/sidebar/quick-actions.tsx (1)
97-97
: Consider adding aria-label for accessibilityWhile the translation is correctly implemented, consider adding an aria-label to the button to ensure screen readers announce the translated text correctly.
- {!isSidebarCollapsed && <span className="text-sm font-medium">{t("new_issue")}</span>} + {!isSidebarCollapsed && <span className="text-sm font-medium" aria-label={t("new_issue")}>{t("new_issue")}</span>}web/core/components/project/create/common-attributes.tsx (1)
84-85
: Consider updating the project identifier validation regexThe regex pattern
/^[ÇŞĞIİÖÜA-Z0-9]+$/
includes specific non-Latin characters. Consider using Unicode properties for a more comprehensive solution that supports all languages.-/^[ÇŞĞIİÖÜA-Z0-9]+$/.test(value.toUpperCase()) +/^[\p{L}\p{N}]+$/u.test(value.toUpperCase())packages/types/src/users.d.ts (1)
64-64
: Consider using a more specific type for language fieldInstead of using a broad
string
type, consider using a union type of supported language codes for better type safety.-language: string; +language: "en" | "fr" | "es" | "ja";web/core/components/workspace/sidebar/project-navigation.tsx (1)
149-149
: Consider handling missing translationsWhile the translation implementation is correct, consider adding a fallback mechanism for missing translations to prevent displaying raw translation keys to users.
- tooltipContent={`${project?.name}: ${t(item.key)}`} + tooltipContent={`${project?.name}: ${t(item.key, { fallback: item.name })}`} - {!isSidebarCollapsed && <span className="text-xs font-medium">{t(item.key)}</span>} + {!isSidebarCollapsed && <span className="text-xs font-medium">{t(item.key, { fallback: item.name })}</span>}Also applies to: 163-163
web/core/components/profile/notification/email-notification-form.tsx (1)
38-40
: Consider centralizing toast message translationsWhile the translation of toast messages is correct, consider creating a dedicated translation namespace for toast messages to maintain consistency across the application.
- title: t("success"), - message: t("email_notification_setting_updated_successfully"), + title: t("toast.success"), + message: t("toast.email_notification_setting_updated_successfully"), - title: t("error"), - message: t("failed_to_update_email_notification_setting"), + title: t("toast.error"), + message: t("toast.failed_to_update_email_notification_setting"),Also applies to: 45-47
web/app/profile/security/page.tsx (1)
82-91
: Consider translating error messages from authErrorHandlerThe error messages from
authErrorHandler
might not be translated. Consider wrapping these messages with the translation function to ensure consistent internationalization.- const errorInfo = authErrorHandler(err.error_code?.toString()); + const errorInfo = { + ...authErrorHandler(err.error_code?.toString()), + message: t(authErrorHandler(err.error_code?.toString()).message) + };web/core/components/core/theme/custom-theme-selector.tsx (1)
41-57
: Consider extracting validation messages to constantsThe validation messages are repeated multiple times in the inputRules object. Consider extracting these to constants to improve maintainability.
+ const VALIDATION_MESSAGES = { + HEX_CODE: 'enter_a_valid_hex_code_of_6_characters' + }; const inputRules = useMemo( () => ({ minLength: { value: 7, - message: t("enter_a_valid_hex_code_of_6_characters"), + message: t(VALIDATION_MESSAGES.HEX_CODE), }, // ... apply to other rules }), [t] );web/app/invitations/page.tsx (1)
76-77
: Maintain consistent error message structureThe error messages are repeated in multiple catch blocks. Consider extracting these to a constant to maintain consistency and ease maintenance.
+ const ERROR_MESSAGES = { + TITLE: 'error', + DEFAULT: 'something_went_wrong_please_try_again', + SELECTION: 'please_select_at_least_one_invitation' + }; - title: t("error"), - message: t("something_went_wrong_please_try_again"), + title: t(ERROR_MESSAGES.TITLE), + message: t(ERROR_MESSAGES.DEFAULT),Also applies to: 111-112, 126-127
web/app/profile/sidebar.tsx (2)
95-96
: Consider using more specific error translation keys.The generic error message keys could be more specific to the sign-out context for better maintainability.
- title: t("error"), - message: t("failed_to_sign_out_please_try_again"), + title: t("sign_out_error"), + message: t("sign_out_failed_please_try_again"),
136-136
: Ensure translation key consistency.The translation key pattern varies between different components. Consider standardizing the key format:
- Some keys use snake_case:
create_workspace
- Others use full sentences:
failed_to_sign_out_please_try_again
Also applies to: 149-149
web/core/components/workspace/sidebar/projects-list.tsx (1)
89-90
: Use context-specific error translation keys.The error messages could be more specific to the project reordering context.
- title: t("error"), - message: t("something_went_wrong"), + title: t("project_error"), + message: t("project_reorder_failed"),web/core/components/workspace/sidebar/favorites/favorites-menu.tsx (2)
70-71
: Standardize error translation keys across favorite operations.Multiple error scenarios use generic error messages. Consider using operation-specific translation keys for better maintainability and clarity.
// For moving favorites - title: t("error"), - message: t("failed_to_move_favorite"), + title: t("favorite_error"), + message: t("favorite_move_failed"), // For general errors - title: t("error"), - message: t("something_went_wrong"), + title: t("favorite_error"), + message: t("favorite_operation_failed"), // For reordering - title: t("error"), - message: t("failed_to_reorder_favorite"), + title: t("favorite_error"), + message: t("favorite_reorder_failed"),Also applies to: 128-129, 137-138, 148-149
245-247
: Consider using a more semantic translation key for empty state.The empty state message could use a more descriptive translation key.
- {t("no_favorites_yet")} + {t("favorites_empty_state_message")}packages/i18n/src/locales/ja/translations.json (1)
46-47
: Consider localizing "workspace" termThe term "workspace" is left in English. Consider using a more localized term like "ワークスペース" consistently throughout the translations for better user experience.
- "workspaces": "Workspaces", - "create_workspace": "Crear workspace", + "workspaces": "ワークスペース", + "create_workspace": "ワークスペースを作成",packages/i18n/src/locales/es/translations.json (1)
46-47
: Consider localizing "workspace" termThe term "workspace" is left in English. Consider using "espacio de trabajo" consistently throughout the translations.
- "workspaces": "Workspaces", - "create_workspace": "Crear workspace", + "workspaces": "Espacios de trabajo", + "create_workspace": "Crear espacio de trabajo",web/core/components/workspace/sidebar/projects-list-item.tsx (3)
93-100
: Consider adding type safety for translation keysWhile the translation implementation is correct, consider enhancing type safety for translation keys to prevent potential runtime errors and improve maintainability.
Consider using a TypeScript enum or const object for translation keys:
// i18n/constants.ts export const TOAST_MESSAGES = { ADDING_TO_FAVORITES: "adding_project_to_favorites", REMOVING_FROM_FAVORITES: "removing_project_from_favorites", SUCCESS: "success", ERROR: "error", } as const; // Then in your component t(TOAST_MESSAGES.ADDING_TO_FAVORITES)Also applies to: 110-117
256-258
: Extract tooltip logic for better maintainabilityConsider extracting the tooltip content logic to improve readability and maintainability.
const getDragTooltipContent = (sortOrder: number | null) => { return sortOrder === null ? t("join_the_project_to_rearrange") : t("drag_to_rearrange"); }; // Then in JSX tooltipContent={getDragTooltipContent(project.sort_order)}
Line range hint
366-376
: Clean up commented codeThere's a commented-out section for "Draft issues" that should either be removed or implemented with proper translations.
If this feature is planned for future implementation, consider adding a TODO comment with more context or create a tracking issue.
web/core/components/profile/form.tsx (5)
306-333
: Aligndisplay_name
length validation withmaxLength
propertyThere is a discrepancy between the validation logic and the
maxLength
property for thedisplay_name
field. The validation restricts the length to less than 20 characters after removing spaces, while themaxLength
attribute allows up to 24 characters. This inconsistency may confuse users.Consider updating the
maxLength
to 20 to match the validation rules or adjust the validation to allow up to 24 characters.Apply this diff to align the
maxLength
with the validation:- maxLength={24} + maxLength={20}Alternatively, adjust the validation rule:
- if (value.replace(/\s/g, "").length > 20) + if (value.replace(/\s/g, "").length > 24)
346-362
: Update placeholder text for disabled email fieldThe email input field is disabled but contains the placeholder "Enter your email," which might confuse users since they cannot edit it.
Consider changing the placeholder to "Email" or removing it to prevent confusion.
Apply this diff to update the placeholder text:
- placeholder="Enter your email" + placeholder="Email"
209-214
: Improve accessibility by avoidingonClick
on<img>
elementsUsing
onClick
directly on an<img>
element can cause accessibility issues, as images are not inherently interactive and may not be focusable or accessible via keyboard navigation.Wrap the
<img>
element within a<button>
to enhance accessibility and semantic correctness.Apply this diff to refactor the clickable image:
- <img - src={getFileURL(userAvatar)} - className="absolute left-0 top-0 h-full w-full rounded-lg object-cover" - onClick={() => setIsImageUploadModalOpen(true)} - alt={currentUser?.display_name} - role="button" - /> + <button + type="button" + className="absolute left-0 top-0 h-full w-full rounded-lg overflow-hidden" + onClick={() => setIsImageUploadModalOpen(true)} + aria-label="Edit profile picture" + > + <img + src={getFileURL(userAvatar)} + className="h-full w-full object-cover" + alt={currentUser?.display_name} + /> + </button>
247-274
: Add length validation forfirst_name
fieldThe
first_name
field has amaxLength
attribute of 24 but lacks corresponding validation to enforce this limit. This could lead to inconsistent user experiences if users exceed the maximum length.Introduce a
maxLength
validation rule to ensure the input does not exceed 24 characters.Apply this diff to add length validation:
rules={{ required: "Please enter first name", + maxLength: { + value: 24, + message: "First name cannot exceed 24 characters", + }, }}
277-297
: Add length validation forlast_name
fieldSimilarly, the
last_name
field lacks a validation rule to enforce themaxLength
of 24 characters, which may result in inconsistent behavior.Add a
maxLength
validation rule to thelast_name
field.Apply this diff to include length validation:
rules={{ + maxLength: { + value: 24, + message: "Last name cannot exceed 24 characters", + }, }}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (71)
packages/constants/src/workspace.ts
(1 hunks)packages/i18n/.eslintignore
(1 hunks)packages/i18n/.eslintrc.js
(1 hunks)packages/i18n/.prettierignore
(1 hunks)packages/i18n/.prettierrc
(1 hunks)packages/i18n/package.json
(1 hunks)packages/i18n/src/components/index.tsx
(1 hunks)packages/i18n/src/components/store.ts
(1 hunks)packages/i18n/src/config/index.ts
(1 hunks)packages/i18n/src/hooks/index.ts
(1 hunks)packages/i18n/src/hooks/use-translation.ts
(1 hunks)packages/i18n/src/index.ts
(1 hunks)packages/i18n/src/locales/en/translations.json
(1 hunks)packages/i18n/src/locales/es/translations.json
(1 hunks)packages/i18n/src/locales/fr/translations.json
(1 hunks)packages/i18n/src/locales/ja/translations.json
(1 hunks)packages/i18n/tsconfig.json
(1 hunks)packages/types/src/users.d.ts
(1 hunks)web/app/[workspaceSlug]/(projects)/active-cycles/header.tsx
(2 hunks)web/app/[workspaceSlug]/(projects)/analytics/header.tsx
(3 hunks)web/app/[workspaceSlug]/(projects)/profile/[userId]/layout.tsx
(3 hunks)web/app/[workspaceSlug]/(projects)/profile/[userId]/navbar.tsx
(3 hunks)web/app/create-workspace/page.tsx
(5 hunks)web/app/invitations/page.tsx
(8 hunks)web/app/profile/activity/page.tsx
(3 hunks)web/app/profile/appearance/page.tsx
(3 hunks)web/app/profile/notifications/page.tsx
(3 hunks)web/app/profile/page.tsx
(2 hunks)web/app/profile/security/page.tsx
(7 hunks)web/app/profile/sidebar.tsx
(11 hunks)web/app/provider.tsx
(2 hunks)web/ce/components/active-cycles/workspace-active-cycles-upgrade.tsx
(5 hunks)web/ce/components/global/product-updates-header.tsx
(1 hunks)web/ce/components/global/version-number.tsx
(1 hunks)web/ce/components/projects/create/attributes.tsx
(4 hunks)web/ce/components/projects/create/root.tsx
(5 hunks)web/ce/components/workspace/edition-badge.tsx
(3 hunks)web/ce/constants/dashboard.ts
(4 hunks)web/ce/constants/project/settings/features.tsx
(8 hunks)web/core/components/account/password-strength-meter.tsx
(2 hunks)web/core/components/core/theme/custom-theme-selector.tsx
(10 hunks)web/core/components/core/theme/theme-switch.tsx
(4 hunks)web/core/components/global/product-updates/footer.tsx
(2 hunks)web/core/components/global/product-updates/modal.tsx
(3 hunks)web/core/components/profile/form.tsx
(1 hunks)web/core/components/profile/index.ts
(1 hunks)web/core/components/profile/notification/email-notification-form.tsx
(8 hunks)web/core/components/project/create/common-attributes.tsx
(8 hunks)web/core/components/project/create/header.tsx
(4 hunks)web/core/components/project/create/project-create-buttons.tsx
(3 hunks)web/core/components/project/form.tsx
(3 hunks)web/core/components/project/project-feature-update.tsx
(3 hunks)web/core/components/project/settings/features-list.tsx
(4 hunks)web/core/components/workspace/create-workspace-form.tsx
(10 hunks)web/core/components/workspace/sidebar/dropdown.tsx
(10 hunks)web/core/components/workspace/sidebar/favorites/favorites-menu.tsx
(7 hunks)web/core/components/workspace/sidebar/favorites/new-fav-folder.tsx
(7 hunks)web/core/components/workspace/sidebar/help-section.tsx
(8 hunks)web/core/components/workspace/sidebar/project-navigation.tsx
(11 hunks)web/core/components/workspace/sidebar/projects-list-item.tsx
(10 hunks)web/core/components/workspace/sidebar/projects-list.tsx
(6 hunks)web/core/components/workspace/sidebar/quick-actions.tsx
(3 hunks)web/core/components/workspace/sidebar/user-menu.tsx
(3 hunks)web/core/components/workspace/sidebar/workspace-menu.tsx
(6 hunks)web/core/constants/cycle.ts
(1 hunks)web/core/constants/profile.ts
(3 hunks)web/core/constants/themes.ts
(7 hunks)web/core/lib/wrappers/store-wrapper.tsx
(3 hunks)web/core/store/user/profile.store.ts
(1 hunks)web/next.config.js
(1 hunks)web/package.json
(1 hunks)
✅ Files skipped from review due to trivial changes (12)
- packages/i18n/.eslintignore
- packages/i18n/.prettierrc
- packages/i18n/.eslintrc.js
- packages/constants/src/workspace.ts
- packages/i18n/src/hooks/index.ts
- packages/i18n/.prettierignore
- packages/i18n/src/index.ts
- packages/i18n/tsconfig.json
- packages/i18n/package.json
- web/core/components/profile/index.ts
- packages/i18n/src/locales/en/translations.json
- packages/i18n/src/locales/fr/translations.json
🧰 Additional context used
🪛 Biome (1.9.4)
web/core/components/workspace/sidebar/projects-list.tsx
[error] 186-192: Avoid using unnecessary Fragment.
A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.
Unsafe fix: Remove the Fragment
(lint/complexity/noUselessFragments)
🔇 Additional comments (56)
web/core/components/workspace/sidebar/dropdown.tsx (2)
3-3
: LGTM! Proper integration of i18n imports
The imports are correctly organized, and the useTranslation hook is properly imported from the @plane/i18n package.
Also applies to: 13-13
94-95
: LGTM! Proper error message translations
Error messages are correctly internationalized while maintaining the existing error handling structure.
web/app/profile/appearance/page.tsx (3)
6-6
: LGTM: Import statement is correctly placed
The addition of the useTranslation
hook import is appropriate for implementing internationalization support.
20-20
: LGTM: Translation hook is properly initialized
The useTranslation
hook is correctly implemented at the component level, following React hooks best practices.
66-70
: Verify translation key existence and consistency
The translation keys are being used correctly, but let's verify that they exist in all language files to prevent runtime errors.
✅ Verification successful
Let me verify the actual content of these translation keys in the locale files.
Translation keys are properly implemented across all language files
All three translation keys ("appearance", "theme", and "select_or_customize_your_interface_color_scheme") are present and correctly translated in all language files (English, Spanish, French, and Japanese) under packages/i18n/src/locales/. No issues found.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the translation keys exist in all language files
# Find all translation files
echo "Searching for translation files..."
fd -e json -e yaml -e yml . | grep -i "translation\|locale\|lang"
# Search for the specific keys being used
echo "Checking for translation keys..."
rg -l "appearance|theme|select_or_customize_your_interface_color_scheme" --type json --type yaml
Length of output: 897
Script:
#!/bin/bash
# Check the actual content of the translation keys in all locale files
for key in "appearance" "theme" "select_or_customize_your_interface_color_scheme"; do
echo "Checking key: $key"
echo "-------------------"
rg "\"$key\"" packages/i18n/src/locales/*/translations.json
echo -e "\n"
done
Length of output: 2537
web/core/components/workspace/sidebar/help-section.tsx (3)
7-7
: LGTM: Clean import of translation hook
The addition of the useTranslation
hook import aligns with the PR's internationalization objectives.
28-28
: LGTM: Proper translation hook initialization
The useTranslation
hook is correctly initialized at the component level, following React hooks best practices.
88-88
: Verify translation key existence
The translation implementation looks correct, but we should verify the existence of the "documentation" key in the translation files.
✅ Verification successful
Translation key "documentation" is properly defined across locales
The "documentation" translation key is present in all translation files (en, es, fr, ja) with appropriate translations, confirming proper i18n implementation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for the "documentation" translation key in all translation files
rg -g '*.{json,ts,js}' '"documentation"'
Length of output: 367
web/core/components/global/product-updates/modal.tsx (2)
3-3
: LGTM: Import statement is correctly placed
The addition of the useTranslation
hook import is consistent with the internationalization objective and follows the existing import structure.
20-20
: LGTM: Hook usage follows best practices
The useTranslation
hook is correctly implemented at the component's top level, following React hooks best practices.
web/core/components/workspace/sidebar/favorites/new-fav-folder.tsx (3)
6-6
: LGTM: Translation hook import added correctly.
The useTranslation hook is properly imported from the @plane/i18n package.
28-28
: LGTM: Translation hook initialized correctly.
The useTranslation hook is properly initialized at the component level, following React hooks best practices.
137-137
: Verify translation coverage for new_folder key.
The placeholder translation is correctly implemented. Let's verify that the "new_folder" translation key exists in all supported language files (French, Spanish, and Japanese).
✅ Verification successful
Translation key "new_folder" is properly defined in all supported languages
The translation key "new_folder" is present in all required language files (English, French, Spanish, and Japanese) with appropriate translations:
- English: "New folder"
- French: "Nouveau dossier"
- Spanish: "Nueva carpeta"
- Japanese: "新しいフォルダー"
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the new_folder translation key exists in all language files
# Search for translation files and check for the new_folder key
fd -e json -e yaml -e yml . | xargs rg "new_folder"
Length of output: 365
web/next.config.js (1)
32-32
: LGTM: Correct configuration for i18n support
The addition of @plane/i18n
to transpilePackages
is necessary for proper integration of the internationalization package.
web/ce/components/projects/create/attributes.tsx (3)
4-4
: LGTM: Clean import of i18n hook
The import statement is properly placed and uses the correct package path.
22-22
: LGTM: Proper hook initialization
The translation hook is correctly initialized at the component level, making the translation function available throughout the component.
4-4
: Verify translation key definitions
Let's verify that all used translation keys are properly defined in the translation files.
Also applies to: 22-22, 46-46, 82-82
✅ Verification successful
Translation keys are properly defined and used
The translation keys "select_network" and "lead" used in web/ce/components/projects/create/attributes.tsx
are correctly defined in the English translation file at packages/i18n/src/locales/en/translations.json
. The implementation follows the established i18n patterns across the codebase.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if translation keys are defined in all language files
# Find all translation files
echo "Searching for translation files..."
fd -e json -p "translations/"
# Search for the used translation keys
echo -e "\nChecking for translation keys..."
for key in "select_network" "lead"; do
echo -e "\nSearching for key: $key"
rg -l "\"$key\":" translations/
done
Length of output: 591
Script:
#!/bin/bash
# Let's first locate the translation files in the repository
echo "Searching for i18n or translation related files..."
fd -t f "i18n|translation|locale" --full-path
# Let's also check the imports of translation utilities
echo -e "\nChecking translation utility imports..."
rg "import.*@plane/i18n" -A 2
# Let's check the actual usage of useTranslation
echo -e "\nChecking useTranslation usage..."
ast-grep --pattern 'const { t } = useTranslation();'
Length of output: 16130
Script:
#!/bin/bash
# Let's check the translation files content
echo "Checking translation files content..."
cat packages/i18n/src/locales/en/translations.json
# Let's also check for the specific translation keys used in the file
echo -e "\nChecking specific translation usage in the file..."
rg "t\(['\"].*['\"]\)" web/ce/components/projects/create/attributes.tsx
Length of output: 15288
web/ce/constants/dashboard.ts (1)
16-18
: LGTM: Good separation of concerns in type definition
The addition of a separate key
property for translations while maintaining value
for internal usage is a good practice for i18n implementation.
web/core/components/workspace/sidebar/workspace-menu.tsx (1)
166-166
: Verify workspace feature check
The feature check uses the new value
property instead of key
. Ensure all feature flag configurations have been updated accordingly.
✅ Verification successful
Let me check the type definition and usage of TSidebarWorkspaceMenuItemKeys
to understand how the feature keys are structured.
Let me check how the workspace menu items are defined and used to understand if there's any mismatch between key and value properties.
Let me check the actual implementation of the workspace menu items to see how the value
property is being used.
Feature check implementation is correctly using the value
property
Looking at the implementation in web/ce/constants/dashboard.ts
, the workspace menu items are properly defined with both value
and key
properties, where the value
property matches exactly with the TSidebarWorkspaceMenuItemKeys
type ("projects", "all-issues", "active-cycles", "analytics"). The isWorkspaceFeatureEnabled
function correctly expects and uses these value
properties as its featureKey
parameter.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for feature flag configurations that might still be using the old 'key' property
rg -g '!*.{lock,min.js,map}' -A 3 'isWorkspaceFeatureEnabled'
Length of output: 1079
Script:
#!/bin/bash
# Search for TSidebarWorkspaceMenuItemKeys type definition and its usage
rg -g '!*.{lock,min.js,map}' 'TSidebarWorkspaceMenuItemKeys'
# Also search for the link.value usage context
ast-grep --pattern 'const $_ = [
$$$
{
$$$
value: $_,
$$$
}
$$$
]'
Length of output: 1100
Script:
#!/bin/bash
# Search for SIDEBAR_WORKSPACE_MENU definition
rg -g '!*.{lock,min.js,map}' -A 10 'SIDEBAR_WORKSPACE_MENU\s*='
# Also search for any other usage of key property in workspace menu
rg -g '!*.{lock,min.js,map}' -B 2 -A 2 'key:.*workspace'
Length of output: 784
Script:
#!/bin/bash
# Search for the workspace menu items implementation
rg -g '!*.{lock,min.js,map}' -A 15 'WORKSPACE_MENU_ITEMS\s*='
# Also check for any migration or changes related to key/value properties
rg -g '!*.{lock,min.js,map}' -B 2 -A 2 'value:\s*["'\''](?:projects|all-issues|active-cycles|analytics)['\''"]\s*,'
Length of output: 1264
packages/i18n/src/config/index.ts (1)
15-20
: Verify translation completeness.
Ensure all languages have the same translation keys to prevent runtime errors.
✅ Verification successful
Let me try a different approach to verify the translation files.
Based on the output, I can now provide a final response as I have verified all translation files and their contents.
All languages have complete and matching translation keys.
I have verified that all four language files (en, fr, es, ja) contain the same set of translation keys, and each key has a corresponding translated value in the respective language. The translations are comprehensive and well-maintained across all supported languages, with no missing keys that could cause runtime errors.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for missing translations across language files
# Function to extract keys from a JSON file
extract_keys() {
jq -r 'paths(scalars) | join(".")' "$1" | sort
}
# Compare translation files with English (base) translations
for lang in fr es ja; do
echo "Checking $lang translations..."
diff <(extract_keys "packages/i18n/src/locales/en/translations.json") \
<(extract_keys "packages/i18n/src/locales/$lang/translations.json")
done
Length of output: 1550
Script:
#!/bin/bash
# First, let's check if these translation files exist and see their content
echo "Checking English translations:"
cat packages/i18n/src/locales/en/translations.json 2>/dev/null || echo "File not found"
echo -e "\nChecking French translations:"
cat packages/i18n/src/locales/fr/translations.json 2>/dev/null || echo "File not found"
echo -e "\nChecking Spanish translations:"
cat packages/i18n/src/locales/es/translations.json 2>/dev/null || echo "File not found"
echo -e "\nChecking Japanese translations:"
cat packages/i18n/src/locales/ja/translations.json 2>/dev/null || echo "File not found"
# Let's also check the directory structure to ensure we're looking in the right place
echo -e "\nChecking directory structure:"
fd -t f . packages/i18n/src
Length of output: 60106
web/app/[workspaceSlug]/(projects)/active-cycles/header.tsx (1)
3-3
: LGTM! Verify translation key existence.
The i18n implementation looks good. The component has been properly updated to support translations.
Let's verify the translation key exists in all language files:
Also applies to: 11-31
✅ Verification successful
Translation key verified and properly implemented across all languages
The "active_cycles" translation key is present and correctly defined in all language files (en, es, fr, ja) with appropriate translations for each locale.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if the translation key exists in all language files
rg -l "active_cycles" packages/i18n/src/locales/
Length of output: 236
Script:
#!/bin/bash
# Check the actual content of translation files to verify the key exists with proper value
rg "active_cycles" packages/i18n/src/locales/ -A 1 -B 1
Length of output: 1971
packages/i18n/src/components/index.tsx (1)
4-4
: Ensure type safety for Language enum.
Verify that the Language type is properly defined as an enum or union type for type safety.
✅ Verification successful
Let me check the definition of languages
to ensure complete type safety.
Type safety for Language is properly implemented
The Language type is correctly defined as a union type derived from the languages
constant array using as const
assertion. This creates a type-safe union of literal string types ("en" | "fr" | "es" | "ja"), ensuring strict type checking for language values throughout the codebase.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check Language type definition
rg -A 5 "export (type|enum) Language" packages/i18n/src/
Length of output: 396
Script:
#!/bin/bash
# Check languages definition
rg "export const languages" -A 5 packages/i18n/src/
Length of output: 385
web/app/profile/notifications/page.tsx (1)
5-5
: LGTM: Translation hook integration
The useTranslation
hook is correctly imported and initialized.
Also applies to: 16-16
web/app/[workspaceSlug]/(projects)/profile/[userId]/navbar.tsx (1)
5-5
: Verify translation keys for tab labels
The implementation looks good, but we should verify that all tab labels have corresponding translations defined.
Also applies to: 18-18, 36-36
✅ Verification successful
Let me analyze the translation files to verify if all tab labels have corresponding translations.
All tab labels have corresponding translations
I've verified that all tab labels used in the profile constants ("Summary", "Assigned", "Subscribed", "Activity") have corresponding translations in all language files (en, es, fr, ja). The implementation is correct and complete.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if all tab labels have corresponding translations
# Extract tab labels from constants
echo "Checking PROFILE_VIEWER_TAB and PROFILE_ADMINS_TAB for translation keys..."
rg -A 5 "PROFILE_.*_TAB.*=.*\["
# Search for these keys in translation files
echo "Searching for translation keys in i18n files..."
fd -e json . | xargs cat
Length of output: 97915
Script:
#!/bin/bash
# Extract tab labels from the profile constants
echo "Checking tab labels in profile constants..."
rg -A 2 'key: ".*",' web/core/constants/profile.ts
# Search for these keys in translation files
echo "Searching for corresponding translations..."
rg '"summary"|"assigned"|"created"|"subscribed"' packages/i18n/src/locales/
Length of output: 2139
web/app/provider.tsx (1)
45-55
: LGTM! TranslationProvider is correctly positioned
The TranslationProvider is appropriately placed high in the component tree, ensuring translation context is available throughout the application.
web/app/profile/activity/page.tsx (2)
60-67
: LGTM! Translation implementation for activity section
The translation keys are appropriately used for the activity title and load more button.
Line range hint 48-48
: Verify translation support in EmptyState component
The EmptyState component is used with EmptyStateType.PROFILE_ACTIVITY. Ensure this component supports translations.
web/app/[workspaceSlug]/(projects)/analytics/header.tsx (1)
7-7
: LGTM! Verify translation key existence.
The translation integration looks good. The component correctly uses the translation hook for internationalizing the "analytics" text.
Let's verify the translation key exists in all language files:
Also applies to: 17-17, 44-44
✅ Verification successful
Translation key "analytics" is properly configured in all language files
The "analytics" translation key is present and correctly translated in all supported languages:
- English (en): "Analytics"
- Spanish (es): "Analítica"
- French (fr): "Analyse"
- Japanese (ja): "分析"
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if "analytics" key exists in all language files
fd . --extension json --exec grep -l "\"analytics\"" {} \;
Length of output: 257
Script:
#!/bin/bash
# Check the actual content of translation files to verify the "analytics" key
for locale in en es fr ja; do
echo "=== $locale translation ==="
rg "analytics" "packages/i18n/src/locales/$locale/translations.json" -C 2
done
Length of output: 1911
web/core/lib/wrappers/store-wrapper.tsx (1)
5-5
: Verify Language enum values.
Ensure the Language enum includes all supported languages (French, Spanish, Japanese).
✅ Verification successful
Language enum includes all required languages
Based on the search results, the Language type is derived from the languages
constant in packages/i18n/src/config/index.ts
which includes all the required languages:
- French ("fr")
- Spanish ("es")
- Japanese ("ja")
- English ("en")
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check Language enum definition
ast-grep --pattern 'enum Language {
$$$
}'
Length of output: 46
Script:
#!/bin/bash
# Search for Language type/enum definition using ripgrep
rg -A 10 "type Language = |enum Language |export type Language"
# Also search for language-related constants or configurations
rg -A 10 "languages|LANGUAGES" -g "!*.lock" -g "!*.log"
Length of output: 66312
Script:
#!/bin/bash
# Search for language-related configurations and constants
rg -A 5 "languages = \[|SUPPORTED_LANGUAGES = \[|const languages" -g "!*.lock" -g "!*.log"
# Also search for language-related imports and type definitions
rg -A 5 "import.*Language|type Language" -g "!*.lock" -g "!*.log"
Length of output: 4124
web/core/components/global/product-updates/footer.tsx (1)
15-41
: 🛠️ Refactor suggestion
Maintain consistency in translations.
The text "Discord" is not translated while other link texts are. Consider translating it for consistency.
- Discord
+ {t("discord")}
Likely invalid or redundant comment.
web/core/components/core/theme/theme-switch.tsx (2)
4-4
: LGTM: Translation hook implementation
The useTranslation hook is properly imported and initialized.
Also applies to: 17-17
44-44
: Verify translation keys existence
Please ensure that all translation keys (value.key
, themeOption.key
, and "select_your_theme"
) exist in the translation files for all supported languages (French, Spanish, Japanese).
Also applies to: 47-47
✅ Verification successful
Let me check the actual content of these translation files to verify if all the required keys exist.
Let me check the theme options and their corresponding translation keys to complete the verification.
Let me check the specific translation keys used in the theme component.
All translation keys are properly defined across all supported languages
Based on the verification results, all the required translation keys (value.key
, themeOption.key
, and select_your_theme
) are properly defined in all supported language files (English, Spanish, French, and Japanese). The theme-related translations include:
- System preference (
system_preference
) - Theme selection prompt (
select_your_theme
) - Theme options (light, dark, etc.)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if translation keys exist in all language files
# Look for translation files and verify keys
# Search for translation files
echo "Searching for translation files..."
fd -e json -e yaml -e yml . | grep -i "translation\|locale\|lang"
# Search for theme-related translation keys
echo "Checking for theme-related translations..."
rg -l "select_your_theme"
Length of output: 691
Script:
#!/bin/bash
# Check content of translation files for theme-related keys
echo "English translations:"
jq '.theme' packages/i18n/src/locales/en/translations.json
echo -e "\nFrench translations:"
jq '.theme' packages/i18n/src/locales/fr/translations.json
echo -e "\nSpanish translations:"
jq '.theme' packages/i18n/src/locales/es/translations.json
echo -e "\nJapanese translations:"
jq '.theme' packages/i18n/src/locales/ja/translations.json
# Also let's check the actual usage in the theme-switch component
echo -e "\nTheme switch component usage:"
cat web/core/components/core/theme/theme-switch.tsx
Length of output: 3051
Script:
#!/bin/bash
# Check theme options constants
echo "Theme options constants:"
rg -A 10 "THEME_OPTIONS.*=" .
# Check all theme-related translations
echo -e "\nAll theme-related translations in all languages:"
for lang in en es fr ja; do
echo -e "\n$lang translations:"
jq '.theme, .settings.theme' "packages/i18n/src/locales/$lang/translations.json"
done
Length of output: 4845
Script:
#!/bin/bash
# Check for specific theme-related keys in translation files
echo "Checking for system_preference key:"
rg -l "system_preference" packages/i18n/src/locales/
echo -e "\nChecking for select_your_theme key:"
rg -l "select_your_theme" packages/i18n/src/locales/
# Get the actual content around these keys
echo -e "\nContent around theme-related keys in English translations:"
rg -A 2 -B 2 "system_preference|select_your_theme" packages/i18n/src/locales/en/translations.json
echo -e "\nContent around theme-related keys in Spanish translations:"
rg -A 2 -B 2 "system_preference|select_your_theme" packages/i18n/src/locales/es/translations.json
echo -e "\nContent around theme-related keys in French translations:"
rg -A 2 -B 2 "system_preference|select_your_theme" packages/i18n/src/locales/fr/translations.json
echo -e "\nContent around theme-related keys in Japanese translations:"
rg -A 2 -B 2 "system_preference|select_your_theme" packages/i18n/src/locales/ja/translations.json
Length of output: 3240
web/core/constants/cycle.ts (1)
Line range hint 96-135
: Verify translation coverage
Ensure that all new cycle-related translation keys are present in all language files (French, Spanish, Japanese).
✅ Verification successful
Let me verify the exact content of these translation files to ensure all the new cycle-related keys are properly included.
All cycle-related translations are properly covered in all language files
The verification shows that all six new cycle-related keys and their descriptions are present in all four language files (English, Spanish, French, and Japanese) with appropriate translations. Each key has both a title and a description variant properly translated.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify translation coverage for cycle-related content
# Search for translation files
echo "Searching for cycle-related translations..."
rg -l "cycle_view_title|cycle_view_description"
# Count occurrences in each language file
echo "Checking translation coverage..."
fd -e json -e yaml -e yml . | grep -i "translation\|locale\|lang" | \
xargs rg -c "10000_feet_view|get_snapshot_of_each_active_cycle|compare_burndowns|quickly_see_make_or_break_issues|zoom_into_cycles_that_need_attention|stay_ahead_of_blockers"
Length of output: 666
Script:
#!/bin/bash
# Check the actual content of translation files for these specific keys
for key in "10000_feet_view" "get_snapshot_of_each_active_cycle" "compare_burndowns" "quickly_see_make_or_break_issues" "zoom_into_cycles_that_need_attention" "stay_ahead_of_blockers"; do
echo "=== Checking key: $key ==="
rg -A 1 "\"$key\"" packages/i18n/src/locales/
done
Length of output: 9569
web/core/components/account/password-strength-meter.tsx (1)
4-4
: LGTM: Translation hook integration
The useTranslation hook is properly imported and initialized.
Also applies to: 21-21
web/core/components/workspace/sidebar/user-menu.tsx (1)
67-68
: 🛠️ Refactor suggestion
Inconsistent usage of link.key vs link.value
The conditions are using link.value
while translations use link.key
. This mixing of identifiers could lead to maintenance issues. Consider using consistent identifiers for better maintainability.
- if (link.value === "drafts" && draftIssueCount === 0) return null;
- if (!isUserFeatureEnabled(link.value)) return null;
+ if (link.key === "drafts" && draftIssueCount === 0) return null;
+ if (!isUserFeatureEnabled(link.key)) return null;
Likely invalid or redundant comment.
web/app/[workspaceSlug]/(projects)/profile/[userId]/layout.tsx (1)
7-7
: Verify translation key usage across the application
Let's ensure consistent usage of these translation keys across the application.
Also applies to: 36-36
✅ Verification successful
Based on the search results, I can see that:
- The translation key "you_do_not_have_the_permission_to_access_this_page" is properly defined in all language files (en, es, fr, ja) in packages/i18n/src/locales/
- The key is used correctly in web/app/[workspaceSlug]/(projects)/profile/[userId]/layout.tsx with the useTranslation hook
- The translation system appears to be set up and working properly across the application
Translation key is properly implemented and localized
The translation key is correctly defined in all language files and used appropriately in the codebase. No issues found.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for hardcoded error messages that should be translated
rg -l "permission|access|denied" --type ts --type tsx
# Search for translation key usage
rg "you_do_not_have_the_permission_to_access_this_page" --type ts --type tsx
Length of output: 188
Script:
#!/bin/bash
# Search for hardcoded error messages that should be translated (without file type flags)
rg -l "permission|access|denied"
# Search for translation key usage
rg "you_do_not_have_the_permission_to_access_this_page"
# Look for other translation key usages in the codebase
rg "useTranslation|t\(['\"]"
Length of output: 84589
web/core/components/workspace/sidebar/quick-actions.tsx (1)
5-5
: LGTM! Translation implementation looks good
The translation hook is properly imported and used to translate the "New issue" text.
Also applies to: 19-19, 97-97
web/core/components/project/settings/features-list.tsx (2)
5-5
: LGTM! Consistent translation implementation
The translation implementation is consistent across all text elements, following a clear pattern for features and their descriptions.
Also applies to: 24-24, 67-68, 84-84, 92-92
67-68
: Verify translation key existence
The implementation consistently uses translation keys, but we should verify that all required keys exist in the translation files:
- Feature section keys:
{feature.key}
and${feature.key}_description
- Feature item keys:
{featureItem.key}
and${featureItem.key}_description
Also applies to: 84-84, 92-92
web/ce/components/projects/create/root.tsx (1)
6-6
: LGTM! Basic translation implementation
The translation hook is properly integrated for static text elements like success and error titles.
Also applies to: 51-51, 69-70, 100-101, 112-112
web/core/components/project/create/common-attributes.tsx (1)
5-5
: Well-implemented internationalization!
The translation integration is comprehensive and consistent:
- All user-facing strings are properly translated
- Validation messages use translation keys
- Form placeholders are internationalized
Also applies to: 30-30, 55-130
packages/types/src/users.d.ts (1)
Line range hint 1-64
: Verify the impact of removing the role field
The removal of the role
field from IUser
interface might affect existing code that relies on this field.
web/app/create-workspace/page.tsx (1)
8-8
: Well-structured internationalization implementation!
The translation integration is thorough and consistent:
- All static text is properly translated
- Image alt texts are internationalized
- UI components use translation keys consistently
Also applies to: 26-26, 70-103
web/core/components/workspace/sidebar/project-navigation.tsx (2)
21-21
: LGTM: Type definition enhancement for i18n support
The addition of the key
property to TNavigationItem
type properly supports internationalization while maintaining type safety.
Line range hint 60-112
: Verify translation keys in locale files
The navigation items now use translation keys instead of hardcoded strings. While the implementation is correct, we should ensure all keys are defined in the locale files.
✅ Verification successful
Let me verify the actual content of these translation keys to ensure they are properly defined and not just partial matches.
Let me fix the regex syntax and try again.
All navigation item translation keys are properly defined
All the required translation keys ("issues", "cycles", "modules", "views", "pages", "intake") are present in the English locale file with their corresponding translations. The keys are also available in other locale files (French, Spanish, and Japanese) as verified in the first check.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that all navigation item keys exist in locale files
# Expected results: All keys should be found in the locale files
# Find all locale files
echo "Searching for translation keys in locale files..."
for key in "issues" "cycles" "modules" "views" "pages" "intake"; do
echo "Checking key: $key"
rg -l "\"$key\":" --type json
done
Length of output: 2127
Script:
#!/bin/bash
# Check the actual content of these keys in the English locale file
echo "Checking English translations content:"
rg -A 1 '"(issues|cycles|modules|views|pages|intake)":\s*{?' packages/i18n/src/locales/en/translations.json
Length of output: 378
Script:
#!/bin/bash
# Check the actual content of these keys in the English locale file
echo "Checking English translations content:"
for key in "issues" "cycles" "modules" "views" "pages" "intake"; do
echo "=== Content for key: $key ==="
rg -A 2 "\"${key}\":" packages/i18n/src/locales/en/translations.json
done
Length of output: 1781
web/core/components/profile/notification/email-notification-form.tsx (1)
63-64
: Verify form translation keys
The form labels and descriptions have been properly internationalized. Let's verify that all translation keys exist in the locale files.
Also applies to: 85-87, 109-110, 131-133, 155-157
✅ Verification successful
Translation keys verified successfully
All form-related translation keys are present in all supported locale files (en, es, fr, ja). Each key exists in the translation files at packages/i18n/src/locales/*/translations.json
.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that all form-related translation keys exist
# Expected results: All keys should be found in the locale files
echo "Searching for form translation keys..."
keys=(
"property_changes"
"property_changes_description"
"state_change"
"state_change_description"
"issue_completed"
"issue_completed_description"
"comments"
"comments_description"
"mentions"
"mentions_description"
)
for key in "${keys[@]}"; do
echo "Checking key: $key"
rg -l "\"$key\":" --type json
done
Length of output: 3627
web/core/store/user/profile.store.ts (1)
61-61
: Add language validation in updateUserProfile
Consider adding validation for the language value when updating the user profile to ensure only supported languages are set.
web/app/profile/security/page.tsx (1)
7-7
: LGTM: Translation setup is properly implemented
The translation hook is correctly imported and initialized at the component level.
Also applies to: 59-60
web/core/components/core/theme/custom-theme-selector.tsx (1)
74-82
: LGTM: Toast messages are properly internationalized
The success and error messages in the toast notifications are correctly implemented with translations.
web/app/invitations/page.tsx (1)
156-157
: LGTM: User-facing messages are properly internationalized
All user-facing messages, including empty states and action buttons, are correctly implemented with translations.
Also applies to: 226-227, 230-230
packages/i18n/src/locales/ja/translations.json (1)
213-223
:
Untranslated content detected
Several strings from line 213 to 223 are still in English and need to be translated to Japanese.
Apply these translations:
- "removing_project_from_favorites": "Removing project from favorites",
- "project_removed_from_favorites": "Project removed from favorites",
+ "removing_project_from_favorites": "お気に入りからプロジェクトを削除中",
+ "project_removed_from_favorites": "プロジェクトがお気に入りから削除されました",
Likely invalid or redundant comment.
web/core/components/project/form.tsx (1)
6-6
: LGTM: Translation hook implementation
The useTranslation
hook is correctly imported and initialized. The implementation follows i18n best practices.
Also applies to: 47-47
web/core/components/workspace/sidebar/projects-list-item.tsx (2)
17-17
: LGTM: Translation hook integration
The translation hook is properly imported and initialized at the component level, following React hooks best practices.
Also applies to: 53-53
350-350
: LGTM: Comprehensive menu item translations
All menu items are properly internationalized, maintaining consistency throughout the component.
Also applies to: 362-362, 379-379, 387-387, 396-396, 405-405
web/app/profile/page.tsx (2)
4-4
: Successful integration of translation capabilities
The use of useTranslation
and the appropriate application of translation keys with t()
enhance the application's language support. The implementation aligns well with the PR objectives and follows best practices for internationalization.
Also applies to: 13-13, 26-26
28-28
: Correct integration of ProfileForm
component
The ProfileForm
component is correctly integrated into the ProfileSettingsPage
, and the required props user
and profile
are passed appropriately. This modular approach improves code readability and maintainability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
web/core/components/account/deactivate-account-modal.tsx (1)
Line range hint
37-44
: Add translations for toast notifications.The success and error messages in the toast notifications are still hardcoded in English. Consider internationalizing these messages for consistency:
setToast({ type: TOAST_TYPE.SUCCESS, - title: "Success!", - message: "Account deactivated successfully.", + title: t("success"), + message: t("account_deactivated_successfully"), });
🧹 Nitpick comments (1)
web/core/components/account/deactivate-account-modal.tsx (1)
Line range hint
33-44
: Consider separating business logic from UI component.The account deactivation logic could be moved to a custom hook (e.g.,
useAccountDeactivation
) to:
- Improve separation of concerns
- Make the component more focused on UI rendering
- Facilitate better testing of business logic
- Enable reuse of deactivation logic if needed elsewhere
Example structure:
// hooks/useAccountDeactivation.ts export const useAccountDeactivation = () => { const { t } = useTranslation(); const { deactivateAccount, signOut } = useUser(); const router = useAppRouter(); const handleDeactivation = async () => { try { await deactivateAccount(); setToast({ type: TOAST_TYPE.SUCCESS, title: t("success"), message: t("account_deactivated_successfully"), }); signOut(); router.push("/"); return true; } catch (err: any) { setToast({ type: TOAST_TYPE.ERROR, title: t("error"), message: err?.error, }); return false; } }; return { handleDeactivation }; };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
packages/i18n/src/locales/en/translations.json
(1 hunks)packages/i18n/src/locales/es/translations.json
(1 hunks)packages/i18n/src/locales/fr/translations.json
(1 hunks)packages/i18n/src/locales/ja/translations.json
(1 hunks)web/core/components/account/deactivate-account-modal.tsx
(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/i18n/src/locales/en/translations.json
- packages/i18n/src/locales/es/translations.json
- packages/i18n/src/locales/fr/translations.json
- packages/i18n/src/locales/ja/translations.json
🔇 Additional comments (1)
web/core/components/account/deactivate-account-modal.tsx (1)
6-6
: LGTM! Translation hook integration is correct.
The useTranslation hook is properly imported and initialized.
Also applies to: 22-22
* chore: package code refactoring * chore: component restructuring and refactor * chore: comment create improvement
…own (#6211) * enhancement:added functionality to add features directly from dropdown * fix: fixed import order * fix: fixed lint errors
* chore: added common component for project activity * fix: added enum * fix: added enum for initiatives
- Handle edge cases in sync workspace
* fix: project activity type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🔭 Outside diff range comments (3)
web/core/components/dropdowns/priority.tsx (1)
Line range hint
314-314
: Replace hardcoded placeholder default valueThe default value for the placeholder prop is still hardcoded in English. Consider using the translation function here as well.
- placeholder = "Priority", + placeholder = t("priority"),web/core/components/dropdowns/project.tsx (1)
Internationalization improvements needed
The following hardcoded strings need to be wrapped with the translation hook:
- Default placeholder "Project"
- Tooltip heading "Project"
- Dynamic string construction for project count (
${value.length} project${value.length !== 1 ? "s" : ""}
)Currently only these strings are translated:
- "search"
- "no_matching_results"
- "loading"
🔗 Analysis chain
Line range hint
1-277
: Verify complete internationalization coverageSome potentially untranslated strings were found in the component:
- "Project" in tooltipHeading
- "project"/"projects" in tooltipContent
Let's verify if any other user-facing strings in the component or related files need translation:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for hardcoded strings that might need translation rg -i --type tsx --type ts 'tooltip(Heading|Content).*["'\''].*["'\'']' web/core/components/dropdowns/Length of output: 132
Script:
#!/bin/bash # Search for hardcoded strings that might need translation in the dropdown components rg -t js -t jsx -t ts -t tsx 'tooltip(Heading|Content).*["'\''].*["'\'']' web/core/components/dropdowns/ # Search for other potential hardcoded strings in the component rg -t js -t jsx -t ts -t tsx '"[^"]+"|\'[^\']+\'' web/core/components/dropdowns/project.tsxLength of output: 251
Script:
#!/bin/bash # Search for hardcoded strings in the project dropdown component rg -g '*.{ts,tsx}' '"[^"]*"' web/core/components/dropdowns/project.tsx # Check usage of translation hook in the component rg -g '*.{ts,tsx}' 't\([^)]+\)' web/core/components/dropdowns/project.tsxLength of output: 3810
web/core/components/issues/issue-modal/base.tsx (1)
Missing translation key "issue" in all locales
The translation key "issue" is missing in all locale files (returns null), while it's being used in the error message construction:
${is_draft_issue ? t("draft_issue") : t("issue")} ${t("could_not_be_created")}
. This could lead to incomplete error messages being displayed to users.
- The key "issue" should be added to all translation files:
- packages/i18n/src/locales/en/translations.json
- packages/i18n/src/locales/es/translations.json
- packages/i18n/src/locales/fr/translations.json
- packages/i18n/src/locales/ja/translations.json
All other translation keys are properly defined across all supported locales.
🔗 Analysis chain
Line range hint
220-303
: Verify translation key coverageLet's ensure all translation keys used in the component are properly defined in the translation files.
Let me try a different approach to locate and verify the translation files.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if all used translation keys exist in the translation files # Find all translation keys used in this file echo "Translation keys used in the file:" rg -o 't\("([^"]+)"\)' web/core/components/issues/issue-modal/base.tsx | cut -d'"' -f2 # Check if these keys exist in the translation files echo -e "\nChecking translation files for these keys:" for locale in en es fr ja; do echo "Checking $locale locale..." if [ -f "packages/i18n/src/locales/$locale.json" ]; then jq 'keys' "packages/i18n/src/locales/$locale.json" fi doneLength of output: 959
Script:
#!/bin/bash # Let's first find where the translation files might be located fd -t f -e json . | grep -i 'locale\|translation\|lang' # Then let's check the content of package.json files to find i18n related configurations fd package.json -t f -x jq -r 'select(.dependencies != null) | .dependencies | keys[] | select(contains("i18n") or contains("translate") or contains("intl"))'Length of output: 418
Script:
#!/bin/bash # Now that we found the translation files, let's check for the required keys echo "Translation keys used in the file:" keys=( "success" "draft_created" "issue_created_successfully" "error" "draft_issue" "issue" "could_not_be_created" "please_try_again" "issue_updated_successfully" "issue_could_not_be_updated" ) for key in "${keys[@]}"; do echo -e "\nChecking key: $key" for locale in en es fr ja; do echo "[$locale]" jq ".[\"$key\"]" "packages/i18n/src/locales/$locale/translations.json" 2>/dev/null || echo "Key not found" done doneLength of output: 6908
🧹 Nitpick comments (11)
web/core/components/issues/issue-modal/form.tsx (1)
95-98
: Consider extracting translation logic for better readabilityWhile the implementation is functionally correct, the nested ternary operations with template literals make the code harder to read.
Consider extracting the logic into helper functions:
- modalTitle = `${data?.id ? t("update") : isDraft ? t("create_a_draft") : t("create_new_issue")}`, - primaryButtonText = { - default: `${data?.id ? t("update") : isDraft ? t("save_to_drafts") : t("save")}`, - loading: `${data?.id ? t("updating") : t("saving")}`, + modalTitle = getModalTitle(data?.id, isDraft, t), + primaryButtonText = { + default: getDefaultButtonText(data?.id, isDraft, t), + loading: getLoadingButtonText(data?.id, t), },Add these helper functions:
const getModalTitle = (hasId: boolean, isDraft: boolean, t: TranslationFunction) => hasId ? t("update") : isDraft ? t("create_a_draft") : t("create_new_issue"); const getDefaultButtonText = (hasId: boolean, isDraft: boolean, t: TranslationFunction) => hasId ? t("update") : isDraft ? t("save_to_drafts") : t("save"); const getLoadingButtonText = (hasId: boolean, t: TranslationFunction) => hasId ? t("updating") : t("saving");web/core/components/issues/issue-modal/components/title-input.tsx (2)
34-37
: Consider extracting repeated translation keysThe translation key "title_is_required" is used multiple times in the code. Consider extracting it to a constant to improve maintainability and reduce the risk of typos.
+ const TRANSLATION_KEYS = { + TITLE_REQUIRED: "title_is_required", + TITLE_MAX_LENGTH: "title_should_be_less_than_255_characters", + TITLE_PLACEHOLDER: "title" + } as const; const validateWhitespace = (value: string) => { if (value.trim() === "") { - return t("title_is_required"); + return t(TRANSLATION_KEYS.TITLE_REQUIRED); } return undefined; };
Line range hint
1-74
: Consider implementing i18n type safetyTo improve the robustness of the internationalization implementation, consider:
- Using TypeScript template literal types for translation keys to catch typos at compile time
- Implementing a translation key validation system during the build process
- Adding runtime fallback messages for missing translations
This would help prevent issues with missing or incorrect translations in production.
packages/i18n/src/locales/es/translations.json (1)
1-317
: Consider adding missing common UI translationsThe translation file might be missing some common UI elements:
- Error states (404, 500, etc.)
- Common actions (edit, delete, etc.)
- Form validation messages
Also, consider organizing keys into logical groups using nested objects for better maintainability:
{ + "common": { + "actions": { + "edit": "Editar", + "delete": "Eliminar", + // ... + }, + "errors": { + "not_found": "Página no encontrada", + "server_error": "Error del servidor", + // ... + } + }, // ... rest of the translations }web/core/components/dropdowns/project.tsx (3)
238-238
: Consider using a more specific translation keyThe current translation key "search" is quite generic. Consider using a more context-specific key like "project_search_placeholder" to avoid potential conflicts and improve maintainability.
-placeholder={t("search")} +placeholder={t("project_search_placeholder")}
268-268
: Consider using a more specific translation keyThe translation key "no_matching_results" could be more specific to the project context.
-<p className="text-custom-text-400 italic py-1 px-1.5">{t("no_matching_results")}</p> +<p className="text-custom-text-400 italic py-1 px-1.5">{t("project_search_no_results")}</p>
271-271
: Consider enhancing loading state and translation keyThe current implementation has two suggestions for improvement:
- The translation key "loading" is too generic
- The loading state could benefit from a more informative message
-<p className="text-custom-text-400 italic py-1 px-1.5">{t("loading")}</p> +<p className="text-custom-text-400 italic py-1 px-1.5">{t("project_list_loading")}</p>Consider adding a loading skeleton or spinner for a better user experience during the loading state.
web/core/components/dropdowns/state.tsx (2)
165-166
: Consider using centralized translation keysWhile the translation implementation is functional, consider using centralized translation key constants instead of string literals. This would make it easier to maintain and refactor translations across the application.
Example implementation:
// constants/translations.ts export const TRANSLATION_KEYS = { STATE: { LABEL: 'state', TOOLTIP: { HEADING: 'state', CONTENT: 'state' } } } as const; // Then in the component: t(TRANSLATION_KEYS.STATE.LABEL)Also applies to: 183-183
244-244
: Consider extracting common UI messagesThese are common UI messages that might be reused across different components. Consider extracting them into shared translation constants.
Example implementation:
// constants/common-messages.ts export const COMMON_MESSAGES = { NO_RESULTS: 'no_matching_results', LOADING: 'loading' } as const; // Then in components: t(COMMON_MESSAGES.NO_RESULTS) t(COMMON_MESSAGES.LOADING)Also applies to: 247-247
web/core/components/dropdowns/member/member-options.tsx (2)
90-90
: Consider cultural naming conventionsThe translation of "you" might need to consider formal/informal variants in languages like Japanese (あなた vs 君) and Spanish (tú vs usted).
Consider implementing a user preference for formal/informal language style in the settings.
147-147
: Add loading state enhancementThe loading and no results states could benefit from more contextual information.
Consider enhancing the user experience:
-<p className="px-1.5 py-1 italic text-custom-text-400">{t("loading")}</p> +<div className="px-1.5 py-1 flex items-center gap-2"> + <span className="animate-spin">⏳</span> + <p className="italic text-custom-text-400">{t("loading_members")}</p> +</div>Also applies to: 150-150
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
packages/i18n/src/locales/en/translations.json
(1 hunks)packages/i18n/src/locales/es/translations.json
(1 hunks)packages/i18n/src/locales/fr/translations.json
(1 hunks)packages/i18n/src/locales/ja/translations.json
(1 hunks)web/ce/types/projects/index.ts
(1 hunks)web/ce/types/projects/project-activity.ts
(1 hunks)web/core/components/dropdowns/member/index.tsx
(5 hunks)web/core/components/dropdowns/member/member-options.tsx
(5 hunks)web/core/components/dropdowns/priority.tsx
(11 hunks)web/core/components/dropdowns/project.tsx
(4 hunks)web/core/components/dropdowns/state.tsx
(5 hunks)web/core/components/issues/issue-modal/base.tsx
(6 hunks)web/core/components/issues/issue-modal/components/default-properties.tsx
(11 hunks)web/core/components/issues/issue-modal/components/title-input.tsx
(4 hunks)web/core/components/issues/issue-modal/form.tsx
(7 hunks)web/core/components/issues/select/label.tsx
(6 hunks)
✅ Files skipped from review due to trivial changes (1)
- web/ce/types/projects/project-activity.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/i18n/src/locales/ja/translations.json
- packages/i18n/src/locales/fr/translations.json
- packages/i18n/src/locales/en/translations.json
🔇 Additional comments (28)
web/core/components/issues/issue-modal/form.tsx (3)
9-10
: LGTM: Clean import organization
The import for the translation hook is properly organized under a dedicated i18n section.
204-205
: LGTM: Proper error message translation
Error messages are correctly internationalized using consistent translation keys.
501-501
: LGTM: Consistent translation of UI elements
UI text elements are properly internationalized using consistent translation keys.
Also applies to: 521-521
web/core/components/dropdowns/priority.tsx (5)
8-8
: LGTM: Translation hook import
The import of useTranslation
hook is correctly placed and follows the project's module structure.
158-163
: LGTM: Consistent translation implementation
The translation implementation in BackgroundButton follows the same pattern as BorderButton, maintaining consistency across components.
Also applies to: 207-207
242-247
: LGTM: Consistent translation pattern
The TransparentButton component maintains the same translation pattern as other button variants, ensuring a uniform approach to internationalization.
Also applies to: 292-292
343-344
: LGTM: Comprehensive translation implementation
The dropdown component has been properly internationalized with all user-facing strings using the translation function, including:
- Priority option labels
- Search placeholder
- No results message
Also applies to: 355-355, 465-465, 491-491
75-80
: Verify translation key consistency
The translation keys should align with the defined keys in the translation files. Ensure that:
priority
key exists for tooltipHeading- Priority level keys (
urgent
,high
,medium
,low
,none
) exist
Also applies to: 124-124
✅ Verification successful
Let me verify the exact content of these translation keys to ensure they match our requirements.
Translation keys verified and found consistent
All required translation keys (priority
, urgent
, high
, medium
, low
, none
) are properly defined in the translation files across all supported languages (en, es, fr, ja), and the English translations confirm their correct usage for priority levels.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if all required translation keys exist in translation files
rg -l "\"priority\":|\"urgent\":|\"high\":|\"medium\":|\"low\":|\"none\":" packages/i18n/src/locales/
Length of output: 279
Script:
#!/bin/bash
# Check the actual content of the translation keys in the English locale file
rg -A 1 '"priority":|"urgent":|"high":|"medium":|"low":|"none":' packages/i18n/src/locales/en/translations.json
Length of output: 259
web/core/components/issues/issue-modal/components/title-input.tsx (4)
7-7
: LGTM: Clean import addition
The useTranslation hook import is properly placed and follows the established import pattern.
29-29
: LGTM: Proper hook initialization
The useTranslation hook is correctly initialized and follows React hooks best practices.
64-64
: LGTM: Consistent placeholder translation
The placeholder translation is properly implemented and maintains consistency with other internationalization changes.
46-50
: Verify translation keys existence
The translation keys used in the validation rules should exist in the translation files to prevent missing translations at runtime.
✅ Verification successful
Let me verify the actual content of these translation files to ensure the specific keys exist.
Translation keys are properly defined
Both translation keys title_is_required
and title_should_be_less_than_255_characters
exist in the English translations file with appropriate messages, and the translation files are present for all supported languages (en, es, fr, ja).
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the translation keys exist in the translation files
# Search for the translation keys in the translation files
rg -l "title_is_required|title_should_be_less_than_255_characters|title" --type json
Length of output: 274
Script:
#!/bin/bash
# Check the content of English translations file for these specific keys
rg "title_is_required|title_should_be_less_than_255_characters" packages/i18n/src/locales/en/translations.json
Length of output: 246
packages/i18n/src/locales/es/translations.json (1)
1-317
: JSON structure looks good!
The file is well-formatted and follows proper JSON syntax standards.
web/ce/types/projects/index.ts (2)
1-2
: LGTM! Export statement follows consistent pattern
The new export statement follows the established pattern and maintains good TypeScript practices for type exports.
2-2
: Verify the relationship between project activities and i18n
This change introduces project activity types, but it's not immediately clear how this relates to the PR's primary objective of adding language support. Could you please clarify:
- How project activities integrate with the new i18n features?
- Whether this change should be in a separate PR focused on project activities?
web/core/components/issues/select/label.tsx (2)
8-8
: LGTM: Translation hook setup is correct.
The import and initialization of the useTranslation
hook follow React best practices and are properly placed within the component.
Also applies to: 42-42
135-135
: Verify translation keys and consider adding translator context.
The translation implementation looks good, but let's ensure all keys are properly defined and provide enough context for translators.
Let's verify the translation keys exist in all language files:
Consider adding translator comments to provide context:
- {t("labels")}
+ {/* Translators: Label text for the issue labels selector button */}
+ {t("labels")}
- {t("no_matching_results")}
+ {/* Translators: Shown when no labels match the search query */}
+ {t("no_matching_results")}
Also applies to: 156-156, 236-236, 239-239, 248-248
✅ Verification successful
Translation keys are properly defined and widely used
Based on the verification:
- All translation keys ("labels", "search", "no_matching_results", "loading", "create_new_label") are defined in the English translations file.
- The keys are consistently used across multiple components, indicating they are part of the established translation system.
- The translation implementation follows the project's patterns, as evidenced by similar usage in other components.
The suggestion for adding translator comments remains valid as a good practice, but it's not a critical issue.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if all translation keys used in the component exist in the translation files
# Expected location of translation files based on the import path: packages/i18n/src/locales/
# Define the keys we're looking for
KEYS=("labels" "search" "no_matching_results" "loading" "create_new_label")
# Find and check all JSON translation files
fd -e json -p "packages/i18n/src/locales/" -x sh -c '
echo "Checking file: {}"
for key in "${KEYS[@]}"; do
if ! jq "has(\"$key\")" {} | grep -q true; then
echo "⚠️ Missing key: $key in {}"
fi
done
'
Length of output: 648
Script:
#!/bin/bash
# Let's try a different approach to check translation keys
# First, let's examine the content of one translation file to understand its structure
echo "=== English translations ==="
cat ./packages/i18n/src/locales/en/translations.json
echo -e "\n=== Searching for translation key usage ==="
# Search for these specific translation keys in the codebase
rg -l "t\([\"']labels[\"']\)"
rg -l "t\([\"']search[\"']\)"
rg -l "t\([\"']no_matching_results[\"']\)"
rg -l "t\([\"']loading[\"']\)"
rg -l "t\([\"']create_new_label[\"']\)"
Length of output: 18271
web/core/components/dropdowns/project.tsx (2)
7-7
: LGTM: Clean import of translation hook
The import is properly organized with other dependencies.
90-90
: LGTM: Proper translation hook initialization
The translation hook is correctly initialized at the component level.
web/core/components/dropdowns/state.tsx (3)
9-9
: LGTM: Import statement is correctly placed
The import of useTranslation
from @plane/i18n
is appropriately placed with other imports and is necessary for the internationalization changes.
86-86
: LGTM: Translation hook is properly initialized
The useTranslation
hook is correctly initialized and destructured to obtain the t
function, following React hooks best practices.
9-9
: Verify consistent translation key usage across the codebase
Let's verify that these translation keys are used consistently across other components.
Also applies to: 86-86, 165-166, 183-183, 244-244, 247-247
✅ Verification successful
Based on the results from our verification scripts, I can now provide a final response:
Translation implementation is consistent and properly configured
The translation key "state" is:
- Properly defined in all language files (en, es, fr, ja)
- Used consistently in the state dropdown component
- Follows the same pattern as other translation keys ("loading", "no_matching_results")
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistent usage of translation keys across the codebase
# Search for direct string usage of translation keys
echo "Checking for translation key usage patterns..."
rg -g '*.{ts,tsx}' "t\(['\"]state['\"]\)" --type-add 'tsx:*.tsx'
rg -g '*.{ts,tsx}' "t\(['\"]no_matching_results['\"]\)" --type-add 'tsx:*.tsx'
rg -g '*.{ts,tsx}' "t\(['\"]loading['\"]\)" --type-add 'tsx:*.tsx'
# Look for potential translation key definitions
echo "Checking for translation key definitions..."
rg -g '*.{json,ts,tsx}' -C 2 '"state":\s*{' --type-add 'tsx:*.tsx'
Length of output: 3172
Script:
#!/bin/bash
# Let's check the translation files and state-related components more thoroughly
# Check translation files for state-related keys
echo "Checking translation files..."
fd -e json . | xargs rg '"state":'
# Check for useTranslation hook usage with state
echo "Checking useTranslation with state..."
ast-grep --pattern 'const { t } = useTranslation();
$$$
t("state")'
# Check for state dropdown component imports
echo "Checking state dropdown imports..."
rg -g '*.{ts,tsx}' "from.*dropdowns/state"
# Check for other state-related translations
echo "Checking other state translations..."
rg -g '*.{ts,tsx}' 't\(["\'].+state["\']' --type-add 'tsx:*.tsx'
Length of output: 857
web/core/components/issues/issue-modal/components/default-properties.tsx (3)
7-7
: LGTM: Translation hook import added correctly
The addition of the useTranslation
hook import aligns with the internationalization objectives.
69-69
: LGTM: Translation hook initialized properly
The useTranslation
hook is correctly initialized at the component level and well-placed with other hooks.
138-138
: Verify translation keys existence
All hardcoded strings have been replaced with translation keys. Let's verify that all these keys exist in the translation files to prevent any missing translations at runtime.
Consider adding JSDoc comments to document the translation keys being used in this component, which would help other developers understand and maintain the translations.
/** Translation keys used in this component:
* @i18n assignees - Placeholder for assignee dropdown
* @i18n start_date - Placeholder for start date dropdown
* @i18n due_date - Placeholder for due date dropdown
* @i18n cycle - Placeholder for cycle dropdown
* @i18n modules - Placeholder for modules dropdown
* @i18n estimate - Placeholder for estimate dropdown
* @i18n change_parent_issue - Text for changing parent issue
* @i18n remove_parent_issue - Text for removing parent issue
* @i18n add_parent - Text for adding parent issue
*/
Also applies to: 177-177, 196-196, 214-214, 236-236, 261-261, 293-293, 306-306, 319-319
✅ Verification successful
Let me generate one more verification script to check the content of the translation files directly, as the previous script only checked for exact matches which might have missed the keys if they were nested:
This will help us see the actual structure and content of the translation files to verify if these keys exist, possibly under a different hierarchy or format.
Translation keys exist and are properly defined
After checking the translation files, I can confirm that all the translation keys used in the component are present in the translation files. The keys were found in the English, Spanish, Japanese, and French translation files:
- "assignees"
- "start_date"
- "due_date"
- "cycle"
- "modules"
- "estimate"
- "change_parent_issue"
- "remove_parent_issue"
- "add_parent"
All keys are properly defined with their corresponding translations in each language file.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if all translation keys used in the component exist in translation files
# Define the keys to check
KEYS=("assignees" "start_date" "due_date" "cycle" "modules" "estimate" "change_parent_issue" "remove_parent_issue" "add_parent")
# Find and check translation files
echo "Checking translation files for required keys..."
for key in "${KEYS[@]}"; do
echo "Checking key: $key"
fd -e json -e yaml -e yml . | while read -r file; do
if [[ "$file" =~ translations|i18n|locale ]]; then
if ! grep -q "\"$key\"\\|'$key'" "$file"; then
echo "Warning: Key '$key' not found in $file"
fi
fi
done
done
Length of output: 42949
Script:
#!/bin/bash
# Check the actual content of translation files
echo "Checking translation files content:"
fd -t f . packages/i18n/src/locales/ -e json -x cat {}
Length of output: 67031
web/core/components/issues/issue-modal/base.tsx (1)
6-6
: LGTM: Translation hook integration
The integration of the useTranslation
hook follows React best practices and is correctly placed at the component's top level.
Also applies to: 58-58
web/core/components/dropdowns/member/index.tsx (2)
4-4
: LGTM: Translation hook integration
The useTranslation
hook is correctly imported and initialized.
Also applies to: 30-30
45-45
: Verify translation key consistency
The component uses several translation keys: "members", "assignee". Ensure these keys are consistently defined across all language files.
Also applies to: 91-91, 136-136
✅ Verification successful
Let me generate another script to specifically check the translation files, since the previous script included many configuration files that aren't relevant for translations.
Translation keys are properly defined across all language files
The translation keys "members" and "assignee" are consistently defined in all language files (en, es, fr, ja) with appropriate translations for each locale:
- English (en): "Members", "Assignee"
- Spanish (es): "Miembros", "Asignado"
- French (fr): "Membres", "Assigné"
- Japanese (ja): "メンバー", "アサイン者"
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistency of translation keys across language files
# Find all translation files
fd -e json -e yaml -e yml . | while read -r file; do
echo "Checking $file for required keys..."
# Check for the required translation keys
for key in "members" "assignee"; do
rg -q "\"$key\":|'$key':" "$file" || echo "Missing key '$key' in $file"
done
done
Length of output: 26932
Script:
#!/bin/bash
# Search specifically in translation files for the keys
echo "Checking translation files for 'members' and 'assignee' keys..."
rg -l "\"members\":|'members':" "packages/i18n/src/locales/**/translations.json"
echo -e "\nChecking actual content of translation files:"
for lang in packages/i18n/src/locales/*/translations.json; do
echo -e "\n=== $lang ==="
rg -A 1 "\"members\":|\"assignee\":" "$lang" || echo "No matches found"
done
Length of output: 1798
"workspaces": "Workspaces", | ||
"create_workspace": "Crear workspace", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent translation of "workspace" terms
The translation of "workspace" is inconsistent throughout the file:
- Lines 46-47: Left untranslated as "workspace"
- Line 270: Translated as "nombre-del-espacio-de-trabajo"
Consider using "espacio de trabajo" consistently throughout the file:
- "workspaces": "Workspaces",
- "create_workspace": "Crear workspace",
+ "workspaces": "Espacios de trabajo",
+ "create_workspace": "Crear espacio de trabajo",
Also applies to: 270-270
* fix: modified translation for plurals
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/i18n/src/locales/en/translations.json
(1 hunks)packages/i18n/src/locales/es/translations.json
(1 hunks)packages/i18n/src/locales/fr/translations.json
(1 hunks)packages/i18n/src/locales/ja/translations.json
(1 hunks)web/core/components/dropdowns/member/index.tsx
(5 hunks)web/core/components/issues/issue-modal/base.tsx
(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/i18n/src/locales/en/translations.json
- web/core/components/dropdowns/member/index.tsx
- packages/i18n/src/locales/fr/translations.json
- packages/i18n/src/locales/ja/translations.json
🔇 Additional comments (5)
web/core/components/issues/issue-modal/base.tsx (3)
6-6
: LGTM: Translation hook setup is correct
The useTranslation
hook is properly imported and initialized.
Also applies to: 58-58
220-221
: Avoid string concatenation in translated success messages
The success message still uses string concatenation which can lead to grammatically incorrect sentences in non-English languages where word order might differ.
Replace with a single translation key:
- message: `${is_draft_issue ? t("draft_created") : t("issue_created_successfully")} `,
+ message: t(is_draft_issue ? "message.draft_created" : "message.issue_created_successfully"),
289-290
: LGTM: Proper translation implementation
The success and error messages in the update flow correctly use direct translation keys without string concatenation.
Also applies to: 302-303
packages/i18n/src/locales/es/translations.json (2)
270-270
: Use consistent translation for workspace terms
The workspace name translation is inconsistent with other occurrences:
- "workspace_name": "nombre-del-espacio-de-trabajo",
+ "workspace_name": "Nombre del espacio de trabajo"
310-311
: Add Spanish date format localization
For proper date localization in Spanish format (DD/MM/YYYY), add the following:
+ "date_format": "DD/MM/YYYY",
+ "time_format": "HH:mm",
"start_date": "Fecha de inicio",
"due_date": "Fecha de vencimiento"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
packages/i18n/src/locales/es/translations.json (2)
143-143
: Improve translation of metaphorical expressionThe translation of "10,000 feet view" is too literal and might not convey the intended meaning in Spanish.
Consider using a more culturally appropriate expression:
- "10000_feet_view": "Vista de 10,000 pies de todos los ciclos activos.", - "10000_feet_view_description": "Amplía para ver ciclos en ejecución en todos tus proyectos a la vez en lugar de ir de ciclo en ciclo en cada proyecto.", + "10000_feet_view": "Vista general de todos los ciclos activos", + "10000_feet_view_description": "Obtén una perspectiva global de los ciclos en ejecución en todos tus proyectos a la vez.",Also applies to: 144-144
317-318
: Add missing ellipsis characterThe loading text uses regular periods instead of the proper ellipsis character.
Apply this diff to use the proper ellipsis character:
- "loading_members": "Cargando miembros..." + "loading_members": "Cargando miembros…"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/i18n/src/locales/es/translations.json
(1 hunks)
🔇 Additional comments (2)
packages/i18n/src/locales/es/translations.json (2)
1-318
: Verify translations with native speakers
While most translations appear correct, it's recommended to have a native Spanish speaker review the translations to ensure they are contextually accurate and maintain consistent formality levels throughout the file.
Run the following script to identify potential inconsistencies in formality levels:
✅ Verification successful
Based on the script results, I can now provide a final response:
Spanish translations maintain consistent informal tone
The translations consistently use the informal "tú" form throughout the interface, which is the preferred approach for modern Spanish software localization. The few instances of "su/sus" found are not related to formal pronouns but rather possessive adjectives in proper context (e.g., "su estado" meaning "its state").
The informal tone is appropriately maintained across:
- User account sections ("Tu cuenta", "Tu trabajo")
- Action prompts ("Selecciona tu tema", "Personaliza tu tema")
- Workspace management ("Crea tu espacio de trabajo")
- System messages and descriptions
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for mixed formal/informal pronouns and conjugations
# Check for mixed use of "tú" vs "usted" forms
echo "Checking for mixed formal/informal pronouns:"
rg -i '\b(tu|tus|tuyo|tuya|tuyos|tuyas)\b' packages/i18n/src/locales/es/translations.json
echo "---"
rg -i '\b(usted|ustedes|su|sus|suyo|suya|suyos|suyas)\b' packages/i18n/src/locales/es/translations.json
Length of output: 2497
310-311
: 🛠️ Refactor suggestion
Add date format localization
The date-related translations should include format strings to ensure proper localization for Spanish users.
Add the following translations:
+ "date_format": "DD/MM/YYYY",
+ "time_format": "HH:mm",
"start_date": "Fecha de inicio",
"due_date": "Fecha de vencimiento",
Likely invalid or redundant comment.
"workspaces": "Espacios de trabajo", | ||
"create_workspace": "Crear espacio de trabajo", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent translation of "workspace" terms
The translation of "workspace" is inconsistent:
- Lines 46-47: Correctly translated as "Espacios de trabajo"
- Line 270: Incorrectly using a URL-like format "nombre-del-espacio-de-trabajo"
Apply this diff to maintain consistency:
- "workspace_name": "nombre-del-espacio-de-trabajo",
+ "workspace_name": "Nombre del espacio de trabajo",
Also applies to: 270-270
"we_see_that_someone_has_invited_you_to_join_a_workspace": "Vemos que alguien te ha invitado a unirte a un espacio de trabajo", | ||
"join_a_workspace": "Unirse a un espacio de trabajo", | ||
"we_see_that_someone_has_invited_you_to_join_a_workspace_description": "Vemos que alguien te ha invitado a unirte a un espacio de trabajo", | ||
"join_a_workspace_description": "Unirse a un espacio de trabajo", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove duplicate translations
These entries have identical translations which could lead to confusion:
- "we_see_that_someone_has_invited_you_to_join_a_workspace" and its description
- "join_a_workspace" and its description
Apply this diff to differentiate the descriptions:
"we_see_that_someone_has_invited_you_to_join_a_workspace": "Vemos que alguien te ha invitado a unirte a un espacio de trabajo",
- "we_see_that_someone_has_invited_you_to_join_a_workspace_description": "Vemos que alguien te ha invitado a unirte a un espacio de trabajo",
+ "we_see_that_someone_has_invited_you_to_join_a_workspace_description": "Has recibido una invitación para colaborar en un espacio de trabajo",
"join_a_workspace": "Unirse a un espacio de trabajo",
- "join_a_workspace_description": "Unirse a un espacio de trabajo",
+ "join_a_workspace_description": "Únete a un espacio de trabajo existente para colaborar con otros",
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
"we_see_that_someone_has_invited_you_to_join_a_workspace": "Vemos que alguien te ha invitado a unirte a un espacio de trabajo", | |
"join_a_workspace": "Unirse a un espacio de trabajo", | |
"we_see_that_someone_has_invited_you_to_join_a_workspace_description": "Vemos que alguien te ha invitado a unirte a un espacio de trabajo", | |
"join_a_workspace_description": "Unirse a un espacio de trabajo", | |
"we_see_that_someone_has_invited_you_to_join_a_workspace": "Vemos que alguien te ha invitado a unirte a un espacio de trabajo", | |
"join_a_workspace": "Unirse a un espacio de trabajo", | |
"we_see_that_someone_has_invited_you_to_join_a_workspace_description": "Has recibido una invitación para colaborar en un espacio de trabajo", | |
"join_a_workspace_description": "Únete a un espacio de trabajo existente para colaborar con otros", |
Description
Added option to switch languages.
Added French, Spanish, and Japanese as supported languages.
Added language support for sidebar and user settings.
Type of Change
References
WEB-2870
Summary by CodeRabbit
Summary by CodeRabbit
New Features
TranslationProvider
to manage language context throughout the application.Bug Fixes
Chores
@plane/i18n
dependency to the project for internationalization capabilities.next.config.js
to include package transpilation settings.