<script setup lang="ts"> import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import { computed, watch } from "vue"; import ParameterNumberInput from "@/components/parameter-schema/form-mode/ParameterNumberInput.vue"; import MarkdownRenderer from "@/components/MarkdownRenderer.vue"; import ParameterBooleanInput from "@/components/parameter-schema/form-mode/ParameterBooleanInput.vue"; import ParameterEnumInput from "@/components/parameter-schema/form-mode/ParameterEnumInput.vue"; import ParameterStringInput from "@/components/parameter-schema/form-mode/ParameterStringInput.vue"; const props = defineProps({ parameterGroup: { type: Object, required: true, validator(value: Record<string, never>) { return "object" === value["type"]; }, }, parameterGroupName: { type: String, required: true, }, modelValue: { type: Object, required: true, }, }); const title = computed<string>(() => props.parameterGroup["title"]); const icon = computed<string>(() => props.parameterGroup["fa_icon"]); const description = computed<string>(() => props.parameterGroup["description"]); const groupHidden = computed<boolean>(() => Object.keys(parameters.value).reduce( (acc: boolean, val: string) => acc && parameters.value[val]["hidden"], true ) ); const parameters = computed<Record<string, never>>( () => props.parameterGroup["properties"] ); const formInput = computed(() => props.modelValue); const emit = defineEmits<{ ( e: "update:modelValue", value: Record<string, number | string | boolean | undefined> ): void; }>(); function parameterRequired( // eslint-disable-next-line @typescript-eslint/no-explicit-any parameterGroup: Record<string, any>, parameterName: string ): boolean { return ( parameterGroup["required"]?.includes(parameterName) || // parameter is required parameterGroup["dependentRequired"]?.[parameterName] // parameter is required when another parameter is set ?.map((param: string) => formInput.value[param]) ?.reduce((acc: boolean, val: string) => acc || val, false) ); } watch( formInput, (newVal) => { //console.log("Group", props.parameterGroupName, newVal); emit("update:modelValue", newVal); }, { deep: true, } ); </script> <template> <div class="card bg-dark mb-3" v-if="!groupHidden"> <h2 class="card-header" :id="props.parameterGroupName"> <font-awesome-icon :icon="icon" class="me-2" v-if="icon" /> {{ title }} </h2> <div class="card-body"> <h5 class="card-title" v-if="description">{{ description }}</h5> <template v-for="(parameter, parameterName) in parameters" :key="parameterName" > <template v-if="!parameter['hidden']"> <div class="input-group"> <span class="input-group-text" :id="parameterName + '-help'"> <font-awesome-icon class="me-2 text-dark" :icon="parameter['fa_icon']" v-if="parameter['fa_icon']" /> <code>--{{ parameterName }}</code> </span> <parameter-number-input v-if=" parameter['type'] === 'number' || parameter['type'] === 'integer' " :parameter-name="parameterName" :parameter="parameter" :help-id="parameterName + '-help'" :required="parameterRequired(parameterGroup, parameterName)" :model-value="formInput[parameterName]" @update:model-value=" (newValue) => (formInput[parameterName] = newValue) " /> <parameter-boolean-input v-else-if="parameter['type'] === 'boolean'" :parameter-name="parameterName" :parameter="parameter" :help-id="parameterName + '-help'" :model-value="formInput[parameterName]" @update:model-value=" (newValue) => (formInput[parameterName] = newValue) " /> <template v-else-if="parameter['type'] === 'string'"> <parameter-enum-input v-if="parameter['enum']" :parameter-name="parameterName" :parameter="parameter" :model-value="formInput[parameterName]" :required="parameterRequired(parameterGroup, parameterName)" @update:model-value=" (newValue) => (formInput[parameterName] = newValue) " /> <parameter-string-input v-else :parameter-name="parameterName" :parameter="parameter" :model-value="formInput[parameterName]" :required="parameterRequired(parameterGroup, parameterName)" @update:model-value=" (newValue) => (formInput[parameterName] = newValue) " /> </template> <span class="input-group-text cursor-pointer px-2" v-if="parameter['help_text']" data-bs-toggle="collapse" :data-bs-target="'#helpCollapse' + parameterName" aria-expanded="false" aria-controls="collapseExample" > <font-awesome-icon class="cursor-pointer" icon="fa-solid fa-circle-question" /> </span> </div> <label v-if="parameter['description']" ><markdown-renderer :markdown="parameter['description']" /></label> <div class="collapse p-2 pb-0 bg-dark mx-2 mt-1 flex-shrink-1" :id="'helpCollapse' + parameterName" v-if="parameter['help_text']" > <markdown-renderer class="helpTextCode" :markdown="parameter['help_text']" /> <p v-if="parameter['pattern']"> Pattern: <code>{{ parameter["pattern"] }}</code> </p> </div> </template> </template> </div> </div> </template> <style scoped> div.card-body { backdrop-filter: brightness(1.2); } span.cursor-pointer:hover { color: var(--bs-info); background: var(--bs-light); } </style>