Skip to content
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

Merged
merged 25 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
607ca5a
fix: adding language support package
sriramveeraghanta Dec 15, 2024
254db2d
Merge branch 'preview' of github.com:makeplane/plane into feat-langua…
sriramveeraghanta Dec 16, 2024
2dab6c0
fix: language support implementation using mobx
sriramveeraghanta Dec 16, 2024
f311264
fix: adding more languages for support
sriramveeraghanta Dec 16, 2024
194003d
fix: profile settings translations
sriramveeraghanta Dec 16, 2024
07c5147
feat: added language support for sidebar and user settings
vamsikrishnamathala Dec 17, 2024
e1fede3
feat: added language support for deactivation modal
vamsikrishnamathala Dec 17, 2024
28c5e3f
fix: added project sync after transfer issues (#6200)
vamsikrishnamathala Dec 16, 2024
8800b2f
code refactor and improvement (#6203)
anmolsinghbhatia Dec 16, 2024
23dc6f5
refactor: enhance workspace and project wrapper modularity (#6207)
prateekshourya29 Dec 16, 2024
4d13b0b
[WEB-2678]feat: added functionality to add labels directly from dropd…
vamsikrishnamathala Dec 17, 2024
c1fbe98
chore: added common component for project activity (#6212)
gakshita Dec 17, 2024
c17f43f
- Do not clear temp files that are locked. (#6214)
SatishGandham Dec 17, 2024
fa4af3c
fix: labels empty state for drop down (#6216)
vamsikrishnamathala Dec 17, 2024
00f5a5c
refactor: remove cn helper function from the editor package (#6217)
aaryan610 Dec 18, 2024
7002474
Merge branch 'preview' of github.com:makeplane/plane into feat-langua…
vamsikrishnamathala Dec 18, 2024
ed5ff98
Merge branch 'preview' of github.com:makeplane/plane into feat-langua…
vamsikrishnamathala Dec 18, 2024
fdcc233
* feat: added language support to issue create modal in sidebar
vamsikrishnamathala Dec 18, 2024
fd5b829
* fix: added missing translations
vamsikrishnamathala Dec 18, 2024
7c4d548
fix: fixed spanish translation
vamsikrishnamathala Dec 18, 2024
c1f6887
Merge branch 'preview' of gurusainath:makeplane/plane into feat-langu…
gurusainath Dec 30, 2024
0ef2aee
dev: language type error in space user profile types
gurusainath Dec 30, 2024
0ae0832
fix: type fixes
sriramveeraghanta Dec 30, 2024
5bd199f
chore: added alpha tag
vamsikrishnamathala Dec 30, 2024
988261c
Merge branch 'feat-language-support' of github.com:makeplane/plane in…
vamsikrishnamathala Dec 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 React, { createContext, useEffect } from "react";
import { observer } from "mobx-react";
import { TranslationStore } from "./store";
import { Language, languages } from "../config";

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

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

export const TranslationProvider = observer(({ children }: any) => {
sriramveeraghanta marked this conversation as resolved.
Show resolved Hide resolved
// 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);
}, []);
sriramveeraghanta marked this conversation as resolved.
Show resolved Hide resolved

return <TranslationContext.Provider value={translationStore}>{children}</TranslationContext.Provider>;
});
38 changes: 38 additions & 0 deletions packages/i18n/src/components/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
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;
}
sriramveeraghanta marked this conversation as resolved.
Show resolved Hide resolved

setLanguage(lng: Language) {
localStorage.setItem("userLanguage", lng);
this.currentLocale = lng;
}
sriramveeraghanta marked this conversation as resolved.
Show resolved Hide resolved

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);
}
}
sriramveeraghanta marked this conversation as resolved.
Show resolved Hide resolved
}
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;
};
};
sriramveeraghanta marked this conversation as resolved.
Show resolved Hide resolved

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,
};
sriramveeraghanta marked this conversation as resolved.
Show resolved Hide resolved
}
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
Loading