2022-02-13 23:39:27 +08:00
|
|
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
2020-10-20 22:37:38 +08:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2024-02-27 22:31:02 +08:00
|
|
|
import React, {Component, Suspense, lazy} from "react";
|
2022-07-10 15:45:55 +08:00
|
|
|
import "./App.less";
|
2021-04-29 19:51:03 +08:00
|
|
|
import {Helmet} from "react-helmet";
|
2020-10-20 22:37:38 +08:00
|
|
|
import * as Setting from "./Setting";
|
2023-03-09 22:01:39 +08:00
|
|
|
import {StyleProvider, legacyLogicalPropertiesTransformer} from "@ant-design/cssinjs";
|
2024-02-27 18:49:23 +08:00
|
|
|
import {GithubOutlined, InfoCircleFilled, ShareAltOutlined} from "@ant-design/icons";
|
|
|
|
import {Alert, Button, ConfigProvider, Drawer, FloatButton, Layout, Result, Tooltip} from "antd";
|
|
|
|
import {Route, Switch, withRouter} from "react-router-dom";
|
2023-03-26 18:44:47 +08:00
|
|
|
import CustomGithubCorner from "./common/CustomGithubCorner";
|
2022-03-05 23:51:55 +08:00
|
|
|
import * as Conf from "./Conf";
|
2021-02-14 15:40:57 +08:00
|
|
|
|
2021-02-14 16:59:08 +08:00
|
|
|
import * as Auth from "./auth/Auth";
|
2022-12-22 23:39:02 +08:00
|
|
|
import EntryPage from "./EntryPage";
|
2021-02-14 15:40:57 +08:00
|
|
|
import * as AuthBackend from "./auth/AuthBackend";
|
2021-02-14 14:34:03 +08:00
|
|
|
import AuthCallback from "./auth/AuthCallback";
|
2022-07-10 15:45:55 +08:00
|
|
|
import SamlCallback from "./auth/SamlCallback";
|
2023-07-07 12:30:07 +08:00
|
|
|
import i18next from "i18next";
|
2022-10-12 13:52:02 +02:00
|
|
|
import {withTranslation} from "react-i18next";
|
2024-02-27 22:31:02 +08:00
|
|
|
const ManagementPage = lazy(() => import("./ManagementPage"));
|
2024-02-27 18:49:23 +08:00
|
|
|
const {Footer, Content} = Layout;
|
2020-10-20 22:37:38 +08:00
|
|
|
|
2023-08-05 17:52:16 +08:00
|
|
|
import {setTwoToneColor} from "@ant-design/icons";
|
|
|
|
|
|
|
|
setTwoToneColor("rgb(87,52,211)");
|
|
|
|
|
2020-10-20 22:37:38 +08:00
|
|
|
class App extends Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2024-02-25 00:05:13 +08:00
|
|
|
let storageThemeAlgorithm = [];
|
|
|
|
try {
|
|
|
|
storageThemeAlgorithm = localStorage.getItem("themeAlgorithm") ? JSON.parse(localStorage.getItem("themeAlgorithm")) : ["default"];
|
|
|
|
} catch {
|
|
|
|
storageThemeAlgorithm = ["default"];
|
|
|
|
}
|
2020-10-20 22:37:38 +08:00
|
|
|
this.state = {
|
|
|
|
classes: props,
|
|
|
|
selectedMenuKey: 0,
|
|
|
|
account: undefined,
|
2021-03-26 21:57:41 +08:00
|
|
|
uri: null,
|
2024-02-25 00:05:13 +08:00
|
|
|
themeAlgorithm: storageThemeAlgorithm,
|
2023-02-12 18:56:56 +08:00
|
|
|
themeData: Conf.ThemeDefault,
|
2024-02-25 00:05:13 +08:00
|
|
|
logo: this.getLogo(storageThemeAlgorithm),
|
2023-07-07 12:30:07 +08:00
|
|
|
requiredEnableMfa: false,
|
2023-10-28 23:58:51 +08:00
|
|
|
isAiAssistantOpen: false,
|
2020-10-20 22:37:38 +08:00
|
|
|
};
|
2020-10-20 23:14:03 +08:00
|
|
|
Setting.initServerUrl();
|
2021-02-14 16:59:08 +08:00
|
|
|
Auth.initAuthWithConfig({
|
|
|
|
serverUrl: Setting.ServerUrl,
|
2023-07-02 09:15:22 +08:00
|
|
|
appName: Conf.DefaultApplication, // the application used in Casdoor root path: "/"
|
2021-02-14 16:59:08 +08:00
|
|
|
});
|
2020-10-20 22:37:38 +08:00
|
|
|
}
|
|
|
|
|
2021-03-27 11:38:15 +08:00
|
|
|
UNSAFE_componentWillMount() {
|
2020-10-20 22:37:38 +08:00
|
|
|
this.updateMenuKey();
|
|
|
|
this.getAccount();
|
|
|
|
}
|
|
|
|
|
2023-07-07 12:30:07 +08:00
|
|
|
componentDidUpdate(prevProps, prevState, snapshot) {
|
2021-03-26 21:57:41 +08:00
|
|
|
const uri = location.pathname;
|
|
|
|
if (this.state.uri !== uri) {
|
|
|
|
this.updateMenuKey();
|
|
|
|
}
|
2023-07-07 12:30:07 +08:00
|
|
|
|
|
|
|
if (this.state.account !== prevState.account) {
|
|
|
|
const requiredEnableMfa = Setting.isRequiredEnableMfa(this.state.account, this.state.account?.organization);
|
|
|
|
this.setState({
|
|
|
|
requiredEnableMfa: requiredEnableMfa,
|
|
|
|
});
|
|
|
|
|
2023-07-08 22:35:31 +08:00
|
|
|
if (requiredEnableMfa === true) {
|
2023-10-28 23:58:51 +08:00
|
|
|
const mfaType = Setting.getMfaItemsByRules(this.state.account, this.state.account?.organization, [Setting.MfaRuleRequired])
|
|
|
|
.find((item) => item.rule === Setting.MfaRuleRequired)?.name;
|
2023-07-07 12:30:07 +08:00
|
|
|
if (mfaType !== undefined) {
|
|
|
|
this.props.history.push(`/mfa/setup?mfaType=${mfaType}`, {from: "/login"});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-26 21:57:41 +08:00
|
|
|
}
|
|
|
|
|
2020-10-20 22:37:38 +08:00
|
|
|
updateMenuKey() {
|
|
|
|
const uri = location.pathname;
|
2021-03-26 21:57:41 +08:00
|
|
|
this.setState({
|
|
|
|
uri: uri,
|
|
|
|
});
|
2023-08-20 00:58:39 +08:00
|
|
|
if (uri === "/" || uri.includes("/shortcuts") || uri.includes("/apps")) {
|
|
|
|
this.setState({selectedMenuKey: "/home"});
|
2023-12-31 19:48:58 +08:00
|
|
|
} else if (uri.includes("/organizations") || uri.includes("/trees") || uri.includes("/groups") || uri.includes("/users") || uri.includes("/invitations")) {
|
2023-08-05 17:41:35 +08:00
|
|
|
this.setState({selectedMenuKey: "/orgs"});
|
|
|
|
} else if (uri.includes("/applications") || uri.includes("/providers") || uri.includes("/resources") || uri.includes("/certs")) {
|
|
|
|
this.setState({selectedMenuKey: "/identity"});
|
2023-08-12 02:44:38 +08:00
|
|
|
} else if (uri.includes("/roles") || uri.includes("/permissions") || uri.includes("/models") || uri.includes("/adapters") || uri.includes("/enforcers")) {
|
|
|
|
this.setState({selectedMenuKey: "/auth"});
|
2023-08-05 17:41:35 +08:00
|
|
|
} else if (uri.includes("/records") || uri.includes("/tokens") || uri.includes("/sessions")) {
|
|
|
|
this.setState({selectedMenuKey: "/logs"});
|
|
|
|
} else if (uri.includes("/products") || uri.includes("/payments") || uri.includes("/plans") || uri.includes("/pricings") || uri.includes("/subscriptions")) {
|
|
|
|
this.setState({selectedMenuKey: "/business"});
|
|
|
|
} else if (uri.includes("/sysinfo") || uri.includes("/syncers") || uri.includes("/webhooks")) {
|
|
|
|
this.setState({selectedMenuKey: "/admin"});
|
2022-07-10 15:45:55 +08:00
|
|
|
} else if (uri.includes("/signup")) {
|
|
|
|
this.setState({selectedMenuKey: "/signup"});
|
|
|
|
} else if (uri.includes("/login")) {
|
|
|
|
this.setState({selectedMenuKey: "/login"});
|
|
|
|
} else if (uri.includes("/result")) {
|
|
|
|
this.setState({selectedMenuKey: "/result"});
|
2020-10-20 22:37:38 +08:00
|
|
|
} else {
|
2022-07-10 15:45:55 +08:00
|
|
|
this.setState({selectedMenuKey: -1});
|
2020-10-20 22:37:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-28 21:33:10 +08:00
|
|
|
getAccessTokenParam(params) {
|
2021-03-28 16:35:59 +08:00
|
|
|
// "/page?access_token=123"
|
2021-05-16 18:18:55 +08:00
|
|
|
const accessToken = params.get("access_token");
|
|
|
|
return accessToken === null ? "" : `?accessToken=${accessToken}`;
|
|
|
|
}
|
|
|
|
|
2022-02-28 21:33:10 +08:00
|
|
|
getCredentialParams(params) {
|
2021-05-16 18:18:55 +08:00
|
|
|
// "/page?username=abc&password=123"
|
|
|
|
if (params.get("username") === null || params.get("password") === null) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
return `?username=${params.get("username")}&password=${params.get("password")}`;
|
2021-03-28 16:35:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
getUrlWithoutQuery() {
|
2022-02-28 21:33:10 +08:00
|
|
|
return window.location.toString().replace(window.location.search, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
getLanguageParam(params) {
|
|
|
|
// "/page?language=en"
|
|
|
|
const language = params.get("language");
|
|
|
|
if (language !== null) {
|
|
|
|
Setting.setLanguage(language);
|
|
|
|
return `language=${language}`;
|
|
|
|
}
|
|
|
|
return "";
|
2021-03-28 16:35:59 +08:00
|
|
|
}
|
|
|
|
|
2023-02-01 22:06:40 +08:00
|
|
|
getLogo(themes) {
|
|
|
|
if (themes.includes("dark")) {
|
|
|
|
return `${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256_dark.png`;
|
|
|
|
} else {
|
|
|
|
return `${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256.png`;
|
|
|
|
}
|
2022-12-29 15:30:37 +01:00
|
|
|
}
|
|
|
|
|
2021-09-14 01:22:13 +08:00
|
|
|
setLanguage(account) {
|
2022-08-08 23:35:24 +08:00
|
|
|
const language = account?.language;
|
2023-06-03 10:15:29 +08:00
|
|
|
if (language !== null && language !== "" && language !== i18next.language) {
|
2021-09-14 01:22:13 +08:00
|
|
|
Setting.setLanguage(language);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-01 22:06:40 +08:00
|
|
|
setTheme = (theme, initThemeAlgorithm) => {
|
|
|
|
this.setState({
|
|
|
|
themeData: theme,
|
|
|
|
});
|
|
|
|
|
|
|
|
if (initThemeAlgorithm) {
|
2024-02-25 00:05:13 +08:00
|
|
|
if (localStorage.getItem("themeAlgorithm")) {
|
|
|
|
let storageThemeAlgorithm = [];
|
|
|
|
try {
|
|
|
|
storageThemeAlgorithm = JSON.parse(localStorage.getItem("themeAlgorithm"));
|
|
|
|
} catch {
|
|
|
|
storageThemeAlgorithm = ["default"];
|
|
|
|
}
|
|
|
|
this.setState({
|
|
|
|
logo: this.getLogo(storageThemeAlgorithm),
|
|
|
|
themeAlgorithm: storageThemeAlgorithm,
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
2023-02-01 22:06:40 +08:00
|
|
|
this.setState({
|
|
|
|
logo: this.getLogo(Setting.getAlgorithmNames(theme)),
|
|
|
|
themeAlgorithm: Setting.getAlgorithmNames(theme),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-10-20 22:37:38 +08:00
|
|
|
getAccount() {
|
2022-02-28 21:33:10 +08:00
|
|
|
const params = new URLSearchParams(this.props.location.search);
|
|
|
|
|
|
|
|
let query = this.getAccessTokenParam(params);
|
2021-05-16 18:18:55 +08:00
|
|
|
if (query === "") {
|
2022-02-28 21:33:10 +08:00
|
|
|
query = this.getCredentialParams(params);
|
|
|
|
}
|
|
|
|
|
|
|
|
const query2 = this.getLanguageParam(params);
|
|
|
|
if (query2 !== "") {
|
|
|
|
const url = window.location.toString().replace(new RegExp(`[?&]${query2}`), "");
|
|
|
|
window.history.replaceState({}, document.title, url);
|
2021-05-16 18:18:55 +08:00
|
|
|
}
|
2022-02-28 21:33:10 +08:00
|
|
|
|
2021-05-16 18:18:55 +08:00
|
|
|
if (query !== "") {
|
2021-03-28 16:35:59 +08:00
|
|
|
window.history.replaceState({}, document.title, this.getUrlWithoutQuery());
|
|
|
|
}
|
2022-02-28 21:33:10 +08:00
|
|
|
|
2021-05-16 18:18:55 +08:00
|
|
|
AuthBackend.getAccount(query)
|
2020-10-20 22:37:38 +08:00
|
|
|
.then((res) => {
|
2021-04-29 19:51:03 +08:00
|
|
|
let account = null;
|
|
|
|
if (res.status === "ok") {
|
|
|
|
account = res.data;
|
|
|
|
account.organization = res.data2;
|
2023-02-01 22:06:40 +08:00
|
|
|
|
2021-09-14 01:22:13 +08:00
|
|
|
this.setLanguage(account);
|
2023-02-01 22:06:40 +08:00
|
|
|
this.setTheme(Setting.getThemeData(account.organization), Conf.InitThemeAlgorithm);
|
2021-05-15 23:34:06 +08:00
|
|
|
} else {
|
2022-10-27 23:50:45 +08:00
|
|
|
if (res.data !== "Please login first") {
|
2022-12-09 15:11:13 +08:00
|
|
|
Setting.showMessage("error", `${i18next.t("application:Failed to sign in")}: ${res.msg}`);
|
2021-05-15 23:34:06 +08:00
|
|
|
}
|
2021-04-29 19:51:03 +08:00
|
|
|
}
|
|
|
|
|
2020-10-20 22:37:38 +08:00
|
|
|
this.setState({
|
2021-04-29 19:51:03 +08:00
|
|
|
account: account,
|
2020-10-20 22:37:38 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-06-20 13:27:26 +08:00
|
|
|
onUpdateAccount(account) {
|
|
|
|
this.setState({
|
2022-08-06 23:54:56 +08:00
|
|
|
account: account,
|
2021-06-20 13:27:26 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-10-20 22:37:38 +08:00
|
|
|
renderFooter() {
|
|
|
|
return (
|
2022-12-22 23:39:02 +08:00
|
|
|
<React.Fragment>
|
2022-09-23 16:03:09 +08:00
|
|
|
{!this.state.account ? null : <div style={{display: "none"}} id="CasdoorApplicationName" value={this.state.account.signupApplication} />}
|
|
|
|
<Footer id="footer" style={
|
|
|
|
{
|
|
|
|
textAlign: "center",
|
|
|
|
}
|
|
|
|
}>
|
2023-05-15 16:49:45 +08:00
|
|
|
{
|
|
|
|
Conf.CustomFooter !== null ? Conf.CustomFooter : (
|
|
|
|
<React.Fragment>
|
|
|
|
Powered by <a target="_blank" href="https://casdoor.org" rel="noreferrer"><img style={{paddingBottom: "3px"}} height={"20px"} alt={"Casdoor"} src={this.state.logo} /></a>
|
|
|
|
</React.Fragment>
|
|
|
|
)
|
|
|
|
}
|
2022-09-23 16:03:09 +08:00
|
|
|
</Footer>
|
2022-12-22 23:39:02 +08:00
|
|
|
</React.Fragment>
|
2022-07-10 15:45:55 +08:00
|
|
|
);
|
2020-10-20 22:37:38 +08:00
|
|
|
}
|
|
|
|
|
2023-10-28 23:58:51 +08:00
|
|
|
renderAiAssistant() {
|
|
|
|
return (
|
|
|
|
<Drawer
|
|
|
|
title={
|
|
|
|
<React.Fragment>
|
|
|
|
<Tooltip title="Want to deploy your own AI assistant? Click to learn more!">
|
|
|
|
<a target="_blank" rel="noreferrer" href={"https://casdoor.com"}>
|
|
|
|
<img style={{width: "20px", marginRight: "10px", marginBottom: "2px"}} alt="help" src="https://casbin.org/img/casbin.svg" />
|
|
|
|
AI Assistant
|
|
|
|
</a>
|
|
|
|
</Tooltip>
|
|
|
|
<a className="custom-link" style={{float: "right", marginTop: "2px"}} target="_blank" rel="noreferrer" href={"https://ai.casbin.com"}>
|
|
|
|
<ShareAltOutlined className="custom-link" style={{fontSize: "20px", color: "rgb(140,140,140)"}} />
|
|
|
|
</a>
|
|
|
|
<a className="custom-link" style={{float: "right", marginRight: "30px", marginTop: "2px"}} target="_blank" rel="noreferrer" href={"https://github.com/casibase/casibase"}>
|
|
|
|
<GithubOutlined className="custom-link" style={{fontSize: "20px", color: "rgb(140,140,140)"}} />
|
|
|
|
</a>
|
|
|
|
</React.Fragment>
|
|
|
|
}
|
|
|
|
placement="right"
|
|
|
|
width={500}
|
|
|
|
mask={false}
|
|
|
|
onClose={() => {
|
|
|
|
this.setState({
|
|
|
|
isAiAssistantOpen: false,
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
visible={this.state.isAiAssistantOpen}
|
|
|
|
>
|
|
|
|
<iframe id="iframeHelper" title={"iframeHelper"} src={"https://ai.casbin.com/?isRaw=1"} width="100%" height="100%" scrolling="no" frameBorder="no" />
|
|
|
|
</Drawer>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-02-11 16:43:30 +08:00
|
|
|
isDoorPages() {
|
2022-12-22 23:39:02 +08:00
|
|
|
return this.isEntryPages() || window.location.pathname.startsWith("/callback");
|
|
|
|
}
|
|
|
|
|
|
|
|
isEntryPages() {
|
2021-06-09 20:38:46 +08:00
|
|
|
return window.location.pathname.startsWith("/signup") ||
|
2023-02-02 16:43:51 +08:00
|
|
|
window.location.pathname.startsWith("/login") ||
|
|
|
|
window.location.pathname.startsWith("/forget") ||
|
|
|
|
window.location.pathname.startsWith("/prompt") ||
|
2023-05-05 01:08:56 +08:00
|
|
|
window.location.pathname.startsWith("/result") ||
|
2023-02-02 16:43:51 +08:00
|
|
|
window.location.pathname.startsWith("/cas") ||
|
2023-08-24 23:20:50 +08:00
|
|
|
window.location.pathname.startsWith("/select-plan") ||
|
2023-09-07 15:45:54 +08:00
|
|
|
window.location.pathname.startsWith("/buy-plan") ||
|
|
|
|
window.location.pathname.startsWith("/qrcode") ;
|
2021-02-11 16:43:30 +08:00
|
|
|
}
|
|
|
|
|
2024-02-27 18:49:23 +08:00
|
|
|
onClick = ({key}) => {
|
|
|
|
if (key !== "/swagger" && key !== "/records") {
|
|
|
|
if (this.state.requiredEnableMfa) {
|
|
|
|
Setting.showMessage("info", "Please enable MFA first!");
|
|
|
|
} else {
|
|
|
|
this.props.history.push(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-04-29 19:51:03 +08:00
|
|
|
renderPage() {
|
2021-02-11 16:43:30 +08:00
|
|
|
if (this.isDoorPages()) {
|
|
|
|
return (
|
2024-02-25 00:05:13 +08:00
|
|
|
<ConfigProvider theme={{
|
|
|
|
algorithm: Setting.getAlgorithm(["default"]),
|
|
|
|
}}>
|
|
|
|
<StyleProvider hashPriority="high" transformers={[legacyLogicalPropertiesTransformer]}>
|
|
|
|
<Layout id="parent-area">
|
|
|
|
<Content style={{display: "flex", justifyContent: "center"}}>
|
|
|
|
{
|
|
|
|
this.isEntryPages() ?
|
|
|
|
<EntryPage
|
|
|
|
account={this.state.account}
|
|
|
|
theme={this.state.themeData}
|
|
|
|
onLoginSuccess={(redirectUrl) => {
|
|
|
|
if (redirectUrl) {
|
|
|
|
localStorage.setItem("mfaRedirectUrl", redirectUrl);
|
|
|
|
}
|
|
|
|
this.getAccount();
|
|
|
|
}}
|
|
|
|
onUpdateAccount={(account) => this.onUpdateAccount(account)}
|
|
|
|
updataThemeData={this.setTheme}
|
|
|
|
/> :
|
|
|
|
<Switch>
|
|
|
|
<Route exact path="/callback" component={AuthCallback} />
|
|
|
|
<Route exact path="/callback/saml" component={SamlCallback} />
|
|
|
|
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")}
|
|
|
|
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>} />} />
|
|
|
|
</Switch>
|
|
|
|
}
|
|
|
|
</Content>
|
|
|
|
{
|
|
|
|
this.renderFooter()
|
|
|
|
}
|
|
|
|
{
|
|
|
|
this.renderAiAssistant()
|
|
|
|
}
|
|
|
|
</Layout>
|
|
|
|
</StyleProvider>
|
|
|
|
</ConfigProvider>
|
2022-07-10 15:45:55 +08:00
|
|
|
);
|
2021-02-11 16:43:30 +08:00
|
|
|
}
|
2020-10-20 22:37:38 +08:00
|
|
|
return (
|
2022-12-22 23:39:02 +08:00
|
|
|
<React.Fragment>
|
2023-03-19 01:01:39 +08:00
|
|
|
{/* { */}
|
|
|
|
{/* this.renderBanner() */}
|
|
|
|
{/* } */}
|
2022-12-04 23:05:30 +08:00
|
|
|
<FloatButton.BackTop />
|
2021-08-07 19:52:01 +08:00
|
|
|
<CustomGithubCorner />
|
2020-10-20 22:37:38 +08:00
|
|
|
{
|
2024-02-27 22:31:02 +08:00
|
|
|
<Suspense fallback={<div>loading</div>}>
|
|
|
|
<Layout id="parent-area">
|
|
|
|
<ManagementPage
|
|
|
|
account={this.state.account}
|
|
|
|
uri={this.state.uri}
|
|
|
|
themeData={this.state.themeData}
|
|
|
|
themeAlgorithm={this.state.themeAlgorithm}
|
|
|
|
selectedMenuKey={this.state.selectedMenuKey}
|
|
|
|
requiredEnableMfa={this.state.requiredEnableMfa}
|
|
|
|
menuVisible={this.state.menuVisible}
|
|
|
|
logo={this.state.logo}
|
|
|
|
onChangeTheme={this.setTheme}
|
|
|
|
onClick = {this.onClick}
|
|
|
|
onfinish={() => {
|
|
|
|
this.setState({requiredEnableMfa: false});
|
|
|
|
}}
|
|
|
|
openAiAssistant={() => {
|
|
|
|
this.setState({
|
|
|
|
isAiAssistantOpen: true,
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
setLogoAndThemeAlgorithm={(nextThemeAlgorithm) => {
|
|
|
|
this.setState({
|
|
|
|
themeAlgorithm: nextThemeAlgorithm,
|
|
|
|
logo: this.getLogo(nextThemeAlgorithm),
|
|
|
|
});
|
|
|
|
localStorage.setItem("themeAlgorithm", JSON.stringify(nextThemeAlgorithm));
|
|
|
|
}}
|
|
|
|
setLogoutState={() => {
|
|
|
|
this.setState({
|
|
|
|
account: null,
|
|
|
|
themeAlgorithm: ["default"],
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
{
|
|
|
|
this.renderFooter()
|
|
|
|
}
|
|
|
|
{
|
|
|
|
this.renderAiAssistant()
|
|
|
|
}
|
|
|
|
</Layout>
|
|
|
|
</Suspense>
|
2020-10-20 22:37:38 +08:00
|
|
|
}
|
2022-12-22 23:39:02 +08:00
|
|
|
</React.Fragment>
|
2020-10-20 22:37:38 +08:00
|
|
|
);
|
|
|
|
}
|
2021-04-29 19:51:03 +08:00
|
|
|
|
2023-02-18 18:07:23 +08:00
|
|
|
renderBanner() {
|
|
|
|
if (!Conf.IsDemoMode) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2023-02-18 23:39:32 +08:00
|
|
|
const language = Setting.getLanguage();
|
|
|
|
if (language === "en" || language === "zh") {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2023-02-18 18:07:23 +08:00
|
|
|
return (
|
|
|
|
<Alert type="info" banner showIcon={false} closable message={
|
|
|
|
<div style={{textAlign: "center"}}>
|
|
|
|
<InfoCircleFilled style={{color: "rgb(87,52,211)"}} />
|
|
|
|
|
|
|
|
{i18next.t("general:Found some texts still not translated? Please help us translate at")}
|
|
|
|
|
|
|
|
<a target="_blank" rel="noreferrer" href={"https://crowdin.com/project/casdoor-site"}>
|
|
|
|
Crowdin
|
|
|
|
</a>
|
|
|
|
! 🙏
|
|
|
|
</div>
|
|
|
|
} />
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-04-29 19:51:03 +08:00
|
|
|
render() {
|
2023-02-01 22:06:40 +08:00
|
|
|
return (
|
|
|
|
<React.Fragment>
|
|
|
|
{(this.state.account === undefined || this.state.account === null) ?
|
2021-04-29 19:51:03 +08:00
|
|
|
<Helmet>
|
2022-02-13 23:34:29 +08:00
|
|
|
<link rel="icon" href={"https://cdn.casdoor.com/static/favicon.png"} />
|
2023-02-01 22:06:40 +08:00
|
|
|
</Helmet> :
|
|
|
|
<Helmet>
|
|
|
|
<title>{this.state.account.organization?.displayName}</title>
|
|
|
|
<link rel="icon" href={this.state.account.organization?.favicon} />
|
2021-04-29 19:51:03 +08:00
|
|
|
</Helmet>
|
2023-02-01 22:06:40 +08:00
|
|
|
}
|
2022-12-04 23:05:30 +08:00
|
|
|
<ConfigProvider theme={{
|
|
|
|
token: {
|
2023-02-01 22:06:40 +08:00
|
|
|
colorPrimary: this.state.themeData.colorPrimary,
|
|
|
|
colorInfo: this.state.themeData.colorPrimary,
|
|
|
|
borderRadius: this.state.themeData.borderRadius,
|
2022-12-04 23:05:30 +08:00
|
|
|
},
|
2023-02-01 22:06:40 +08:00
|
|
|
algorithm: Setting.getAlgorithm(this.state.themeAlgorithm),
|
2022-12-04 23:05:30 +08:00
|
|
|
}}>
|
2023-03-09 22:01:39 +08:00
|
|
|
<StyleProvider hashPriority="high" transformers={[legacyLogicalPropertiesTransformer]}>
|
2023-02-22 20:57:57 +08:00
|
|
|
{
|
|
|
|
this.renderPage()
|
|
|
|
}
|
|
|
|
</StyleProvider>
|
2022-12-04 23:05:30 +08:00
|
|
|
</ConfigProvider>
|
2021-04-29 19:51:03 +08:00
|
|
|
</React.Fragment>
|
2022-07-10 15:45:55 +08:00
|
|
|
);
|
2021-04-29 19:51:03 +08:00
|
|
|
}
|
2020-10-20 21:46:44 +08:00
|
|
|
}
|
|
|
|
|
2022-10-12 13:52:02 +02:00
|
|
|
export default withRouter(withTranslation()(App));
|