From b2819e5ef614589ab84c0bd8dcf52cb973ac87df Mon Sep 17 00:00:00 2001 From: Bohdan Shulha Date: Wed, 28 Aug 2024 01:24:37 +0200 Subject: [PATCH] feat: #145 rework 1-click template forms logic --- .../Services/Partials/DeploymentData.vue | 2 +- .../Pages/Services/Partials/DynamicForm.vue | 56 ++++++++++++ .../Services/Partials/TemplatePicker.vue | 90 +++++++++++++------ 3 files changed, 119 insertions(+), 29 deletions(-) create mode 100644 resources/js/Pages/Services/Partials/DynamicForm.vue diff --git a/resources/js/Pages/Services/Partials/DeploymentData.vue b/resources/js/Pages/Services/Partials/DeploymentData.vue index 97d19aa..93762c2 100644 --- a/resources/js/Pages/Services/Partials/DeploymentData.vue +++ b/resources/js/Pages/Services/Partials/DeploymentData.vue @@ -1570,7 +1570,7 @@ const extractFieldErrors = (basePath) => {
{ + if (props.scope) { + return `${props.scope}/${props.item.name}`; + } + + return props.item.name; +}); + + + diff --git a/resources/js/Pages/Services/Partials/TemplatePicker.vue b/resources/js/Pages/Services/Partials/TemplatePicker.vue index ce72953..64d42be 100644 --- a/resources/js/Pages/Services/Partials/TemplatePicker.vue +++ b/resources/js/Pages/Services/Partials/TemplatePicker.vue @@ -8,6 +8,7 @@ import TextInput from "@/Components/TextInput.vue"; import FormField from "@/Components/FormField.vue"; import { makeId } from "@/id.js"; import useSWRV, { mutate } from "swrv"; +import DynamicForm from "./DynamicForm.vue"; const props = defineProps({ marketplaceUrl: String, @@ -45,6 +46,9 @@ const form = reactive({ }); const selectTemplate = async (template) => { + form.errors = {}; + form.data = {}; + state.template = await ( await fetch(props.marketplaceUrl + "/" + template.slug + ".json") ).json(); @@ -136,6 +140,25 @@ const mapProcessTemplate = (templateSlug, process, newIndex) => { }; const applyTemplate = () => { + form.errors = {}; + + validateForm(form.data, state.template.form, form.errors); + state.extends.forEach((template) => { + console.log( + JSON.stringify({ + data: form.data, + form: template.form, + errors: form.errors, + slug: template.slug, + }), + ); + validateForm(form.data, template.form, form.errors, template.slug); + }); + + if (Object.keys(form.errors).length > 0) { + return; + } + const extendedTemplates = state.extends.reduce((acc, template) => { return [ ...acc, @@ -159,6 +182,34 @@ const applyTemplate = () => { }, }); }; + +const validateForm = (formData, schema, errors, scope) => { + switch (schema.type) { + case "v-stack": + case "h-stack": + for (const item of schema.items) { + validateForm(formData, item, errors, scope); + } + + break; + case "text-field": + console.log(JSON.stringify({ formData, schema, errors, scope })); + + const itemName = scope ? `${scope}/${schema.name}` : schema.name; + if ( + schema.required && + schema.format === "string" && + (formData[itemName] == null || formData[itemName].trim() === "") + ) { + errors[itemName] = + `The ${schema.label.toLowerCase()} field is required`; + } + + break; + } + + return Object.keys(errors).length === 0; +};