-
Daniel Göbel authored
#95
Daniel Göbel authored#95
ParameterGroupForm.vue 6.86 KiB
<script setup lang="ts">
import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
import { computed, type PropType } 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";
import type { WorkflowParameters } from "@/types/WorkflowParameters";
const model = defineModel<WorkflowParameters>({ required: true });
const props = defineProps({
parameterGroup: {
type: Object,
required: true,
validator(value: Record<string, never>) {
return "object" === value["type"];
},
},
parameterGroupName: {
type: String,
required: true,
},
showHidden: {
type: Boolean,
default: false,
},
showOptional: {
type: Boolean,
default: false,
},
resourceParameters: {
type: Array as PropType<string[]>,
required: false,
},
});
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 groupRequired = computed<boolean>(
() => (props.parameterGroup["required"] ?? []).length > 0,
);
const parameters = computed<Record<string, never>>(
() => props.parameterGroup["properties"],
);
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) => model.value[param])
?.reduce((acc: boolean, val: string) => acc || val, false)
);
}
</script>
<template>
<div
class="card mb-3"
:hidden="(!showHidden && groupHidden) || (!showOptional && !groupRequired)"
>
<h3 class="card-header" :id="props.parameterGroupName">
<font-awesome-icon :icon="icon" class="me-2" v-if="icon" />
{{ title }}
</h3>
<div class="card-body">
<h5 class="card-title" v-if="description">{{ description }}</h5>
<template
v-for="(parameter, parameterName) in parameters"
:key="parameterName"
>
<div
:hidden="
(!showHidden && parameter['hidden']) ||
(!showOptional && !parameterRequired(parameterGroup, parameterName))
"
>
<code
class="p-2 rounded-top border-bottom-0 border bg-secondary-subtle border-secondary"
>--{{ parameter["name"] ?? parameterName }}</code
><span
v-if="parameterRequired(parameterGroup, parameterName)"
class="rounded p-1 bg-warning text-light ms-2"
>required</span
>
<div class="input-group">
<span
class="input-group-text border-end-0 border border-secondary"
v-if="parameter['fa_icon']"
>
<font-awesome-icon :icon="parameter['fa_icon']" />
</span>
<template
v-if="
parameter['type'] === 'number' ||
parameter['type'] === 'integer'
"
>
<!-- @vue-ignore -->
<parameter-number-input
:parameter-name="parameterName"
:parameter="parameter"
:help-id="parameterName + '-help'"
:required="parameterRequired(parameterGroup, parameterName)"
v-model="model[parameterName]"
/>
</template>
<template v-else-if="parameter['type'] === 'boolean'">
<!-- @vue-ignore -->
<parameter-boolean-input
:parameter-name="parameterName"
:parameter="parameter"
:help-id="parameterName + '-help'"
v-model="model[parameterName]"
/>
</template>
<template v-else-if="parameter['type'] === 'string'">
<!-- @vue-ignore -->
<template v-if="parameter['enum']">
<!-- @vue-ignore -->
<parameter-enum-input
:parameter-name="parameterName"
:parameter="parameter"
:required="parameterRequired(parameterGroup, parameterName)"
v-model="model[parameterName]"
/>
</template>
<!-- @vue-ignore -->
<parameter-string-input
v-else
:parameter-name="parameterName"
:parameter="parameter"
:required="parameterRequired(parameterGroup, parameterName)"
v-model="model[parameterName]"
:remove-advanced="!showOptional"
:clowm-resource="resourceParameters?.includes(parameterName)"
/>
</template>
<span
class="input-group-text cursor-pointer px-2 border border-secondary"
v-if="parameter['help_text']"
data-bs-toggle="collapse"
:data-bs-target="
'#helpCollapse' + parameterName.replace(/\./g, '')
"
aria-expanded="false"
:aria-controls="'helpCollapse' + parameterName.replace(/\./g, '')"
>
<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"
:id="'helpCollapse' + parameterName.replace(/\./g, '')"
v-if="parameter['help_text']"
>
<div class="p-2 pb-0 mx-2 mb-3 flex-shrink-1 border rounded">
<markdown-renderer
class="helpTextCode"
:markdown="parameter['help_text']"
/>
<p v-if="parameter['pattern']">
Pattern: <code>{{ parameter["pattern"] }}</code>
</p>
</div>
</div>
</div>
</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>