From 19ba37e0c2d3798aa091821cbaad635be027a546 Mon Sep 17 00:00:00 2001 From: Yaodong Yu <2814461814@qq.com> Date: Sat, 19 Nov 2022 22:11:19 +0800 Subject: [PATCH] feat: can specify available UI languages for an organization (#1306) --- object/init.go | 1 + object/organization.go | 1 + web/src/App.js | 4 ++-- web/src/App.less | 6 ----- web/src/OrganizationEditPage.js | 25 +++++++++++++++++++++ web/src/OrganizationListPage.js | 1 + web/src/SelectLanguageBox.js | 39 +++++++++++++++++++++++---------- web/src/Setting.js | 7 ------ web/src/auth/LoginPage.js | 6 ++--- web/src/auth/SignupPage.js | 2 +- web/src/locales/de/data.json | 2 ++ web/src/locales/en/data.json | 2 ++ web/src/locales/fr/data.json | 2 ++ web/src/locales/ja/data.json | 2 ++ web/src/locales/ko/data.json | 2 ++ web/src/locales/ru/data.json | 2 ++ web/src/locales/zh/data.json | 2 ++ 17 files changed, 75 insertions(+), 31 deletions(-) diff --git a/object/init.go b/object/init.go index b7d51489..cc2a4868 100644 --- a/object/init.go +++ b/object/init.go @@ -58,6 +58,7 @@ func initBuiltInOrganization() bool { PhonePrefix: "86", DefaultAvatar: fmt.Sprintf("%s/img/casbin.svg", conf.GetConfigString("staticBaseUrl")), Tags: []string{}, + Languages: []string{"en", "zh", "es", "fr", "de", "ja", "ko", "ru"}, AccountItems: []*AccountItem{ {Name: "Organization", Visible: true, ViewRule: "Public", ModifyRule: "Admin"}, {Name: "ID", Visible: true, ViewRule: "Public", ModifyRule: "Immutable"}, diff --git a/object/organization.go b/object/organization.go index 9315f61c..19ea752f 100644 --- a/object/organization.go +++ b/object/organization.go @@ -45,6 +45,7 @@ type Organization struct { DefaultAvatar string `xorm:"varchar(100)" json:"defaultAvatar"` DefaultApplication string `xorm:"varchar(100)" json:"defaultApplication"` Tags []string `xorm:"mediumtext" json:"tags"` + Languages []string `xorm:"varchar(255)" json:"languages"` MasterPassword string `xorm:"varchar(100)" json:"masterPassword"` EnableSoftDeletion bool `json:"enableSoftDeletion"` IsProfilePublic bool `json:"isProfilePublic"` diff --git a/web/src/App.js b/web/src/App.js index 7b26dd69..f9b67887 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -636,7 +636,7 @@ class App extends Component { { this.renderAccount() } - + {this.state.account && } @@ -680,7 +680,7 @@ class App extends Component { { this.renderAccount() } - + {this.state.account && } { diff --git a/web/src/App.less b/web/src/App.less index a1f34018..c8df7432 100644 --- a/web/src/App.less +++ b/web/src/App.less @@ -59,12 +59,6 @@ height: 70px; /* Footer height */ } -#language-box-corner { - position: absolute; - top: 75px; - right: 0; -} - .language-box { background: url("@{StaticBaseUrl}/img/muti_language.svg"); background-size: 25px, 25px; diff --git a/web/src/OrganizationEditPage.js b/web/src/OrganizationEditPage.js index 879a143c..00dc3876 100644 --- a/web/src/OrganizationEditPage.js +++ b/web/src/OrganizationEditPage.js @@ -255,6 +255,31 @@ class OrganizationEditPage extends React.Component { }} /> + + + {Setting.getLabel(i18next.t("general:Languages"), i18next.t("general:Languages - Tooltip"))} : + + + + + {Setting.getLabel(i18next.t("organization:Soft deletion"), i18next.t("organization:Soft deletion - Tooltip"))} : diff --git a/web/src/OrganizationListPage.js b/web/src/OrganizationListPage.js index a77701d0..523aa002 100644 --- a/web/src/OrganizationListPage.js +++ b/web/src/OrganizationListPage.js @@ -37,6 +37,7 @@ class OrganizationListPage extends BaseListPage { defaultAvatar: `${Setting.StaticBaseUrl}/img/casbin.svg`, defaultApplication: "", tags: [], + languages: ["en", "zh", "es", "fr", "de", "ja", "ko", "ru"], masterPassword: "", enableSoftDeletion: false, isProfilePublic: true, diff --git a/web/src/SelectLanguageBox.js b/web/src/SelectLanguageBox.js index 5770ff41..1490b19d 100644 --- a/web/src/SelectLanguageBox.js +++ b/web/src/SelectLanguageBox.js @@ -28,28 +28,45 @@ class SelectLanguageBox extends React.Component { super(props); this.state = { classes: props, + languages: props.languages ?? ["en", "zh", "es", "fr", "de", "ja", "ko", "ru"], }; } + items = [ + this.getItem("English", "en", flagIcon("US", "English")), + this.getItem("简体中文", "zh", flagIcon("CN", "简体中文")), + this.getItem("Español", "es", flagIcon("ES", "Español")), + this.getItem("Français", "fr", flagIcon("FR", "Français")), + this.getItem("Deutsch", "de", flagIcon("DE", "Deutsch")), + this.getItem("日本語", "ja", flagIcon("JP", "日本語")), + this.getItem("한국어", "ko", flagIcon("KR", "한국어")), + this.getItem("Русский", "ru", flagIcon("RU", "Русский")), + ]; + + getOrganizationLanguages(languages) { + const select = []; + for (const language of languages) { + this.items.map((item, index) => item.key === language ? select.push(item) : null); + } + return select; + } + + getItem(label, key, icon) { + return {key, icon, label}; + } + render() { + const languageItems = this.getOrganizationLanguages(this.state.languages); const menu = ( - { - Setting.changeLanguage(e.key); + { + Setting.setLanguage(e.key); }}> - English - 简体中文 - Español - Français - Deutsch - 日本語 - 한국어 - Русский ); return ( -
+
); } diff --git a/web/src/Setting.js b/web/src/Setting.js index a6d0718e..87455107 100644 --- a/web/src/Setting.js +++ b/web/src/Setting.js @@ -552,13 +552,6 @@ export function setLanguage(language) { i18next.changeLanguage(language); } -export function changeLanguage(language) { - localStorage.setItem("language", language); - changeMomentLanguage(language); - i18next.changeLanguage(language); - // window.location.reload(true); -} - export function getAcceptLanguage() { return i18next.language + ";q=0.9,en;q=0.8"; } diff --git a/web/src/auth/LoginPage.js b/web/src/auth/LoginPage.js index 26dae3aa..7c47316a 100644 --- a/web/src/auth/LoginPage.js +++ b/web/src/auth/LoginPage.js @@ -28,9 +28,7 @@ import i18next from "i18next"; import CustomGithubCorner from "../CustomGithubCorner"; import {CountDownInput} from "../common/CountDownInput"; import SelectLanguageBox from "../SelectLanguageBox"; -import {withTranslation} from "react-i18next"; import {CaptchaModal} from "../common/CaptchaModal"; -import {withRouter} from "react-router-dom"; const {TabPane} = Tabs; @@ -800,7 +798,7 @@ class LoginPage extends React.Component { {/* {*/} {/* this.state.clientId !== null ? "Redirect" : null*/} {/* }*/} - + { this.renderSignedInBox() } @@ -817,4 +815,4 @@ class LoginPage extends React.Component { } } -export default withTranslation()(withRouter(LoginPage)); +export default LoginPage; diff --git a/web/src/auth/SignupPage.js b/web/src/auth/SignupPage.js index ff74004f..14015264 100644 --- a/web/src/auth/SignupPage.js +++ b/web/src/auth/SignupPage.js @@ -645,7 +645,7 @@ class SignupPage extends React.Component { { Setting.renderLogo(application) } - + { this.renderForm(application) } diff --git a/web/src/locales/de/data.json b/web/src/locales/de/data.json index f89cc5da..07dbb2d0 100644 --- a/web/src/locales/de/data.json +++ b/web/src/locales/de/data.json @@ -170,6 +170,8 @@ "Is enabled - Tooltip": "Ist aktiviert - Tooltip", "LDAPs": "LDAPs", "LDAPs - Tooltip": "LDAPs - Tooltip", + "Languages": "Languages", + "Languages - Tooltip": "Languages - Tooltip", "Last name": "Last name", "Logo": "Logo", "Logo - Tooltip": "App's image tag", diff --git a/web/src/locales/en/data.json b/web/src/locales/en/data.json index ab652a54..83e0d770 100644 --- a/web/src/locales/en/data.json +++ b/web/src/locales/en/data.json @@ -170,6 +170,8 @@ "Is enabled - Tooltip": "Is enabled - Tooltip", "LDAPs": "LDAPs", "LDAPs - Tooltip": "LDAPs - Tooltip", + "Languages": "Languages", + "Languages - Tooltip": "Languages - Tooltip", "Last name": "Last name", "Logo": "Logo", "Logo - Tooltip": "Logo - Tooltip", diff --git a/web/src/locales/fr/data.json b/web/src/locales/fr/data.json index 1e3717ae..43099446 100644 --- a/web/src/locales/fr/data.json +++ b/web/src/locales/fr/data.json @@ -170,6 +170,8 @@ "Is enabled - Tooltip": "Est activé - infobulle", "LDAPs": "LDAPs", "LDAPs - Tooltip": "LDAPs - Infobulle", + "Languages": "Languages", + "Languages - Tooltip": "Languages - Tooltip", "Last name": "Last name", "Logo": "Logo", "Logo - Tooltip": "App's image tag", diff --git a/web/src/locales/ja/data.json b/web/src/locales/ja/data.json index 43fb77bb..7147003f 100644 --- a/web/src/locales/ja/data.json +++ b/web/src/locales/ja/data.json @@ -170,6 +170,8 @@ "Is enabled - Tooltip": "有効にする - ツールチップ", "LDAPs": "LDAP", "LDAPs - Tooltip": "LDAP - ツールチップ", + "Languages": "Languages", + "Languages - Tooltip": "Languages - Tooltip", "Last name": "Last name", "Logo": "Logo", "Logo - Tooltip": "App's image tag", diff --git a/web/src/locales/ko/data.json b/web/src/locales/ko/data.json index a536ac17..a6804535 100644 --- a/web/src/locales/ko/data.json +++ b/web/src/locales/ko/data.json @@ -170,6 +170,8 @@ "Is enabled - Tooltip": "Is enabled - Tooltip", "LDAPs": "LDAPs", "LDAPs - Tooltip": "LDAPs - Tooltip", + "Languages": "Languages", + "Languages - Tooltip": "Languages - Tooltip", "Last name": "Last name", "Logo": "Logo", "Logo - Tooltip": "App's image tag", diff --git a/web/src/locales/ru/data.json b/web/src/locales/ru/data.json index 9814d96c..fae7c09f 100644 --- a/web/src/locales/ru/data.json +++ b/web/src/locales/ru/data.json @@ -170,6 +170,8 @@ "Is enabled - Tooltip": "Включено - Подсказка", "LDAPs": "LDAPы", "LDAPs - Tooltip": "LDAPs - Подсказки", + "Languages": "Languages", + "Languages - Tooltip": "Languages - Tooltip", "Last name": "Фамилия", "Logo": "Логотип", "Logo - Tooltip": "App's image tag", diff --git a/web/src/locales/zh/data.json b/web/src/locales/zh/data.json index c5a92940..db93a6cf 100644 --- a/web/src/locales/zh/data.json +++ b/web/src/locales/zh/data.json @@ -170,6 +170,8 @@ "Is enabled - Tooltip": "是否启用", "LDAPs": "LDAP", "LDAPs - Tooltip": "LDAPs", + "Languages": "语言", + "Languages - Tooltip": "可选语言", "Last name": "姓氏", "Logo": "Logo", "Logo - Tooltip": "应用程序向外展示的图标",