From 950a274b2320ebe456991510bc6a4aeabc613c9d Mon Sep 17 00:00:00 2001 From: Yaodong Yu <2814461814@qq.com> Date: Sun, 12 Feb 2023 18:56:56 +0800 Subject: [PATCH] fix: region don't display in userEditPage (#1544) --- web/src/App.js | 4 +- web/src/ApplicationEditPage.js | 9 ++-- web/src/Conf.js | 9 +++- web/src/EntryPage.js | 3 +- web/src/OrganizationEditPage.js | 5 +- web/src/ResetModal.js | 4 +- web/src/SelectLanguageBox.js | 14 +++++- web/src/SelectRegionBox.js | 4 +- web/src/Setting.js | 46 ++++++------------- web/src/UserListPage.js | 10 ++-- web/src/auth/ForgetPage.js | 6 +-- web/src/auth/LoginPage.js | 6 +-- web/src/auth/SignupPage.js | 6 +-- web/src/backend/UserBackend.js | 2 +- .../{CountDownInput.js => SendCodeInput.js} | 2 +- web/src/common/theme/ThemeEditor.js | 11 ++--- 16 files changed, 68 insertions(+), 73 deletions(-) rename web/src/common/{CountDownInput.js => SendCodeInput.js} (99%) 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]);