| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | <template> | 
					
						
							|  |  |  |   <v-card :color="color" :dark="dark" flat :width="width" class="my-2"> | 
					
						
							|  |  |  |     <v-row> | 
					
						
							|  |  |  |       <v-col v-for="(inputField, index) in items" :key="index" class="py-0" cols="12" sm="12"> | 
					
						
							|  |  |  |         <v-divider v-if="inputField.section" class="my-2" /> | 
					
						
							|  |  |  |         <v-card-title v-if="inputField.section" class="pl-0"> | 
					
						
							|  |  |  |           {{ inputField.section }} | 
					
						
							|  |  |  |         </v-card-title> | 
					
						
							|  |  |  |         <v-card-text v-if="inputField.sectionDetails" class="pl-0 mt-0 pt-0"> | 
					
						
							|  |  |  |           {{ inputField.sectionDetails }} | 
					
						
							|  |  |  |         </v-card-text> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <!-- Check Box --> | 
					
						
							|  |  |  |         <v-checkbox | 
					
						
							|  |  |  |           v-if="inputField.type === fieldTypes.BOOLEAN" | 
					
						
							|  |  |  |           v-model="value[inputField.varName]" | 
					
						
							|  |  |  |           class="my-0 py-0" | 
					
						
							|  |  |  |           :label="inputField.label" | 
					
						
							|  |  |  |           :name="inputField.varName" | 
					
						
							|  |  |  |           :hint="inputField.hint || ''" | 
					
						
							| 
									
										
										
										
											2021-11-23 18:57:24 -09:00
										 |  |  |           :disabled="updateMode && inputField.disableUpdate" | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |           @change="emitBlur" | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <!-- Text Field --> | 
					
						
							|  |  |  |         <v-text-field | 
					
						
							| 
									
										
										
										
											2021-11-23 18:57:24 -09:00
										 |  |  |           v-else-if="inputField.type === fieldTypes.TEXT || inputField.type === fieldTypes.PASSWORD" | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |           v-model="value[inputField.varName]" | 
					
						
							| 
									
										
										
										
											2021-11-23 18:57:24 -09:00
										 |  |  |           :readonly="inputField.disableUpdate && updateMode" | 
					
						
							|  |  |  |           :disabled="inputField.disableUpdate && updateMode" | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |           filled | 
					
						
							| 
									
										
										
										
											2021-11-23 18:57:24 -09:00
										 |  |  |           :type="inputField.type === fieldTypes.PASSWORD ? 'password' : 'text'" | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |           rounded | 
					
						
							|  |  |  |           class="rounded-lg" | 
					
						
							| 
									
										
										
										
											2021-11-25 14:17:02 -09:00
										 |  |  |           :autofocus="index === 0" | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |           dense | 
					
						
							|  |  |  |           :label="inputField.label" | 
					
						
							|  |  |  |           :name="inputField.varName" | 
					
						
							|  |  |  |           :hint="inputField.hint || ''" | 
					
						
							| 
									
										
										
										
											2021-11-23 18:57:24 -09:00
										 |  |  |           :rules="!(inputField.disableUpdate && updateMode) ? [...rulesByKey(inputField.rules), ...defaultRules] : []" | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |           lazy-validation | 
					
						
							|  |  |  |           @blur="emitBlur" | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <!-- Text Area --> | 
					
						
							|  |  |  |         <v-textarea | 
					
						
							|  |  |  |           v-else-if="inputField.type === fieldTypes.TEXT_AREA" | 
					
						
							|  |  |  |           v-model="value[inputField.varName]" | 
					
						
							| 
									
										
										
										
											2021-11-23 18:57:24 -09:00
										 |  |  |           :readonly="inputField.disableUpdate && updateMode" | 
					
						
							|  |  |  |           :disabled="inputField.disableUpdate && updateMode" | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |           filled | 
					
						
							|  |  |  |           rounded | 
					
						
							|  |  |  |           class="rounded-lg" | 
					
						
							|  |  |  |           rows="3" | 
					
						
							|  |  |  |           auto-grow | 
					
						
							|  |  |  |           dense | 
					
						
							|  |  |  |           :label="inputField.label" | 
					
						
							|  |  |  |           :name="inputField.varName" | 
					
						
							|  |  |  |           :hint="inputField.hint || ''" | 
					
						
							|  |  |  |           :rules="[...rulesByKey(inputField.rules), ...defaultRules]" | 
					
						
							|  |  |  |           lazy-validation | 
					
						
							|  |  |  |           @blur="emitBlur" | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <!-- Option Select --> | 
					
						
							|  |  |  |         <v-select | 
					
						
							|  |  |  |           v-else-if="inputField.type === fieldTypes.SELECT" | 
					
						
							|  |  |  |           v-model="value[inputField.varName]" | 
					
						
							| 
									
										
										
										
											2021-11-23 18:57:24 -09:00
										 |  |  |           :readonly="inputField.disableUpdate && updateMode" | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |           filled | 
					
						
							|  |  |  |           rounded | 
					
						
							|  |  |  |           class="rounded-lg" | 
					
						
							|  |  |  |           :prepend-icon="inputField.icons ? value[inputField.varName] : null" | 
					
						
							|  |  |  |           :label="inputField.label" | 
					
						
							|  |  |  |           :name="inputField.varName" | 
					
						
							|  |  |  |           :items="inputField.options" | 
					
						
							|  |  |  |           :return-object="false" | 
					
						
							|  |  |  |           lazy-validation | 
					
						
							|  |  |  |           @blur="emitBlur" | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           <template #item="{ item }"> | 
					
						
							|  |  |  |             <v-list-item-content> | 
					
						
							|  |  |  |               <v-list-item-title>{{ item.text }}</v-list-item-title> | 
					
						
							|  |  |  |               <v-list-item-subtitle>{{ item.description }}</v-list-item-subtitle> | 
					
						
							|  |  |  |             </v-list-item-content> | 
					
						
							|  |  |  |           </template> | 
					
						
							|  |  |  |         </v-select> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <!-- Color Picker --> | 
					
						
							|  |  |  |         <div v-else-if="inputField.type === fieldTypes.COLOR" class="d-flex" style="width: 100%"> | 
					
						
							|  |  |  |           <v-menu offset-y> | 
					
						
							|  |  |  |             <template #activator="{ on }"> | 
					
						
							|  |  |  |               <v-btn class="my-2 ml-auto" style="min-width: 200px" :color="value[inputField.varName]" dark v-on="on"> | 
					
						
							|  |  |  |                 {{ inputField.label }} | 
					
						
							|  |  |  |               </v-btn> | 
					
						
							|  |  |  |             </template> | 
					
						
							|  |  |  |             <v-color-picker | 
					
						
							|  |  |  |               v-model="value[inputField.varName]" | 
					
						
							|  |  |  |               value="#7417BE" | 
					
						
							|  |  |  |               hide-canvas | 
					
						
							|  |  |  |               hide-inputs | 
					
						
							|  |  |  |               show-swatches | 
					
						
							|  |  |  |               class="mx-auto" | 
					
						
							|  |  |  |               @input="emitBlur" | 
					
						
							|  |  |  |             /> | 
					
						
							|  |  |  |           </v-menu> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <div v-else-if="inputField.type === fieldTypes.OBJECT"> | 
					
						
							|  |  |  |           <auto-form v-model="value[inputField.varName]" :color="color" :items="inputField.items" @blur="emitBlur" /> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <!-- List Type --> | 
					
						
							|  |  |  |         <div v-else-if="inputField.type === fieldTypes.LIST"> | 
					
						
							|  |  |  |           <div v-for="(item, idx) in value[inputField.varName]" :key="idx"> | 
					
						
							|  |  |  |             <p> | 
					
						
							|  |  |  |               {{ inputField.label }} {{ idx + 1 }} | 
					
						
							|  |  |  |               <span> | 
					
						
							|  |  |  |                 <BaseButton class="ml-5" x-small delete @click="removeByIndex(value[inputField.varName], idx)" /> | 
					
						
							|  |  |  |               </span> | 
					
						
							|  |  |  |             </p> | 
					
						
							|  |  |  |             <v-divider class="mb-5 mx-2" /> | 
					
						
							|  |  |  |             <auto-form | 
					
						
							|  |  |  |               v-model="value[inputField.varName][idx]" | 
					
						
							|  |  |  |               :color="color" | 
					
						
							|  |  |  |               :items="inputField.items" | 
					
						
							|  |  |  |               @blur="emitBlur" | 
					
						
							|  |  |  |             /> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |           <v-card-actions> | 
					
						
							|  |  |  |             <v-spacer /> | 
					
						
							|  |  |  |             <BaseButton small @click="value[inputField.varName].push(getTemplate(inputField.items))"> New </BaseButton> | 
					
						
							|  |  |  |           </v-card-actions> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </v-col> | 
					
						
							|  |  |  |     </v-row> | 
					
						
							|  |  |  |   </v-card> | 
					
						
							|  |  |  | </template> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  | <script lang="ts"> | 
					
						
							|  |  |  | import { computed, defineComponent } from "@nuxtjs/composition-api"; | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | import { validators } from "@/composables/use-validators"; | 
					
						
							|  |  |  | import { fieldTypes } from "@/composables/forms"; | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  | import { AutoFormItems } from "~/types/auto-forms"; | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | const BLUR_EVENT = "blur"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  | export default defineComponent({ | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |   name: "AutoForm", | 
					
						
							|  |  |  |   props: { | 
					
						
							|  |  |  |     value: { | 
					
						
							|  |  |  |       default: null, | 
					
						
							|  |  |  |       type: [Object, Array], | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     updateMode: { | 
					
						
							|  |  |  |       default: false, | 
					
						
							|  |  |  |       type: Boolean, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     items: { | 
					
						
							|  |  |  |       default: null, | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |       type: Array as () => AutoFormItems, | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |     }, | 
					
						
							|  |  |  |     width: { | 
					
						
							|  |  |  |       type: [Number, String], | 
					
						
							|  |  |  |       default: "max", | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     globalRules: { | 
					
						
							|  |  |  |       default: null, | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |       type: Array as () => string[], | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |     }, | 
					
						
							|  |  |  |     color: { | 
					
						
							|  |  |  |       default: null, | 
					
						
							|  |  |  |       type: String, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     dark: { | 
					
						
							|  |  |  |       default: false, | 
					
						
							|  |  |  |       type: Boolean, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |   setup(props, context) { | 
					
						
							|  |  |  |     function rulesByKey(keys?: string[] | null) { | 
					
						
							|  |  |  |       if (keys === undefined || keys === null) { | 
					
						
							|  |  |  |         return []; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |       const list = [] as ((v: string) => (boolean | string))[]; | 
					
						
							|  |  |  |       keys.forEach((key) => { | 
					
						
							|  |  |  |         if (key in validators) { | 
					
						
							|  |  |  |           list.push(validators[key]); | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |       }); | 
					
						
							|  |  |  |       return list; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |     const defaultRules = computed(() => rulesByKey(props.globalRules)); | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |     function removeByIndex(list: never[], index: number) { | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |       // Removes the item at the index
 | 
					
						
							|  |  |  |       list.splice(index, 1); | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function getTemplate(item: AutoFormItems) { | 
					
						
							|  |  |  |       const obj = {} as { [key: string]: string }; | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       item.forEach((field) => { | 
					
						
							|  |  |  |         obj[field.varName] = ""; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return obj; | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |     function emitBlur() { | 
					
						
							|  |  |  |       context.emit(BLUR_EVENT, props.value); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  |     return { | 
					
						
							|  |  |  |       rulesByKey, | 
					
						
							|  |  |  |       defaultRules, | 
					
						
							|  |  |  |       removeByIndex, | 
					
						
							|  |  |  |       getTemplate, | 
					
						
							|  |  |  |       emitBlur, | 
					
						
							|  |  |  |       fieldTypes, | 
					
						
							|  |  |  |       validators, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  |   }, | 
					
						
							| 
									
										
										
										
											2022-01-09 07:15:23 +01:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2021-08-01 19:24:47 -08:00
										 |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <style lang="scss" scoped></style> |