Mercurial > gemma
comparison client/src/login/Login.vue @ 585:ef307bd6b5d8
refac: restructured client application
To make the application more accessible for developers, the structure was reorganized.
Instead of sticking to technical terminology, the application terminology is according to the domain:
I.e. "map" contains everything regarding map (including store).
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Fri, 07 Sep 2018 11:13:56 +0200 |
parents | |
children | 51dc26b0f066 |
comparison
equal
deleted
inserted
replaced
584:8b66a10aaf8a | 585:ef307bd6b5d8 |
---|---|
1 (<template> | |
2 <div class="d-flex flex-column login shadow-lg"> | |
3 <div class="loginmask"> | |
4 <!-- logo section --> | |
5 <div class="d-flex flex-row justify-content-center mb-3"> | |
6 <div class="logo"><img src="../application/assets/logo.png"></div> | |
7 <div class="title"> | |
8 <h1>{{ appTitle }}</h1> | |
9 </div> | |
10 </div> | |
11 <!-- end logo section --> | |
12 <form class="loginform" @submit.prevent="login"> | |
13 <div id="alert" :style="errorMessageStyle" :class="errorMessageClass" role="alert"> | |
14 <span>{{ errorMessage }}</span> | |
15 </div> | |
16 <div class="input-group mb-3"> | |
17 <input type="text" v-model="user" id="inputUsername" class="form-control shadow-sm" :placeholder="usernameLabel" required autofocus> | |
18 </div> | |
19 <div class="input-group mb-3"> | |
20 <input :type="isPasswordVisible" v-model="password" id="inputPassword" class="form-control shadow-sm" :placeholder='passwordLabel' :required='!showPasswordReset' :disabled='showPasswordReset'> | |
21 <div class="input-group-append"> | |
22 <span class="input-group-text disabled" id="basic-addon2" @click="showPassword"> | |
23 <i :class="eyeIcon"></i> | |
24 </span> | |
25 </div> | |
26 </div> | |
27 <button v-if="showPasswordReset==false" class="btn btn-primary btn-block shadow-sm" :disabled="submitted || showPasswordReset" type="submit"> | |
28 <translate>Login</translate> | |
29 </button> | |
30 <div v-if="showPasswordReset" class="passwordreset"> | |
31 <button class="btn btn-block btn-info" type="button" @click="resetPassword"> | |
32 <translate>Request password reset!</translate> | |
33 </button> | |
34 <div class="pull-right"> | |
35 <a href="#" @click.prevent="togglePasswordReset"> | |
36 <translate>back to login</translate> | |
37 </a> | |
38 </div> | |
39 </div> | |
40 <div v-else class="pull-right"> | |
41 <a href="#" @click.prevent="togglePasswordReset"> | |
42 <translate>Forgot password</translate> | |
43 </a> | |
44 </div> | |
45 </form> | |
46 | |
47 <!-- bottom logo section --> | |
48 <div class="mb-3 secondary-logo"><img :src="secondaryLogo"></div> | |
49 </div> | |
50 </div> | |
51 </template>) | |
52 | |
53 <style lang="scss"> | |
54 @import "../application/assets/application.scss"; | |
55 | |
56 .login { | |
57 background-color: white; | |
58 min-width: 375px; | |
59 min-height: 500px; | |
60 @extend %fully-centered; | |
61 } | |
62 | |
63 .loginform { | |
64 max-width: 375px; | |
65 margin-left: auto; | |
66 margin-right: auto; | |
67 } | |
68 | |
69 .loginmask { | |
70 margin-left: $large-offset; | |
71 margin-right: $large-offset; | |
72 margin-top: $large-offset; | |
73 } | |
74 | |
75 .logo { | |
76 margin-right: $offset; | |
77 } | |
78 | |
79 .alert { | |
80 padding: 0.5rem; | |
81 } | |
82 | |
83 .secondary-logo { | |
84 max-width: 375px; | |
85 margin-left: auto; | |
86 margin-right: auto; | |
87 margin-bottom: auto; | |
88 } | |
89 </style> | |
90 | |
91 <script> | |
92 import { mapGetters } from "vuex"; | |
93 import { HTTP } from "../application/lib/http.js"; | |
94 import { displayError } from "../application/lib/errors.js"; | |
95 | |
96 export default { | |
97 name: "login", | |
98 data() { | |
99 return { | |
100 user: "", | |
101 password: "", | |
102 submitted: false, | |
103 loginFailed: false, | |
104 passwordJustResetted: false, | |
105 readablePassword: false, | |
106 showPasswordReset: false, | |
107 usernameToReset: "" | |
108 }; | |
109 }, | |
110 computed: { | |
111 errorMessage() { | |
112 if (this.loginFailed) return this.$gettext("Login failed"); | |
113 if (this.passwordJustResetted) | |
114 return this.$gettext("Password reset requested!"); | |
115 return "&npsp;"; | |
116 }, | |
117 passwordLabel() { | |
118 return this.$gettext("Enter passphrase"); | |
119 }, | |
120 usernameLabel() { | |
121 return this.$gettext("Enter username"); | |
122 }, | |
123 isPasswordVisible() { | |
124 return this.readablePassword ? "text" : "password"; | |
125 }, | |
126 eyeIcon() { | |
127 return { | |
128 fa: true, | |
129 "fa-eye": !this.readablePassword, | |
130 "fa-eye-slash": this.readablePassword | |
131 }; | |
132 }, | |
133 errorMessageStyle() { | |
134 if (this.loginFailed || this.passwordJustResetted) { | |
135 return "visibility:visible"; | |
136 } | |
137 return "visibility:hidden"; | |
138 }, | |
139 errorMessageClass() { | |
140 let result = { | |
141 "mb-3": true, | |
142 errormessage: true, | |
143 alert: true | |
144 }; | |
145 if (this.loginFailed) { | |
146 result["alert-danger"] = true; | |
147 } | |
148 if (this.passwordJustResetted) { | |
149 result["alert-info"] = true; | |
150 } | |
151 return result; | |
152 }, | |
153 ...mapGetters("application", ["appTitle", "secondaryLogo"]) | |
154 }, | |
155 methods: { | |
156 login() { | |
157 this.submitted = true; | |
158 this.passwordJustResetted = false; | |
159 const { user, password } = this; | |
160 this.$store | |
161 .dispatch("user/login", { user, password }) | |
162 .then(() => { | |
163 this.loginFailed = false; | |
164 this.$router.push("/"); | |
165 }) | |
166 .catch(error => { | |
167 this.loginFailed = true; | |
168 this.submitted = false; | |
169 const { status, data } = error.response; | |
170 displayError({ | |
171 title: "Backend Error", | |
172 message: `${status}: ${data.message || data}` | |
173 }); | |
174 }); | |
175 }, | |
176 showPassword() { | |
177 // disallowing toggle when in reset mode | |
178 if (this.showPasswordReset) return; | |
179 this.readablePassword = !this.readablePassword; | |
180 }, | |
181 togglePasswordReset() { | |
182 this.passwordJustResetted = false; | |
183 this.showPasswordReset = !this.showPasswordReset; | |
184 this.loginFailed = false; | |
185 }, | |
186 resetPassword() { | |
187 if (this.user) { | |
188 HTTP.post("/users/passwordreset", { user: this.user }).catch(error => { | |
189 const { status, data } = error.response; | |
190 displayError({ | |
191 title: "Backend Error", | |
192 message: `${status}: ${data.message || data}` | |
193 }); | |
194 }); | |
195 this.togglePasswordReset(); | |
196 this.passwordJustResetted = true; | |
197 } | |
198 } | |
199 } | |
200 }; | |
201 </script> |