blob: 59e5706275b9dd128a7a7730563ff12846bfcc12 [file] [log] [blame]
Yoshie Muranaka463a5702019-12-04 09:09:36 -08001<template>
Yoshie Muranaka5fa09a22020-01-06 07:36:16 -08002 <b-modal id="modal-user" ref="modal" @ok="onOk" @hidden="resetForm">
Yoshie Muranaka463a5702019-12-04 09:09:36 -08003 <template v-slot:modal-title>
4 <template v-if="newUser">
5 Add user
6 </template>
7 <template v-else>
8 Edit user
9 </template>
10 </template>
Yoshie Muranaka5fa09a22020-01-06 07:36:16 -080011 <b-form novalidate @submit="handleSubmit">
12 <b-container>
13 <b-row>
14 <b-col>
15 <b-form-group label="Account status">
16 <b-form-radio
17 v-model="form.status"
18 name="user-status"
19 :value="true"
20 @input="$v.form.status.$touch()"
21 >
22 Enabled
23 </b-form-radio>
24 <b-form-radio
25 v-model="form.status"
26 name="user-status"
27 :value="false"
28 @input="$v.form.status.$touch()"
29 >
30 Disabled
31 </b-form-radio>
32 </b-form-group>
33 <b-form-group label-for="Username">
34 <b-form-text id="username-help-block">
35 Cannot start with a number
36 <br />
37 No special characters except underscore
38 </b-form-text>
39 <b-form-input
40 v-model="form.username"
41 type="text"
42 aria-describedby="username-help-block"
43 :state="getValidationState('username')"
44 :disabled="!newUser && originalUsername === 'root'"
45 />
46 <b-form-invalid-feedback role="alert">
47 <template v-if="!$v.form.username.required">
48 Field required
49 </template>
50 <template v-else-if="!$v.form.username.maxLength">
51 Length must be between 1 – 16 characters
52 </template>
53 <template v-else-if="!$v.form.username.pattern">
54 Invalid format
55 </template>
56 </b-form-invalid-feedback>
57 </b-form-group>
58 <b-form-group label-for="Privilege">
59 <b-form-select
60 v-model="form.privilege"
61 required
62 :options="privilegeTypes"
63 :state="getValidationState('privilege')"
64 @input="$v.form.privilege.$touch()"
65 >
66 </b-form-select>
67 <b-form-invalid-feedback role="alert">
68 <template v-if="!$v.form.privilege.required">
69 Field required
70 </template>
71 </b-form-invalid-feedback>
72 </b-form-group>
73 </b-col>
74 <b-col>
75 <b-form-group label-for="User password">
76 <b-form-text id="password-help-block" text-variant="black">
77 <!-- TODO: Should be dynamic values -->
78 Password must between 8 – 20 characters
79 </b-form-text>
80 <b-form-input
81 v-model="form.password"
82 type="password"
83 aria-describedby="password-help-block"
84 :state="getValidationState('password')"
85 @input="$v.form.password.$touch()"
86 />
87 <b-form-invalid-feedback role="alert">
88 <template v-if="!$v.form.password.required">
89 Field required
90 </template>
91 <template
92 v-if="
93 !$v.form.password.minLength || !$v.form.password.maxLength
94 "
95 >
96 Length must be between 8 – 20 characters
97 </template>
98 </b-form-invalid-feedback>
99 </b-form-group>
100 <b-form-group label-for="Confirm user password">
101 <b-form-input
102 v-model="form.passwordConfirmation"
103 type="password"
104 :state="getValidationState('passwordConfirmation')"
105 @input="$v.form.passwordConfirmation.$touch()"
106 />
107 <b-form-invalid-feedback role="alert">
108 <template v-if="!$v.form.passwordConfirmation.required">
109 Field required
110 </template>
111 <template
112 v-else-if="!$v.form.passwordConfirmation.sameAsPassword"
113 >
114 Passwords do not match
115 </template>
116 </b-form-invalid-feedback>
117 </b-form-group>
118 </b-col>
119 </b-row>
120 </b-container>
Yoshie Muranaka463a5702019-12-04 09:09:36 -0800121 </b-form>
122 <template v-slot:modal-ok>
123 <template v-if="newUser">
124 Add user
125 </template>
126 <template v-else>
127 Save
128 </template>
129 </template>
130 </b-modal>
131</template>
132
133<script>
Yoshie Muranaka5fa09a22020-01-06 07:36:16 -0800134import {
135 required,
136 maxLength,
137 minLength,
138 sameAs,
139 helpers,
140 requiredIf
141} from 'vuelidate/lib/validators';
142
Yoshie Muranaka463a5702019-12-04 09:09:36 -0800143export default {
Derick Montague5e7ac492020-01-23 15:45:57 -0600144 props: {
145 user: {
146 type: Object,
147 default: null
148 }
149 },
Yoshie Muranaka463a5702019-12-04 09:09:36 -0800150 data() {
151 return {
Yoshie Muranaka5fa09a22020-01-06 07:36:16 -0800152 privilegeTypes: ['Administrator', 'Operator', 'ReadOnly', 'NoAccess'],
153 originalUsername: '',
154 form: {
155 status: true,
156 username: '',
157 privilege: '',
158 password: '',
159 passwordConfirmation: ''
160 }
Yoshie Muranaka463a5702019-12-04 09:09:36 -0800161 };
162 },
163 computed: {
164 newUser() {
165 return this.user ? false : true;
Yoshie Muranaka5fa09a22020-01-06 07:36:16 -0800166 }
167 },
168 watch: {
169 user: function(value) {
170 if (value === null) return;
171 this.originalUsername = value.username;
172 this.form.username = value.username;
173 this.form.status = value.Enabled;
174 this.form.privilege = value.privilege;
175 }
176 },
177 validations: {
178 form: {
179 status: {
180 required
181 },
182 username: {
183 required,
184 maxLength: maxLength(16),
185 pattern: helpers.regex('pattern', /^([a-zA-Z_][a-zA-Z0-9_]*)/)
186 },
187 privilege: {
188 required
189 },
190 password: {
191 required: requiredIf(function() {
192 return this.requirePassword();
193 }),
194 minLength: minLength(8),
195 maxLength: maxLength(20)
196 },
197 passwordConfirmation: {
198 required: requiredIf(function() {
199 return this.requirePassword();
200 }),
201 sameAsPassword: sameAs('password')
202 }
203 }
204 },
205 methods: {
206 handleSubmit() {
207 let userData = {};
208
209 if (this.newUser) {
210 this.$v.$touch();
211 if (this.$v.$invalid) return;
212 userData.username = this.form.username;
213 userData.status = this.form.status;
214 userData.privilege = this.form.privilege;
215 userData.password = this.form.password;
216 } else {
217 if (this.$v.$invalid) return;
218 userData.originalUsername = this.originalUsername;
219 if (this.$v.form.status.$dirty) {
220 userData.status = this.form.status;
221 }
222 if (this.$v.form.username.$dirty) {
223 userData.username = this.form.username;
224 }
225 if (this.$v.form.privilege.$dirty) {
226 userData.privilege = this.form.privilege;
227 }
228 if (this.$v.form.password.$dirty) {
229 userData.password = this.form.password;
230 }
231 if (Object.entries(userData).length === 1) {
232 this.closeModal();
233 return;
234 }
235 }
236
237 this.$emit('ok', { isNewUser: this.newUser, userData });
238 this.closeModal();
Yoshie Muranaka463a5702019-12-04 09:09:36 -0800239 },
Yoshie Muranaka5fa09a22020-01-06 07:36:16 -0800240 closeModal() {
241 this.$nextTick(() => {
242 this.$refs.modal.hide();
243 });
244 },
245 resetForm() {
246 this.form.originalUsername = '';
247 this.form.status = true;
248 this.form.username = '';
249 this.form.privilege = '';
250 this.form.password = '';
251 this.form.passwordConfirmation = '';
252 this.$v.$reset();
253 },
254 getValidationState(name) {
255 const { $dirty, $error } = this.$v.form[name];
256 return $dirty ? !$error : null;
257 },
258 requirePassword() {
259 if (this.newUser) return true;
260 if (this.$v.form.password.$dirty) return true;
261 if (this.$v.form.passwordConfirmation.$dirty) return true;
262 return false;
263 },
264 onOk(bvModalEvt) {
265 // prevent modal close
266 bvModalEvt.preventDefault();
267 this.handleSubmit();
Yoshie Muranaka463a5702019-12-04 09:09:36 -0800268 }
269 }
270};
271</script>