Skip to content

Commit

Permalink
fix: Ensure that parameter default values are correctly set when crea…
Browse files Browse the repository at this point in the history
…ting a pro instance and switching template versions
  • Loading branch information
PRTTMPRPHT authored and pascalbreuninger committed Dec 17, 2024
1 parent fe13cbb commit 3f46926
Showing 1 changed file with 52 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from "@chakra-ui/react"
import { ManagementV1DevPodWorkspaceTemplate } from "@loft-enterprise/client/gen/models/managementV1DevPodWorkspaceTemplate"
import { StorageV1AppParameter } from "@loft-enterprise/client/gen/models/storageV1AppParameter"
import { ReactNode, useMemo } from "react"
import { ReactNode, useEffect, useMemo } from "react"
import { ChangeHandler, Controller, useFormContext } from "react-hook-form"
import { FieldName, TFormValues } from "./types"

Expand All @@ -31,7 +31,8 @@ export function InfrastructureTemplateInput({
defaultInfraTemplate,
resetPreset,
}: TOptionsInputProps) {
const { getValues, watch, resetField, formState } = useFormContext<TFormValues>()
const { getValues, watch, resetField, formState, unregister, setValue } =
useFormContext<TFormValues>()
const borderColor = useBorderColor()

const defaultTemplate = defaultInfraTemplate ?? templates[0]
Expand All @@ -50,9 +51,35 @@ export function InfrastructureTemplateInput({
v = ""
}

return getParameters(currentTemplate, v)
const params = getParameters(currentTemplate, v)

return !params ? params : [...params]
}, [currentTemplate, selectedTemplateVersion])

useEffect(() => {
const value = getValues()

// Apply default values manually when the set of parameters changes.
currentParameters?.forEach((p) => {
if (!p.variable) {
return
}

const paramValue = getDeepValue(value.options, p.variable)
if (paramValue == null && p.defaultValue != null) {
setValue(`${FieldName.OPTIONS}.${p.variable}`, p.defaultValue)
}
})

// resetField won't properly delete the keys when you switch templates,
// so it's probably best to clean it up every time the set of parameters changes...
return () => {
currentParameters?.forEach((p) => {
unregister(`${FieldName.OPTIONS}.${p.variable?.split(/\./)[0]}`)
})
}
}, [currentParameters, unregister, getValues, setValue])

const currentTemplateVersions = useMemo(() => {
return currentTemplate?.spec?.versions?.slice().sort(sortByVersionDesc)
}, [currentTemplate?.spec?.versions])
Expand Down Expand Up @@ -347,3 +374,25 @@ function convertParameterType(paramType: StorageV1AppParameter["type"]): TProvid
return undefined
}
}

function createTraversablePropertyPath(path: string): string[] {
path = path.replace(/\[(\w+)\]/g, ".$1")
path = path.replace(/^\./, "")

return path.split(".")
}

export function getDeepValue<T>(obj: any, path: string): T | undefined {
if (!obj) return undefined

const a = createTraversablePropertyPath(path)
let o = obj
while (a.length) {
const n = a.shift()
if (!n) continue
if (o == null || !(n in o)) return undefined
o = o[n]
}

return o
}

0 comments on commit 3f46926

Please sign in to comment.