diff --git a/web/src/App.js b/web/src/App.js
index 74e3b099..0bd9297e 100644
--- a/web/src/App.js
+++ b/web/src/App.js
@@ -84,8 +84,8 @@ class App extends Component {
uri: null,
menuVisible: false,
themeAlgorithm: ["default"],
- themeData: Setting.ThemeDefault,
- logo: this.getLogo(Setting.getAlgorithmNames(Setting.ThemeDefault)),
+ themeData: Conf.ThemeDefault,
+ logo: this.getLogo(Setting.getAlgorithmNames(Conf.ThemeDefault)),
};
Setting.initServerUrl();
diff --git a/web/src/ApplicationEditPage.js b/web/src/ApplicationEditPage.js
index e9d3b274..0faf856b 100644
--- a/web/src/ApplicationEditPage.js
+++ b/web/src/ApplicationEditPage.js
@@ -18,6 +18,7 @@ import {CopyOutlined, LinkOutlined, UploadOutlined} from "@ant-design/icons";
import * as ApplicationBackend from "./backend/ApplicationBackend";
import * as CertBackend from "./backend/CertBackend";
import * as Setting from "./Setting";
+import * as Conf from "./Conf";
import * as ProviderBackend from "./backend/ProviderBackend";
import * as OrganizationBackend from "./backend/OrganizationBackend";
import * as ResourceBackend from "./backend/ResourceBackend";
@@ -717,7 +718,7 @@ class ApplicationEditPage extends React.Component {
{
- const {_, ...theme} = this.state.application.themeData ?? {...Setting.ThemeDefault, isEnabled: false};
+ const {_, ...theme} = this.state.application.themeData ?? {...Conf.ThemeDefault, isEnabled: false};
this.updateApplicationField("themeData", {...theme, isEnabled: e.target.value});
}} >
{i18next.t("application:Follow organization theme")}
@@ -728,7 +729,7 @@ class ApplicationEditPage extends React.Component {
this.state.application.themeData?.isEnabled ?
{
- const {isEnabled} = this.state.application.themeData ?? {...Setting.ThemeDefault, isEnabled: false};
+ const {isEnabled} = this.state.application.themeData ?? {...Conf.ThemeDefault, isEnabled: false};
this.updateApplicationField("themeData", {...nextThemeData, isEnabled});
}} />
: null
@@ -764,7 +765,7 @@ class ApplicationEditPage extends React.Component {
}
renderSignupSigninPreview() {
- const themeData = this.state.application.themeData ?? Setting.ThemeDefault;
+ const themeData = this.state.application.themeData ?? Conf.ThemeDefault;
let signUpUrl = `/signup/${this.state.application.name}`;
const signInUrl = `/login/oauth/authorize?client_id=${this.state.application.clientId}&response_type=code&redirect_uri=${this.state.application.redirectUris[0]}&scope=read&state=casdoor`;
const maskStyle = {position: "absolute", top: "0px", left: "0px", zIndex: 10, height: "97%", width: "100%", background: "rgba(0,0,0,0.4)"};
@@ -835,7 +836,7 @@ class ApplicationEditPage extends React.Component {
}
renderPromptPreview() {
- const themeData = this.state.application.themeData ?? Setting.ThemeDefault;
+ const themeData = this.state.application.themeData ?? Conf.ThemeDefault;
const promptUrl = `/prompt/${this.state.application.name}`;
const maskStyle = {position: "absolute", top: "0px", left: "0px", zIndex: 10, height: "100%", width: "100%", background: "rgba(0,0,0,0.4)"};
return (
diff --git a/web/src/Conf.js b/web/src/Conf.js
index 5d57cdfb..80b00c94 100644
--- a/web/src/Conf.js
+++ b/web/src/Conf.js
@@ -17,6 +17,13 @@ export const GithubRepo = "https://github.com/casdoor/casdoor";
export const ForceLanguage = "";
export const DefaultLanguage = "en";
-export const InitThemeAlgorithm = true;
export const EnableExtraPages = true;
+
+export const InitThemeAlgorithm = true;
+export const ThemeDefault = {
+ themeType: "default",
+ colorPrimary: "#5734d3",
+ borderRadius: 6,
+ isCompact: false,
+};
diff --git a/web/src/EntryPage.js b/web/src/EntryPage.js
index f6e8139e..b3a04c22 100644
--- a/web/src/EntryPage.js
+++ b/web/src/EntryPage.js
@@ -17,6 +17,7 @@ import {Redirect, Route, Switch} from "react-router-dom";
import {Spin} from "antd";
import i18next from "i18next";
import * as Setting from "./Setting";
+import * as Conf from "./Conf";
import SignupPage from "./auth/SignupPage";
import SelfLoginPage from "./auth/SelfLoginPage";
import LoginPage from "./auth/LoginPage";
@@ -62,7 +63,7 @@ class EntryPage extends React.Component {
application: application,
});
- const themeData = application !== null ? Setting.getThemeData(application.organizationObj, application) : Setting.ThemeDefault;
+ const themeData = application !== null ? Setting.getThemeData(application.organizationObj, application) : Conf.ThemeDefault;
this.props.updataThemeData(themeData);
};
diff --git a/web/src/OrganizationEditPage.js b/web/src/OrganizationEditPage.js
index 6ab38972..87495d92 100644
--- a/web/src/OrganizationEditPage.js
+++ b/web/src/OrganizationEditPage.js
@@ -18,6 +18,7 @@ import * as OrganizationBackend from "./backend/OrganizationBackend";
import * as ApplicationBackend from "./backend/ApplicationBackend";
import * as LdapBackend from "./backend/LdapBackend";
import * as Setting from "./Setting";
+import * as Conf from "./Conf";
import i18next from "i18next";
import {LinkOutlined} from "@ant-design/icons";
import LdapTable from "./LdapTable";
@@ -324,7 +325,7 @@ class OrganizationEditPage extends React.Component {
{
- const {_, ...theme} = this.state.organization.themeData ?? {...Setting.ThemeDefault, isEnabled: false};
+ const {_, ...theme} = this.state.organization.themeData ?? {...Conf.ThemeDefault, isEnabled: false};
this.updateOrganizationField("themeData", {...theme, isEnabled: e.target.value});
}} >
{i18next.t("organization:Follow global theme")}
@@ -335,7 +336,7 @@ class OrganizationEditPage extends React.Component {
this.state.organization.themeData?.isEnabled ?
{
- const {isEnabled} = this.state.organization.themeData ?? {...Setting.ThemeDefault, isEnabled: false};
+ const {isEnabled} = this.state.organization.themeData ?? {...Conf.ThemeDefault, isEnabled: false};
this.updateOrganizationField("themeData", {...nextThemeData, isEnabled});
}} />
: null
diff --git a/web/src/ResetModal.js b/web/src/ResetModal.js
index 48780e66..9bab365a 100644
--- a/web/src/ResetModal.js
+++ b/web/src/ResetModal.js
@@ -17,7 +17,7 @@ import i18next from "i18next";
import React from "react";
import * as Setting from "./Setting";
import * as UserBackend from "./backend/UserBackend";
-import {CountDownInput} from "./common/CountDownInput";
+import {SendCodeInput} from "./common/SendCodeInput";
import {MailOutlined, PhoneOutlined} from "@ant-design/icons";
export const ResetModal = (props) => {
@@ -93,7 +93,7 @@ export const ResetModal = (props) => {
/>
-
@@ -32,12 +42,12 @@ class SelectLanguageBox extends React.Component {
languages: props.languages ?? ["en", "zh", "es", "fr", "de", "ja", "ko", "ru"],
};
- Setting.Countries.forEach((country) => {
+ Countries.forEach((country) => {
new Image().src = `${Setting.StaticBaseUrl}/flag-icons/${country.country}.svg`;
});
}
- items = Setting.Countries.map((country) => Setting.getItem(country.label, country.key, flagIcon(country.country, country.alt)));
+ items = Countries.map((country) => Setting.getItem(country.label, country.key, flagIcon(country.country, country.alt)));
getOrganizationLanguages(languages) {
const select = [];
diff --git a/web/src/SelectRegionBox.js b/web/src/SelectRegionBox.js
index 8f1a2ffa..077f603a 100644
--- a/web/src/SelectRegionBox.js
+++ b/web/src/SelectRegionBox.js
@@ -49,8 +49,8 @@ class SelectRegionBox extends React.Component {
}
>
{
- Setting.CountryRegionData.map((item, index) => (
-
diff --git a/web/src/Setting.js b/web/src/Setting.js
index ad00f33d..a11baef9 100644
--- a/web/src/Setting.js
+++ b/web/src/Setting.js
@@ -30,33 +30,13 @@ export const ServerUrl = "";
// export const StaticBaseUrl = "https://cdn.jsdelivr.net/gh/casbin/static";
export const StaticBaseUrl = "https://cdn.casbin.org";
-// https://catamphetamine.gitlab.io/country-flag-icons/3x2/index.html
-export const CountryRegionData = getCountryRegionData();
-
-export const Countries = [{label: "English", key: "en", country: "US", alt: "English"},
- {label: "简体中文", key: "zh", country: "CN", alt: "简体中文"},
- {label: "Español", key: "es", country: "ES", alt: "Español"},
- {label: "Français", key: "fr", country: "FR", alt: "Français"},
- {label: "Deutsch", key: "de", country: "DE", alt: "Deutsch"},
- {label: "日本語", key: "ja", country: "JP", alt: "日本語"},
- {label: "한국어", key: "ko", country: "KR", alt: "한국어"},
- {label: "Русский", key: "ru", country: "RU", alt: "Русский"},
-];
-
-export const ThemeDefault = {
- themeType: "default",
- colorPrimary: "#5734d3",
- borderRadius: 6,
- isCompact: false,
-};
-
export function getThemeData(organization, application) {
if (application?.themeData?.isEnabled) {
return application.themeData;
} else if (organization?.themeData?.isEnabled) {
return organization.themeData;
} else {
- return ThemeDefault;
+ return Conf.ThemeDefault;
}
}
@@ -208,18 +188,18 @@ export const OtherProviderInfo = {
},
};
-export function getCountryRegionData() {
- let language = i18next.language;
- if (language === null || language === "null") {
- language = Conf.DefaultLanguage;
- }
-
+export function getCountriesData() {
const countries = require("i18n-iso-countries");
- countries.registerLocale(require("i18n-iso-countries/langs/" + language + ".json"));
- const data = countries.getNames(language, {select: "official"});
- const result = [];
- for (const i in data) {result.push({code: i, name: data[i]});}
- return result;
+ countries.registerLocale(require("i18n-iso-countries/langs/" + getLanguage() + ".json"));
+ return countries;
+}
+
+export function getCountryNames() {
+ const data = getCountriesData().getNames(getLanguage(), {select: "official"});
+
+ return Object.entries(data).map(items => {
+ return {code: items[0], name: items[1]};
+ });
}
export function initServerUrl() {
@@ -702,7 +682,7 @@ export function getLanguageText(text) {
}
export function getLanguage() {
- return i18next.language;
+ return i18next.language ?? Conf.DefaultLanguage;
}
export function setLanguage(language) {
diff --git a/web/src/UserListPage.js b/web/src/UserListPage.js
index 69fe8820..e01714ad 100644
--- a/web/src/UserListPage.js
+++ b/web/src/UserListPage.js
@@ -135,13 +135,6 @@ class UserListPage extends BaseListPage {
}
renderTable(users) {
- // transfer country code to name based on selected language
- const countries = require("i18n-iso-countries");
- countries.registerLocale(require("i18n-iso-countries/langs/" + i18next.language + ".json"));
- for (const index in users) {
- users[index].region = countries.getName(users[index].region, i18next.language, {select: "official"});
- }
-
const columns = [
{
title: i18next.t("general:Organization"),
@@ -267,6 +260,9 @@ class UserListPage extends BaseListPage {
width: "140px",
sorter: true,
...this.getColumnSearchProps("region"),
+ render: (text, record, index) => {
+ return Setting.getCountriesData().getName(record.region, Setting.getLanguage(), {select: "official"});
+ },
},
{
title: i18next.t("user:Tag"),
diff --git a/web/src/auth/ForgetPage.js b/web/src/auth/ForgetPage.js
index 5d977b18..a20a7d85 100644
--- a/web/src/auth/ForgetPage.js
+++ b/web/src/auth/ForgetPage.js
@@ -19,7 +19,7 @@ import * as ApplicationBackend from "../backend/ApplicationBackend";
import * as Util from "./Util";
import * as Setting from "../Setting";
import i18next from "i18next";
-import {CountDownInput} from "../common/CountDownInput";
+import {SendCodeInput} from "../common/SendCodeInput";
import * as UserBackend from "../backend/UserBackend";
import {CheckCircleOutlined, KeyOutlined, LockOutlined, SolutionOutlined, UserOutlined} from "@ant-design/icons";
import CustomGithubCorner from "../CustomGithubCorner";
@@ -350,14 +350,14 @@ class ForgetPage extends React.Component {
]}
>
{this.state.verifyType === "email" ? (
-
) : (
- {
@@ -755,7 +755,7 @@ class LoginPage extends React.Component {
name="code"
rules={[{required: true, message: i18next.t("login:Please input your code!")}]}
>
-
-
- res.json());
}
-export function sendCode(checkType, checkId, checkKey, method, dest, type, applicationId, checkUser) {
+export function sendCode(checkType, checkId, checkKey, method, dest, type, applicationId, checkUser = "") {
const formData = new FormData();
formData.append("checkType", checkType);
formData.append("checkId", checkId);
diff --git a/web/src/common/CountDownInput.js b/web/src/common/SendCodeInput.js
similarity index 99%
rename from web/src/common/CountDownInput.js
rename to web/src/common/SendCodeInput.js
index 26cfc390..d95bac37 100644
--- a/web/src/common/CountDownInput.js
+++ b/web/src/common/SendCodeInput.js
@@ -21,7 +21,7 @@ import {CaptchaWidget} from "./CaptchaWidget";
const {Search} = Input;
-export const CountDownInput = (props) => {
+export const SendCodeInput = (props) => {
const {disabled, textBefore, onChange, onButtonClickArgs, application, method} = props;
const [visible, setVisible] = React.useState(false);
const [key, setKey] = React.useState("");
diff --git a/web/src/common/theme/ThemeEditor.js b/web/src/common/theme/ThemeEditor.js
index 5934e566..11ccb37c 100644
--- a/web/src/common/theme/ThemeEditor.js
+++ b/web/src/common/theme/ThemeEditor.js
@@ -14,14 +14,13 @@
import {Card, ConfigProvider, Form, Layout, Switch, theme} from "antd";
import ThemePicker from "./ThemePicker";
-import ColorPicker from "./ColorPicker";
+import ColorPicker, {GREEN_COLOR, PINK_COLOR} from "./ColorPicker";
import RadiusPicker from "./RadiusPicker";
import * as React from "react";
-import {GREEN_COLOR, PINK_COLOR} from "./ColorPicker";
+import {useEffect} from "react";
import {Content} from "antd/es/layout/layout";
import i18next from "i18next";
-import {useEffect} from "react";
-import * as Setting from "../../Setting";
+import * as Conf from "../../Conf";
const ThemesInfo = {
default: {},
@@ -41,7 +40,7 @@ const ThemesInfo = {
const onChange = () => {};
export default function ThemeEditor(props) {
- const themeData = props.themeData ?? Setting.ThemeDefault;
+ const themeData = props.themeData ?? Conf.ThemeDefault;
const onThemeChange = props.onThemeChange ?? onChange;
const {isCompact, themeType, ...themeToken} = themeData;
@@ -59,7 +58,7 @@ export default function ThemeEditor(props) {
}, [isLight, isCompact]);
useEffect(() => {
- const mergedData = Object.assign(Object.assign(Object.assign({}, Setting.ThemeDefault), {themeType}), ThemesInfo[themeType]);
+ const mergedData = Object.assign(Object.assign(Object.assign({}, Conf.ThemeDefault), {themeType}), ThemesInfo[themeType]);
onThemeChange(null, mergedData);
form.setFieldsValue(mergedData);
}, [themeType]);