| <template> | 
 |   <b-modal id="modal-user" ref="modal" @ok="onOk" @hidden="resetForm"> | 
 |     <template v-slot:modal-title> | 
 |       <template v-if="newUser"> | 
 |         Add user | 
 |       </template> | 
 |       <template v-else> | 
 |         Edit user | 
 |       </template> | 
 |     </template> | 
 |     <b-form novalidate @submit="handleSubmit"> | 
 |       <b-container> | 
 |         <b-row> | 
 |           <b-col> | 
 |             <b-form-group label="Account status"> | 
 |               <b-form-radio | 
 |                 v-model="form.status" | 
 |                 name="user-status" | 
 |                 :value="true" | 
 |                 @input="$v.form.status.$touch()" | 
 |               > | 
 |                 Enabled | 
 |               </b-form-radio> | 
 |               <b-form-radio | 
 |                 v-model="form.status" | 
 |                 name="user-status" | 
 |                 :value="false" | 
 |                 @input="$v.form.status.$touch()" | 
 |               > | 
 |                 Disabled | 
 |               </b-form-radio> | 
 |             </b-form-group> | 
 |             <b-form-group label="Username" label-for="username"> | 
 |               <b-form-text id="username-help-block"> | 
 |                 Cannot start with a number | 
 |                 <br /> | 
 |                 No special characters except underscore | 
 |               </b-form-text> | 
 |               <b-form-input | 
 |                 id="username" | 
 |                 v-model="form.username" | 
 |                 type="text" | 
 |                 aria-describedby="username-help-block" | 
 |                 :state="getValidationState($v.form.username)" | 
 |                 :disabled="!newUser && originalUsername === 'root'" | 
 |                 @input="$v.form.username.$touch()" | 
 |               /> | 
 |               <b-form-invalid-feedback role="alert"> | 
 |                 <template v-if="!$v.form.username.required"> | 
 |                   Field required | 
 |                 </template> | 
 |                 <template v-else-if="!$v.form.username.maxLength"> | 
 |                   Length must be between 1 – 16 characters | 
 |                 </template> | 
 |                 <template v-else-if="!$v.form.username.pattern"> | 
 |                   Invalid format | 
 |                 </template> | 
 |               </b-form-invalid-feedback> | 
 |             </b-form-group> | 
 |             <b-form-group label="Privilege"> | 
 |               <b-form-select | 
 |                 v-model="form.privilege" | 
 |                 :options="privilegeTypes" | 
 |                 :state="getValidationState($v.form.privilege)" | 
 |                 @input="$v.form.privilege.$touch()" | 
 |               > | 
 |               </b-form-select> | 
 |               <b-form-invalid-feedback role="alert"> | 
 |                 <template v-if="!$v.form.privilege.required"> | 
 |                   Field required | 
 |                 </template> | 
 |               </b-form-invalid-feedback> | 
 |             </b-form-group> | 
 |           </b-col> | 
 |           <b-col> | 
 |             <b-form-group label="User password" label-for="password"> | 
 |               <b-form-text id="password-help-block"> | 
 |                 Password must between | 
 |                 <span class="text-nowrap"> | 
 |                   {{ passwordRequirements.minLength }} | 
 |                   – {{ passwordRequirements.maxLength }} | 
 |                 </span> | 
 |                 characters | 
 |               </b-form-text> | 
 |               <input-password-toggle> | 
 |                 <b-form-input | 
 |                   id="password" | 
 |                   v-model="form.password" | 
 |                   type="password" | 
 |                   aria-describedby="password-help-block" | 
 |                   :state="getValidationState($v.form.password)" | 
 |                   @input="$v.form.password.$touch()" | 
 |                 /> | 
 |                 <b-form-invalid-feedback role="alert"> | 
 |                   <template v-if="!$v.form.password.required"> | 
 |                     Field required | 
 |                   </template> | 
 |                   <template | 
 |                     v-if=" | 
 |                       !$v.form.password.minLength || !$v.form.password.maxLength | 
 |                     " | 
 |                   > | 
 |                     Length must be between | 
 |                     <span class="text-nowrap"> | 
 |                       {{ passwordRequirements.minLength }} | 
 |                       – {{ passwordRequirements.maxLength }} | 
 |                     </span> | 
 |                     characters | 
 |                   </template> | 
 |                 </b-form-invalid-feedback> | 
 |               </input-password-toggle> | 
 |             </b-form-group> | 
 |             <b-form-group | 
 |               label="Confirm user password" | 
 |               label-for="password-confirmation" | 
 |             > | 
 |               <input-password-toggle> | 
 |                 <b-form-input | 
 |                   id="password-confirmation" | 
 |                   v-model="form.passwordConfirmation" | 
 |                   type="password" | 
 |                   :state="getValidationState($v.form.passwordConfirmation)" | 
 |                   @input="$v.form.passwordConfirmation.$touch()" | 
 |                 /> | 
 |                 <b-form-invalid-feedback role="alert"> | 
 |                   <template v-if="!$v.form.passwordConfirmation.required"> | 
 |                     Field required | 
 |                   </template> | 
 |                   <template | 
 |                     v-else-if="!$v.form.passwordConfirmation.sameAsPassword" | 
 |                   > | 
 |                     Passwords do not match | 
 |                   </template> | 
 |                 </b-form-invalid-feedback> | 
 |               </input-password-toggle> | 
 |             </b-form-group> | 
 |           </b-col> | 
 |         </b-row> | 
 |       </b-container> | 
 |     </b-form> | 
 |     <template v-slot:modal-ok> | 
 |       <template v-if="newUser"> | 
 |         Add user | 
 |       </template> | 
 |       <template v-else> | 
 |         Save | 
 |       </template> | 
 |     </template> | 
 |   </b-modal> | 
 | </template> | 
 |  | 
 | <script> | 
 | import { | 
 |   required, | 
 |   maxLength, | 
 |   minLength, | 
 |   sameAs, | 
 |   helpers, | 
 |   requiredIf | 
 | } from 'vuelidate/lib/validators'; | 
 | import VuelidateMixin from '../../../components/Mixins/VuelidateMixin.js'; | 
 | import InputPasswordToggle from '../../../components/Global/InputPasswordToggle'; | 
 |  | 
 | export default { | 
 |   components: { InputPasswordToggle }, | 
 |   mixins: [VuelidateMixin], | 
 |   props: { | 
 |     user: { | 
 |       type: Object, | 
 |       default: null | 
 |     }, | 
 |     passwordRequirements: { | 
 |       type: Object, | 
 |       required: true | 
 |     } | 
 |   }, | 
 |   data() { | 
 |     return { | 
 |       privilegeTypes: ['Administrator', 'Operator', 'ReadOnly', 'NoAccess'], | 
 |       originalUsername: '', | 
 |       form: { | 
 |         status: true, | 
 |         username: '', | 
 |         privilege: '', | 
 |         password: '', | 
 |         passwordConfirmation: '' | 
 |       } | 
 |     }; | 
 |   }, | 
 |   computed: { | 
 |     newUser() { | 
 |       return this.user ? false : true; | 
 |     } | 
 |   }, | 
 |   watch: { | 
 |     user: function(value) { | 
 |       if (value === null) return; | 
 |       this.originalUsername = value.username; | 
 |       this.form.username = value.username; | 
 |       this.form.status = value.Enabled; | 
 |       this.form.privilege = value.privilege; | 
 |     } | 
 |   }, | 
 |   validations() { | 
 |     return { | 
 |       form: { | 
 |         status: { | 
 |           required | 
 |         }, | 
 |         username: { | 
 |           required, | 
 |           maxLength: maxLength(16), | 
 |           pattern: helpers.regex('pattern', /^([a-zA-Z_][a-zA-Z0-9_]*)/) | 
 |         }, | 
 |         privilege: { | 
 |           required | 
 |         }, | 
 |         password: { | 
 |           required: requiredIf(function() { | 
 |             return this.requirePassword(); | 
 |           }), | 
 |           minLength: minLength(this.passwordRequirements.minLength), | 
 |           maxLength: maxLength(this.passwordRequirements.maxLength) | 
 |         }, | 
 |         passwordConfirmation: { | 
 |           required: requiredIf(function() { | 
 |             return this.requirePassword(); | 
 |           }), | 
 |           sameAsPassword: sameAs('password') | 
 |         } | 
 |       } | 
 |     }; | 
 |   }, | 
 |   methods: { | 
 |     handleSubmit() { | 
 |       let userData = {}; | 
 |  | 
 |       if (this.newUser) { | 
 |         this.$v.$touch(); | 
 |         if (this.$v.$invalid) return; | 
 |         userData.username = this.form.username; | 
 |         userData.status = this.form.status; | 
 |         userData.privilege = this.form.privilege; | 
 |         userData.password = this.form.password; | 
 |       } else { | 
 |         if (this.$v.$invalid) return; | 
 |         userData.originalUsername = this.originalUsername; | 
 |         if (this.$v.form.status.$dirty) { | 
 |           userData.status = this.form.status; | 
 |         } | 
 |         if (this.$v.form.username.$dirty) { | 
 |           userData.username = this.form.username; | 
 |         } | 
 |         if (this.$v.form.privilege.$dirty) { | 
 |           userData.privilege = this.form.privilege; | 
 |         } | 
 |         if (this.$v.form.password.$dirty) { | 
 |           userData.password = this.form.password; | 
 |         } | 
 |         if (Object.entries(userData).length === 1) { | 
 |           this.closeModal(); | 
 |           return; | 
 |         } | 
 |       } | 
 |  | 
 |       this.$emit('ok', { isNewUser: this.newUser, userData }); | 
 |       this.closeModal(); | 
 |     }, | 
 |     closeModal() { | 
 |       this.$nextTick(() => { | 
 |         this.$refs.modal.hide(); | 
 |       }); | 
 |     }, | 
 |     resetForm() { | 
 |       this.form.originalUsername = ''; | 
 |       this.form.status = true; | 
 |       this.form.username = ''; | 
 |       this.form.privilege = ''; | 
 |       this.form.password = ''; | 
 |       this.form.passwordConfirmation = ''; | 
 |       this.$v.$reset(); | 
 |     }, | 
 |     requirePassword() { | 
 |       if (this.newUser) return true; | 
 |       if (this.$v.form.password.$dirty) return true; | 
 |       if (this.$v.form.passwordConfirmation.$dirty) return true; | 
 |       return false; | 
 |     }, | 
 |     onOk(bvModalEvt) { | 
 |       // prevent modal close | 
 |       bvModalEvt.preventDefault(); | 
 |       this.handleSubmit(); | 
 |     } | 
 |   } | 
 | }; | 
 | </script> |