Mercurial > gemma
changeset 539:924490b3395b
refac: Loginmask reworked
The login is now more stable.
The user gets better visual feedback for his actions.
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Thu, 30 Aug 2018 12:39:09 +0200 |
parents | 942a865986f6 |
children | b2d1c82b3e27 |
files | client/src/App.vue client/src/views/Login.vue |
diffstat | 2 files changed, 79 insertions(+), 126 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/App.vue Wed Aug 29 16:12:20 2018 +0200 +++ b/client/src/App.vue Thu Aug 30 12:39:09 2018 +0200 @@ -7,6 +7,8 @@ <style lang="scss"> html { height: 100%; + width: 100%; + margin: 0 auto; } body { min-height: 100%; @@ -20,14 +22,4 @@ text-align: center; color: #2c3e50; } -#nav { - padding: 30px; - a { - font-weight: bold; - color: #2c3e50; - &.router-link-exact-active { - color: #42b983; - } - } -} </style>
--- a/client/src/views/Login.vue Wed Aug 29 16:12:20 2018 +0200 +++ b/client/src/views/Login.vue Thu Aug 30 12:39:09 2018 +0200 @@ -1,138 +1,81 @@ (<template> - <div :class="loginStyle"> - <div> - <div class="logogroup d-flex flex-row justify-content-center"> + <div class="d-flex flex-column login shadow-lg"> + <div class="loginmask"> + <!-- logo section --> + <div class="d-flex flex-row justify-content-center mb-3"> <div class="logo"><img src="../assets/logo.png"></div> - <div class="title"><h1>{{ appTitle }}</h1></div> + <div class="title"> + <h1>{{ appTitle }}</h1> + </div> </div> - </div> - <div class="login-wrapper d-flex flex-row justify-content-center"> - <form class="loginform form-signin" @submit.prevent="login"> - <div id="alert" v-if="loginFailed" class="loginerrormessage alert alert-danger" role="alert"> - <span class="loginerror"><translate>Login failed</translate></span> - </div> - <div id="alert" v-if="passwordJustResetted" - class="loginerrormessage alert alert-danger" role="alert"> - <span class="loginerror" - ><translate>Password reset requested!</translate></span> - </div> - <div class="input-group mb-3 usernamegroup"> - <input type="text" v-model="user" id="inputUsername" class="form-control" :placeholder="usernameLabel" required autofocus> + <!-- end logo section --> + <div id="alert" :style="errorMessageStyle" :class="errorMessageClass" role="alert"> + <span>{{ errorMessage }}</span> + </div> + <form @submit.prevent="login"> + <div class="input-group mb-3"> + <input type="text" v-model="user" id="inputUsername" class="form-control shadow-sm" :placeholder="usernameLabel" required autofocus> </div> - <div class="input-group mb-3 passwordgroup"> - <input :type="isPasswordVisible" v-model="password" - id="inputPassword" class="form-control" - :placeholder='passwordLabel' - :required='!showPasswordReset' :disabled='showPasswordReset'> + <div class="input-group mb-3"> + <input :type="isPasswordVisible" v-model="password" id="inputPassword" class="form-control shadow-sm" :placeholder='passwordLabel' :required='!showPasswordReset' :disabled='showPasswordReset'> <div class="input-group-append"> - <span class="input-group-text disabled" id="basic-addon2" - @click="showPassword"><i :class="eyeIcon"></i></span> + <span class="input-group-text disabled" id="basic-addon2" @click="showPassword"> + <i :class="eyeIcon"></i> + </span> </div> </div> - <button class="submitbutton btn btn-primary btn-block" - :disabled="submitted || showPasswordReset" type="submit" - ><translate>Login</translate></button> + <button v-if="showPasswordReset==false" class="btn btn-primary btn-block shadow-sm" :disabled="submitted || showPasswordReset" type="submit"> + <translate>Login</translate> + </button> </form> - </div> - <!-- password forgotten part --> - <div class="d-flex flex-row justify-content-center"> - <form class="loginform form-signin"> + <!-- password forgotten part --> + <form class=""> <div v-if="showPasswordReset" class="passwordreset"> - <!-- - TODO text and action for password reset - <div class="input-group mb-3 usernamegroup"> - <input type="text" v-model="usernameToReset" class="form-control" :placeholder="usernameLabel" required> + <button class="btn btn-block btn-info" type="button" @click="resetPassword"> + <translate>Request password reset!</translate> + </button> + <div class="pull-right"> + <a href="#" @click.prevent="togglePasswordReset"> + <translate>back to login</translate> + </a> </div> - --> - <button class="btn btn-warning btn-block" type="button" - @click="resetPassword" - ><translate>Request password reset!</translate></button> - <div class="forgottenlink small"> - <a href="#" @click.prevent="togglePasswordReset" - ><translate>back to login</translate></a></div> + </div> + <div v-else class="pull-right"> + <a href="#" @click.prevent="togglePasswordReset"> + <translate>Forgot password</translate> + </a> </div> - <div v-else class="forgottenlink small"> - <a href="#" @click.prevent="togglePasswordReset" - ><translate>Forgot password</translate></a></div> </form> + + <!-- bottom logo section --> + <div><img :src="secondaryLogo"></div> </div> - - <!-- bottom logo section --> - <div class="secondary-logo d-flex flex-row justify-content-center" - ><img :src="secondaryLogo"></div> </div> </template>) <style lang="scss"> @import "../assets/application.scss"; -$logincollapsed: 470px; -$loginextended: 550px; - -.usernamegroup { - box-shadow: $basic-shadow-light !important; -} -.forgottenlink { - text-align: right; - margin-top: $small-offset; - margin-bottom: $small-offset; -} -#inputPassword { - border-right: none; -} -.input-group-text { - background-color: white !important; -} .login { - width: 375px; + background-color: white; + min-width: 375px; + height: 500px; @extend %fully-centered; - padding-top: $offset; - padding-bottom: $offset; - box-shadow: $basic-shadow; -} -.logincollapsed { - height: $logincollapsed; } -.loginextended { - height: $loginextended; -} -.loginerror { - white-space: pre; -} -.loginerrormessage { - box-shadow: $basic-shadow-light !important; -} -.loginform { - width: 300px; -} -.logogroup { - margin-top: $offset; - margin-bottom: $offset; +.loginmask { + margin-left: $large-offset; + margin-right: $large-offset; + margin-top: $large-offset; } -.passwordreset { - margin-top: $offset; - margin-bottom: $offset; -} -.mail-icon { - width: $iconwidth; -} -.passwordgroup { - box-shadow: $basic-shadow-light !important; + +.logo { + margin-right: $offset; } -.password-icon { - position: relative; - top: 10px; - font-size: $iconsize; - line-height: $iconLineHeight; - width: $iconwidth; -} -.submitbutton { - box-shadow: $basic-shadow-light !important; -} -.title { - margin-left: $offset; + +.alert { + padding: 0.5rem; } </style> @@ -155,6 +98,12 @@ }; }, computed: { + errorMessage() { + if (this.loginFailed) return this.$gettext("Login failed"); + if (this.passwordJustResetted) + return this.$gettext("Password reset requested!"); + return "&npsp;"; + }, passwordLabel() { return this.$gettext("Enter passphrase"); }, @@ -171,14 +120,25 @@ "fa-eye-slash": this.readablePassword }; }, - loginStyle() { - return { - login: true, - logincollapsed: !this.loginFailed, - loginextended: this.loginFailed, - "bg-white": true, - rounded: true + errorMessageStyle() { + if (this.loginFailed || this.passwordJustResetted) { + return "visibility:visible"; + } + return "visibility:hidden"; + }, + errorMessageClass() { + let result = { + "mb-3": true, + errormessage: true, + alert: true }; + if (this.loginFailed) { + result["alert-danger"] = true; + } + if (this.passwordJustResetted) { + result["alert-info"] = true; + } + return result; }, ...mapGetters("application", ["appTitle", "secondaryLogo"]) }, @@ -207,6 +167,7 @@ togglePasswordReset() { this.passwordJustResetted = false; this.showPasswordReset = !this.showPasswordReset; + this.loginFailed = false; }, resetPassword() { if (this.user) {