Skip to content

Commit

Permalink
[WEB-2870]feat: language support (#6215)
Browse files Browse the repository at this point in the history
* fix: adding language support package

* fix: language support implementation using mobx

* fix: adding more languages for support

* fix: profile settings translations

* feat: added language support for sidebar and user settings

* feat: added language support for deactivation modal

* fix: added project sync after transfer issues (#6200)

* code refactor and improvement (#6203)

* chore: package code refactoring

* chore: component restructuring and refactor

* chore: comment create improvement

* refactor: enhance workspace and project wrapper modularity (#6207)

* [WEB-2678]feat: added functionality to add labels directly from dropdown (#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 (#6212)

* chore: added common component for project activity

* fix: added enum

* fix: added enum for initiatives

* - Do not clear temp files that are locked. (#6214)

- Handle edge cases in sync workspace

* fix: labels empty state for drop down (#6216)

* refactor: remove cn helper function from the editor package (#6217)

* * feat: added language support to issue create modal in sidebar
* fix: project activity type

* * fix: added missing translations
* fix: modified translation for plurals

* fix: fixed spanish translation

* dev: language type error in space user profile types

* fix: type fixes

* chore: added alpha tag

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
Co-authored-by: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com>
Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
Co-authored-by: Akshita Goyal <36129505+gakshita@users.noreply.github.com>
Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
Co-authored-by: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com>
Co-authored-by: gurusinath <gurusainath007@gmail.com>
  • Loading branch information
8 people authored Jan 3, 2025
1 parent ade0aa1 commit 873e433
Show file tree
Hide file tree
Showing 84 changed files with 2,588 additions and 873 deletions.
2 changes: 1 addition & 1 deletion packages/constants/src/workspace.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const ORGANIZATION_SIZE = [
"Just myself",
"Just myself", // TODO: translate
"2-10",
"11-50",
"51-200",
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/*
dist/*
out/*
9 changes: 9 additions & 0 deletions packages/i18n/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import("eslint").Linter.Config} */
module.exports = {
root: true,
extends: ["@plane/eslint-config/library.js"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: true,
},
};
4 changes: 4 additions & 0 deletions packages/i18n/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.turbo
out/
dist/
build/
5 changes: 5 additions & 0 deletions packages/i18n/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"printWidth": 120,
"tabWidth": 2,
"trailingComma": "es5"
}
20 changes: 20 additions & 0 deletions packages/i18n/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "@plane/i18n",
"version": "0.24.1",
"description": "I18n shared across multiple apps internally",
"private": true,
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"lint": "eslint src --ext .ts,.tsx",
"lint:errors": "eslint src --ext .ts,.tsx --quiet"
},
"dependencies": {
"@plane/utils": "*"
},
"devDependencies": {
"@plane/eslint-config": "*",
"@types/node": "^22.5.4",
"typescript": "^5.3.3"
}
}
29 changes: 29 additions & 0 deletions packages/i18n/src/components/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { observer } from "mobx-react";
import React, { createContext, useEffect } from "react";
import { Language, languages } from "../config";
import { TranslationStore } from "./store";

// Create the store instance
const translationStore = new TranslationStore();

// Create Context
export const TranslationContext = createContext<TranslationStore>(translationStore);

export const TranslationProvider = observer(({ children }: { children: React.ReactNode }) => {
// Handle storage events for cross-tab synchronization
useEffect(() => {
const handleStorageChange = (event: StorageEvent) => {
if (event.key === "userLanguage" && event.newValue) {
const newLang = event.newValue as Language;
if (languages.includes(newLang)) {
translationStore.setLanguage(newLang);
}
}
};

window.addEventListener("storage", handleStorageChange);
return () => window.removeEventListener("storage", handleStorageChange);
}, []);

return <TranslationContext.Provider value={translationStore}>{children}</TranslationContext.Provider>;
});
42 changes: 42 additions & 0 deletions packages/i18n/src/components/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { makeObservable, observable } from "mobx";
import { Language, fallbackLng, languages, translations } from "../config";

export class TranslationStore {
currentLocale: Language = fallbackLng;

constructor() {
makeObservable(this, {
currentLocale: observable.ref,
});
this.initializeLanguage();
}

get availableLanguages() {
return languages;
}

t(key: string) {
return translations[this.currentLocale]?.[key] || translations[fallbackLng][key] || key;
}

setLanguage(lng: Language) {
try {
localStorage.setItem("userLanguage", lng);
this.currentLocale = lng;
} catch (error) {
console.error(error);
}
}

initializeLanguage() {
if (typeof window === "undefined") return;
const savedLocale = localStorage.getItem("userLanguage") as Language;
if (savedLocale && languages.includes(savedLocale)) {
this.setLanguage(savedLocale);
} else {
const browserLang = navigator.language.split("-")[0] as Language;
const newLocale = languages.includes(browserLang as Language) ? (browserLang as Language) : fallbackLng;
this.setLanguage(newLocale);
}
}
}
39 changes: 39 additions & 0 deletions packages/i18n/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import en from "../locales/en/translations.json";
import fr from "../locales/fr/translations.json";
import es from "../locales/es/translations.json";
import ja from "../locales/ja/translations.json";

export type Language = (typeof languages)[number];
export type Translations = {
[key: string]: {
[key: string]: string;
};
};

export const fallbackLng = "en";
export const languages = ["en", "fr", "es", "ja"] as const;
export const translations: Translations = {
en,
fr,
es,
ja,
};

export const SUPPORTED_LANGUAGES = [
{
label: "English",
value: "en",
},
{
label: "French",
value: "fr",
},
{
label: "Spanish",
value: "es",
},
{
label: "Japanese",
value: "ja",
},
];
1 change: 1 addition & 0 deletions packages/i18n/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./use-translation";
17 changes: 17 additions & 0 deletions packages/i18n/src/hooks/use-translation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useContext } from "react";
import { TranslationContext } from "../components";
import { Language } from "../config";

export function useTranslation() {
const store = useContext(TranslationContext);
if (!store) {
throw new Error("useTranslation must be used within a TranslationProvider");
}

return {
t: (key: string) => store.t(key),
currentLocale: store.currentLocale,
changeLanguage: (lng: Language) => store.setLanguage(lng),
languages: store.availableLanguages,
};
}
3 changes: 3 additions & 0 deletions packages/i18n/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./config";
export * from "./components";
export * from "./hooks";
Loading

0 comments on commit 873e433

Please sign in to comment.