mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
fix: region don't display in userEditPage (#1544)
This commit is contained in:
parent
478bd05db4
commit
950a274b23
@ -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();
|
||||
|
@ -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 {
|
||||
<Col span={22} style={{marginTop: "5px"}}>
|
||||
<Row>
|
||||
<Radio.Group value={this.state.application.themeData?.isEnabled ?? false} onChange={e => {
|
||||
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});
|
||||
}} >
|
||||
<Radio.Button value={false}>{i18next.t("application:Follow organization theme")}</Radio.Button>
|
||||
@ -728,7 +729,7 @@ class ApplicationEditPage extends React.Component {
|
||||
this.state.application.themeData?.isEnabled ?
|
||||
<Row style={{marginTop: "20px"}}>
|
||||
<ThemeEditor themeData={this.state.application.themeData} onThemeChange={(_, nextThemeData) => {
|
||||
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});
|
||||
}} />
|
||||
</Row> : 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 (
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
<Col span={22} style={{marginTop: "5px"}}>
|
||||
<Row>
|
||||
<Radio.Group value={this.state.organization.themeData?.isEnabled ?? false} onChange={e => {
|
||||
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});
|
||||
}} >
|
||||
<Radio.Button value={false}>{i18next.t("organization:Follow global theme")}</Radio.Button>
|
||||
@ -335,7 +336,7 @@ class OrganizationEditPage extends React.Component {
|
||||
this.state.organization.themeData?.isEnabled ?
|
||||
<Row style={{marginTop: "20px"}}>
|
||||
<ThemeEditor themeData={this.state.organization.themeData} onThemeChange={(_, nextThemeData) => {
|
||||
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});
|
||||
}} />
|
||||
</Row> : null
|
||||
|
@ -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) => {
|
||||
/>
|
||||
</Row>
|
||||
<Row style={{width: "100%", marginBottom: "20px"}}>
|
||||
<CountDownInput
|
||||
<SendCodeInput
|
||||
textBefore={i18next.t("code:Code You Received")}
|
||||
onChange={setCode}
|
||||
method={"reset"}
|
||||
|
@ -18,6 +18,16 @@ import {Dropdown} from "antd";
|
||||
import "./App.less";
|
||||
import {GlobalOutlined} from "@ant-design/icons";
|
||||
|
||||
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: "Русский"},
|
||||
];
|
||||
|
||||
function flagIcon(country, alt) {
|
||||
return (
|
||||
<img width={24} alt={alt} src={`${Setting.StaticBaseUrl}/flag-icons/${country}.svg`} />
|
||||
@ -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 = [];
|
||||
|
@ -49,8 +49,8 @@ class SelectRegionBox extends React.Component {
|
||||
}
|
||||
>
|
||||
{
|
||||
Setting.CountryRegionData.map((item, index) => (
|
||||
<Option key={index} value={item.code} label={`${item.name} (${item.code})`} >
|
||||
Setting.getCountryNames().map((item) => (
|
||||
<Option key={item.code} value={item.code} label={`${item.name} (${item.code})`} >
|
||||
<img src={`${Setting.StaticBaseUrl}/flag-icons/${item.code}.svg`} alt={item.name} height={20} style={{marginRight: 10}} />
|
||||
{`${item.name} (${item.code})`}
|
||||
</Option>
|
||||
|
@ -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) {
|
||||
|
@ -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"),
|
||||
|
@ -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" ? (
|
||||
<CountDownInput
|
||||
<SendCodeInput
|
||||
disabled={this.state.username === "" || this.state.verifyType === ""}
|
||||
method={"forget"}
|
||||
onButtonClickArgs={[this.state.email, "email", Setting.getApplicationName(this.getApplicationObj()), this.state.name]}
|
||||
application={application}
|
||||
/>
|
||||
) : (
|
||||
<CountDownInput
|
||||
<SendCodeInput
|
||||
disabled={this.state.username === "" || this.state.verifyType === ""}
|
||||
method={"forget"}
|
||||
onButtonClickArgs={[this.state.phone, "phone", Setting.getApplicationName(this.getApplicationObj()), this.state.name]}
|
||||
|
@ -26,7 +26,7 @@ import * as Setting from "../Setting";
|
||||
import SelfLoginButton from "./SelfLoginButton";
|
||||
import i18next from "i18next";
|
||||
import CustomGithubCorner from "../CustomGithubCorner";
|
||||
import {CountDownInput} from "../common/CountDownInput";
|
||||
import {SendCodeInput} from "../common/SendCodeInput";
|
||||
import SelectLanguageBox from "../SelectLanguageBox";
|
||||
import {CaptchaModal} from "../common/CaptchaModal";
|
||||
import RedirectForm from "../common/RedirectForm";
|
||||
@ -419,7 +419,7 @@ class LoginPage extends React.Component {
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t("login:Please input your username, Email or phone!"),
|
||||
message: i18next.t("login:Please input your Email or Phone!"),
|
||||
},
|
||||
{
|
||||
validator: (_, value) => {
|
||||
@ -755,7 +755,7 @@ class LoginPage extends React.Component {
|
||||
name="code"
|
||||
rules={[{required: true, message: i18next.t("login:Please input your code!")}]}
|
||||
>
|
||||
<CountDownInput
|
||||
<SendCodeInput
|
||||
disabled={this.state.username?.length === 0 || !this.state.validEmailOrPhone}
|
||||
method={"login"}
|
||||
onButtonClickArgs={[this.state.username, this.state.validEmail ? "email" : "phone", Setting.getApplicationName(application)]}
|
||||
|
@ -21,7 +21,7 @@ import i18next from "i18next";
|
||||
import * as Util from "./Util";
|
||||
import {authConfig} from "./Auth";
|
||||
import * as ApplicationBackend from "../backend/ApplicationBackend";
|
||||
import {CountDownInput} from "../common/CountDownInput";
|
||||
import {SendCodeInput} from "../common/SendCodeInput";
|
||||
import SelectRegionBox from "../SelectRegionBox";
|
||||
import CustomGithubCorner from "../CustomGithubCorner";
|
||||
import SelectLanguageBox from "../SelectLanguageBox";
|
||||
@ -365,7 +365,7 @@ class SignupPage extends React.Component {
|
||||
message: i18next.t("code:Please input your verification code!"),
|
||||
}]}
|
||||
>
|
||||
<CountDownInput
|
||||
<SendCodeInput
|
||||
disabled={!this.state.validEmail}
|
||||
method={"signup"}
|
||||
onButtonClickArgs={[this.state.email, "email", Setting.getApplicationName(application)]}
|
||||
@ -419,7 +419,7 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<CountDownInput
|
||||
<SendCodeInput
|
||||
disabled={!this.state.validPhone}
|
||||
method={"signup"}
|
||||
onButtonClickArgs={[this.state.phone, "phone", Setting.getApplicationName(application)]}
|
||||
|
@ -109,7 +109,7 @@ export function setPassword(userOwner, userName, oldPassword, newPassword) {
|
||||
}).then(res => 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);
|
||||
|
@ -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("");
|
@ -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]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user