diff --git a/web/src/App.js b/web/src/App.js index 8297055d..d6545931 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -44,6 +44,7 @@ import * as AuthBackend from "./auth/AuthBackend"; import AuthCallback from "./auth/AuthCallback"; import SelectLanguageBox from './SelectLanguageBox'; import i18next from 'i18next'; +import PromptPage from "./auth/PromptPage"; const { Header, Footer } = Layout; @@ -411,6 +412,7 @@ class App extends Component { return window.location.pathname.startsWith("/signup") || window.location.pathname.startsWith("/login") || window.location.pathname.startsWith("/callback") || + window.location.pathname.startsWith("/prompt") || window.location.pathname.startsWith("/forget"); } @@ -426,6 +428,8 @@ class App extends Component { this.renderHomeIfLoggedIn()}/> this.renderHomeIfLoggedIn()}/> + this.renderLoginIfNotLoggedIn()}/> + this.renderLoginIfNotLoggedIn()}/> ) } diff --git a/web/src/ApplicationEditPage.js b/web/src/ApplicationEditPage.js index 5f6dc3a2..73842cb9 100644 --- a/web/src/ApplicationEditPage.js +++ b/web/src/ApplicationEditPage.js @@ -25,6 +25,7 @@ import i18next from "i18next"; import UrlTable from "./UrlTable"; import ProviderTable from "./ProviderTable"; import SignupTable from "./SignupTable"; +import PromptPage from "./auth/PromptPage"; const { Option } = Select; @@ -312,6 +313,14 @@ class ApplicationEditPage extends React.Component { /> + + + {i18next.t("general:Preview")}: + + { + this.renderPreview2() + } + ) } @@ -355,6 +364,25 @@ class ApplicationEditPage extends React.Component { ) } + renderPreview2() { + let promptUrl = `/prompt/${this.state.application.name}`; + + return ( + + + + + +
+
+
+ +
+ +
+ ) + } + submitApplicationEdit() { let application = Setting.deepCopy(this.state.application); ApplicationBackend.updateApplication(this.state.application.owner, this.state.applicationName, application) diff --git a/web/src/UserEditPage.js b/web/src/UserEditPage.js index b7f8bf6b..b1fcc94c 100644 --- a/web/src/UserEditPage.js +++ b/web/src/UserEditPage.js @@ -322,7 +322,7 @@ class UserEditPage extends React.Component { { (this.state.application === null || this.state.user === null) ? null : ( - { return this.updateUserField(key, value)}} /> + { return this.updateUserField(key, value)}} /> ) } diff --git a/web/src/auth/PromptPage.js b/web/src/auth/PromptPage.js new file mode 100644 index 00000000..7f158a9b --- /dev/null +++ b/web/src/auth/PromptPage.js @@ -0,0 +1,147 @@ +// Copyright 2021 The casbin Authors. All Rights Reserved. +// +// 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. + +import React from "react"; +import {Button, Col, Row} from "antd"; +import * as ApplicationBackend from "../backend/ApplicationBackend"; +import * as Setting from "../Setting"; +import i18next from "i18next"; +import AffiliationSelect from "../common/AffiliationSelect"; +import * as UserBackend from "../backend/UserBackend"; + +class PromptPage extends React.Component { + constructor(props) { + super(props); + this.state = { + classes: props, + type: props.type, + applicationName: props.applicationName !== undefined ? props.applicationName : (props.match === undefined ? null : props.match.params.applicationName), + application: null, + user: Setting.deepCopy(this.props.account), + }; + } + + UNSAFE_componentWillMount() { + this.getApplication(); + } + + getApplication() { + if (this.state.applicationName === null) { + return; + } + + ApplicationBackend.getApplication("admin", this.state.applicationName) + .then((application) => { + this.setState({ + application: application, + }); + }); + } + + getApplicationObj() { + if (this.props.application !== undefined) { + return this.props.application; + } else { + return this.state.application; + } + } + + parseUserField(key, value) { + // if ([].includes(key)) { + // value = Setting.myParseInt(value); + // } + return value; + } + + updateUserField(key, value) { + value = this.parseUserField(key, value); + + let user = this.state.user; + user[key] = value; + this.setState({ + user: user, + }); + } + + renderContent(application) { + return ( +
+ { + (application === null || this.state.user === null) ? null : ( + { return this.updateUserField(key, value)}} /> + ) + } +
+ ) + } + + isAnswered() { + if (this.state.user === null) { + return false; + } + + return this.state.user.affiliation !== ""; + } + + submitUserEdit() { + let user = Setting.deepCopy(this.state.user); + UserBackend.updateUser(this.state.user.owner, this.state.user.name, user) + .then((res) => { + if (res.msg === "") { + Setting.showMessage("success", `Successfully saved`); + + Setting.goToLogin(this, this.getApplicationObj()); + } else { + Setting.showMessage("error", res.msg); + } + }) + .catch(error => { + Setting.showMessage("error", `Failed to connect to server: ${error}`); + }); + } + + render() { + const application = this.getApplicationObj(); + if (application === null) { + return null; + } + + return ( + + +
+ { + Setting.renderHelmet(application) + } + { + Setting.renderLogo(application) + } + { + this.renderContent(application) + } + + + + +
+ +
+
+ +
+ ) + } +} + +export default PromptPage; diff --git a/web/src/common/AffiliationSelect.js b/web/src/common/AffiliationSelect.js index 2948d2e7..2082bb5a 100644 --- a/web/src/common/AffiliationSelect.js +++ b/web/src/common/AffiliationSelect.js @@ -59,11 +59,11 @@ class AffiliationSelect extends React.Component { { this.props.application?.affiliationUrl === "" ? null : ( - + {i18next.t("user:Address")}: - - { + + { this.updateUserField('address', value); this.updateUserField('affiliation', ''); this.updateUserField('score', 0); @@ -74,17 +74,17 @@ class AffiliationSelect extends React.Component { ) } - + {i18next.t("user:Affiliation")}: - + { this.props.application?.affiliationUrl === "" ? ( { this.updateUserField('affiliation', e.target.value); }} /> ) : ( - { const name = value; const id = this.state.affiliationOptions.filter(affiliationOption => affiliationOption.name === name)[0].id; this.updateUserField('affiliation', name); diff --git a/web/src/locales/en.json b/web/src/locales/en.json index ca922898..2ca4c475 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -65,7 +65,8 @@ "EmailYou should verify your code in 10 min!": "You should verify your email verification code in 10 min!", "PhoneWrong code!": "Wrong phone verification code!", "EmailWrong code!": "Wrong email verification code!", - "Missing parameter.": "Missing parameter." + "Missing parameter.": "Missing parameter.", + "Submit and complete": "Submit and complete" }, "login": { @@ -179,6 +180,7 @@ "Login page preview": "Login page preview", "Test signup page..": "Test signup page..", "Test signin page..": "Test signin page..", + "Test prompt page..": "Test prompt page..", "Redirect URL": "Redirect URL", "Redirect URLs": "Redirect URLs", "Signup items": "Signup items" diff --git a/web/src/locales/zh.json b/web/src/locales/zh.json index 9f53f460..dd03014e 100644 --- a/web/src/locales/zh.json +++ b/web/src/locales/zh.json @@ -65,7 +65,8 @@ "EmailYou should verify your code in 10 min!": "你应该在 10 分钟之内验证邮箱", "PhoneWrong code!": "手机验证码错误", "EmailWrong code!": "邮箱验证码错误", - "Missing parameter.": "缺少参数" + "Missing parameter.": "缺少参数", + "Submit and complete": "完成提交" }, "login": { @@ -179,6 +180,7 @@ "Login page preview": "登录页面预览", "Test signup page..": "测试注册页面..", "Test signin page..": "测试登录页面..", + "Test prompt page..": "测试提醒页面..", "Redirect URL": "回调URL", "Redirect URLs": "回调URLs", "Signup items": "注册项"