comparison client/src/components/Userdetail.vue @ 389:e7d5383bc358

feat: Primitive validation and error messages Added simple error messages to the usermanagement Added simple validation rules for fields: * password rules according issue70 * email used the regex from gocode
author Thomas Junk <thomas.junk@intevation.de>
date Mon, 13 Aug 2018 16:21:26 +0200
parents 0a9aaf21f69f
children c57b952c60be
comparison
equal deleted inserted replaced
384:af82a8989b44 389:e7d5383bc358
1 <template> 1 <template>
2 <div class="userdetails shadow"> 2 <div class="userdetails shadow">
3 <div class="card"> 3 <div class="card">
4 <div class="card-header text-white bg-info mb-3"> 4 <div class="card-header text-white bg-info mb-3">
5 {{ currentUser.user }} 5 {{ currentUser.user }}
6 <span @click="closeDetailview" class="pull-right"><i class="fa fa-close"></i></span>
6 </div> 7 </div>
7 <div class="card-body"> 8 <div class="card-body">
8 <form @submit.prevent="save"> 9 <form @submit.prevent="save">
9 <div class="form-group row"> 10 <div class="formfields">
10 <label for="country">Country</label> 11 <div v-if="currentUser.isNew" class="form-group row">
11 <select class="form-control form-control-sm" v-model="currentUser.country"> 12 <label for="user">Username</label>
12 <option disabled value="">Please select one</option> 13 <input type="user" class="form-control form-control-sm" id="user" aria-describedby="userHelp" v-model="currentUser.user">
13 <option>AT</option> 14 <div v-show="errors.email" class="text-danger"><small><i class="fa fa-warning"></i> {{ errors.email }}</small></div>
14 <option>RO</option> 15 </div>
15 <option>BG</option> 16 <div class="form-group row">
16 </select> 17 <label for="country">Country</label>
18 <select class="form-control form-control-sm" v-on:change="validateCountry" v-model="currentUser.country">
19 <option disabled value="">Please select one</option>
20 <option>AT</option>
21 <option>RO</option>
22 <option>BG</option>
23 </select>
24 <div v-show="errors.country" class="text-danger"><small><i class="fa fa-warning"></i> {{ errors.country }}</small></div>
25 </div>
26 <div class="form-group row">
27 <label for="email">Email address</label>
28 <input type="email" v-on:change="validateEmailaddress" class="form-control form-control-sm" id="email" aria-describedby="emailHelp" v-model="currentUser.email">
29 <div v-show="errors.email" class="text-danger"><small><i class="fa fa-warning"></i> {{ errors.email }}</small></div>
30 </div>
31 <div class="form-group row">
32 <label for="role">Role</label>
33 <select class="form-control form-control-sm" v-model="currentUser.role">
34 <option disabled value="">Please select one</option>
35 <option value="sys_admin">Sysadmin</option>
36 <option value="waterway_admin">Waterway Admin</option>
37 <option value="waterway_user">Waterway User</option>
38 </select>
39 </div>
40 <div class="form-group row">
41 <label for="password">Password</label>
42 <input type="password" v-on:change="validatePassword" class="form-control form-control-sm" id="password" aria-describedby="passwordHelp" v-model="password">
43 <div v-show="errors.password" class="text-danger"><small><i class="fa fa-warning"></i> {{ errors.password }}</small></div>
44 </div>
45 <div class="form-group row">
46 <label for="passwordre">Retype Password</label>
47 <input type="password" v-on:change="validatePassword" class="form-control form-control-sm" id="passwordre" aria-describedby="passwordreHelp" v-model="passwordre">
48 <div v-show="errors.passwordre" class="text-danger"><small><i class="fa fa-warning"></i> {{ errors.passwordre }}</small></div>
49 </div>
17 </div> 50 </div>
18 <div class="form-group row"> 51 <div>
19 <label for="email">Email address</label> 52 <button type="submit" :disabled="submitted" class="btn btn-info pull-right">Submit</button>
20 <input type="email" class="form-control form-control-sm" id="email" aria-describedby="emailHelp" v-model="currentUser.email">
21 </div> 53 </div>
22 <div class="form-group row">
23 <label for="role">Role</label>
24 <select class="form-control form-control-sm" v-model="currentUser.role">
25 <option disabled value="">Please select one</option>
26 <option value="sys_admin">Sysadmin</option>
27 <option value="waterway_admin">Waterway Admin</option>
28 <option value="waterway_user">Waterway User</option>
29 </select>
30 </div>
31 <button type="submit" class="btn btn-primary pull-right">Submit</button>
32 </form> 54 </form>
33 </div> 55 </div>
34 </div> 56 </div>
35 </div> 57 </div>
36 </template> 58 </template>
37 59
38 <style lang="scss"> 60 <style lang="scss">
39 @import "../assets/application.scss"; 61 @import "../assets/application.scss";
40 62
63 .formfields {
64 width: 10vw;
65 }
66
41 .userdetails { 67 .userdetails {
42 margin-top: $large-offset; 68 margin-top: $large-offset;
43 width: 30vw; 69 width: 53vw;
44 margin-right: auto; 70 margin-right: auto;
45 height: 100%; 71 height: 100%;
46 } 72 }
47 73
48 form { 74 form {
49 width: 20vw; 75 margin-left: $offset;
50 margin: auto; 76 font-size: 0.9rem;
51 } 77 }
52 78
53 .shadow { 79 .shadow {
54 box-shadow: $basic-shadow-light !important; 80 box-shadow: $basic-shadow-light !important;
55 } 81 }
59 85
60 export default { 86 export default {
61 name: "userdetail", 87 name: "userdetail",
62 data() { 88 data() {
63 return { 89 return {
90 password: "",
91 passwordre: "",
64 currentUser: {}, 92 currentUser: {},
65 path: null 93 path: null,
94 submitted: false,
95 errors: {
96 email: "",
97 country: "",
98 password: "",
99 passwordre: ""
100 }
66 }; 101 };
67 }, 102 },
68 mounted() { 103 mounted() {
69 this.currentUser = { ...this.user }; 104 this.currentUser = { ...this.user };
70 this.path = this.user.name; 105 this.path = this.user.name;
76 } 111 }
77 }, 112 },
78 computed: { 113 computed: {
79 user() { 114 user() {
80 return this.$store.getters["usermanagement/currentUser"]; 115 return this.$store.getters["usermanagement/currentUser"];
116 },
117 validationErrors() {
118 const errorMessages = this.errors;
119 return (
120 errorMessages.email ||
121 errorMessages.country ||
122 errorMessages.password ||
123 errorMessages.passwordre
124 );
81 } 125 }
82 }, 126 },
83 methods: { 127 methods: {
128 closeDetailview() {
129 this.$store.commit("usermanagement/clearCurrentUser");
130 this.$store.commit("usermanagement/setUserDetailsInvisible");
131 },
132 validateCountry(event) {
133 if (event.target.value !== "") {
134 this.errors.country = "";
135 } else {
136 this.errors.country = "Please choose a valid country";
137 }
138 },
139 validatePassword() {
140 if (this.password !== this.passwordre) {
141 this.errors.passwordre = "Passwords do not match!";
142 } else {
143 this.errors.passwordre = "";
144 }
145 if (
146 // rules according to issue 70
147 this.password.length < 8 ||
148 /\W/.test(this.password) == false ||
149 /\d/.test(this.password) == false
150 ) {
151 this.errors.password =
152 "Password should at least be 8 char long including 1 digit and 1 special char like $";
153 } else {
154 this.errors.password = "";
155 }
156 },
157 validateEmailaddress(event) {
158 if (
159 /* cf. types.go */
160 // eslint-disable-next-line
161 /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/.test(
162 event.target.value
163 )
164 ) {
165 this.errors.email = "";
166 } else {
167 this.errors.email = "invalid email";
168 }
169 },
84 save() { 170 save() {
171 if (this.validationErrors) return;
172 if (this.password) this.currentUser.password = this.password;
173 this.submitted = true;
85 this.$store 174 this.$store
86 .dispatch("usermanagement/saveCurrentUser", { 175 .dispatch("usermanagement/saveCurrentUser", {
87 path: this.user.user, 176 path: this.user.user,
88 user: this.currentUser 177 user: this.currentUser
89 }) 178 })
90 .then(() => { 179 .then(() => {
91 this.$store.commit("usermanagement/clearCurrentUser"); 180 this.submitted = false;
92 this.$store.dispatch("usermanagement/loadUsers").catch(error => { 181 this.$store.dispatch("usermanagement/loadUsers").catch(error => {
93 const { status, data } = error.response; 182 const { status, data } = error.response;
94 app.$toast.error({ 183 app.$toast.error({
95 title: "Backend Error", 184 title: "Backend Error",
96 message: `${status}: ${data}` 185 message: `${status}: ${data}`
97 }); 186 });
98 }); 187 });
99 }) 188 })
100 .catch(error => { 189 .catch(error => {
190 this.submitted = false;
101 const { status, data } = error.response; 191 const { status, data } = error.response;
102 app.$toast.error({ 192 app.$toast.error({
103 title: "Error while saving user", 193 title: "Error while saving user",
104 message: `${status}: ${data}` 194 message: `${status}: ${data}`
105 }); 195 });