diff --git a/cyclops-ctrl/internal/mapper/helm.go b/cyclops-ctrl/internal/mapper/helm.go index 47d8b04a2..2d24575da 100644 --- a/cyclops-ctrl/internal/mapper/helm.go +++ b/cyclops-ctrl/internal/mapper/helm.go @@ -44,6 +44,8 @@ func HelmSchemaToFields(name string, schema helm.Property, defs map[string]helm. fields = append(fields, HelmSchemaToFields(propertyName, property, defs, nil)) } + fields = append(fields, conditionedFields(schema, defs)...) + fields = sortFields(fields, schema.Order) for _, dependency := range dependencies { @@ -238,3 +240,46 @@ func resolvePropertyComposition(schema helm.Property) helm.Property { return schema.AnyOf[0] } + +func conditionedFields(schema helm.Property, defs map[string]helm.Property) []models.Field { + if schema.If == nil { + return []models.Field{} + } + + conditionalFields := make([]models.Field, 0) + + if schema.Then != nil { + for propertyName, property := range schema.Then.Properties { + field := HelmSchemaToFields(propertyName, property, defs, nil) + field.Condition = mapConditions(schema.If, models.Equal) + + conditionalFields = append(conditionalFields, field) + } + } + + if schema.Else != nil { + for propertyName, property := range schema.Else.Properties { + field := HelmSchemaToFields(propertyName, property, defs, nil) + field.Condition = mapConditions(schema.If, models.NotEqual) + + conditionalFields = append(conditionalFields, field) + } + } + + return conditionalFields +} + +func mapConditions(r *helm.Property, operation models.ConditionOperation) []models.Condition { + conditions := make([]models.Condition, 0) + + for propertyName, property := range r.Properties { + conditions = append(conditions, models.Condition{ + Operation: operation, + Property: propertyName, + Const: property.Const, + Enum: property.Enum, + }) + } + + return conditions +} diff --git a/cyclops-ctrl/internal/models/helm/helmschema.go b/cyclops-ctrl/internal/models/helm/helmschema.go index 85ed8dc36..404e5a2b9 100644 --- a/cyclops-ctrl/internal/models/helm/helmschema.go +++ b/cyclops-ctrl/internal/models/helm/helmschema.go @@ -35,6 +35,12 @@ type Property struct { // schema compositions AnyOf []Property `json:"anyOf"` + AllOf []Property `json:"allOf"` + + If *Property `json:"if,omitempty"` + Then *Property `json:"then,omitempty"` + Else *Property `json:"else,omitempty"` + Const *string `json:"const"` } type PropertyType string diff --git a/cyclops-ctrl/internal/models/templates.go b/cyclops-ctrl/internal/models/templates.go index 4d8f02350..5c4f98524 100644 --- a/cyclops-ctrl/internal/models/templates.go +++ b/cyclops-ctrl/internal/models/templates.go @@ -55,4 +55,20 @@ type Field struct { MinLength *int `json:"minLength"` MaxLength *int `json:"maxLength"` Pattern *string `json:"pattern"` + + Condition []Condition `json:"condition"` +} + +type Condition struct { + Operation ConditionOperation `json:"operation"` + Property string `json:"property"` + Const interface{} `json:"const"` + Enum []interface{} `json:"enum"` } + +type ConditionOperation string + +const ( + Equal ConditionOperation = "eq" + NotEqual ConditionOperation = "neq" +) diff --git a/cyclops-ui/src/components/form/fields/string/StringField.tsx b/cyclops-ui/src/components/form/fields/string/StringField.tsx index 34dcf2354..a3c4d9d52 100644 --- a/cyclops-ui/src/components/form/fields/string/StringField.tsx +++ b/cyclops-ui/src/components/form/fields/string/StringField.tsx @@ -1,6 +1,7 @@ -import React from "react"; +import React, { useState } from "react"; import { Form, Input } from "antd"; import { stringInputValidators } from "./validators"; +import { resolveConditions } from "../../../../utils/conditionalFields"; interface Props { field: any; @@ -17,16 +18,32 @@ const StringField = ({ isRequired, isModuleEdit, }: Props) => { - let stringValidationRules = stringInputValidators(field, isRequired); + const [display, setDisplay] = useState(!field.condition); + + const stringValidationRules = stringInputValidators(field, isRequired); + + const shouldUpdate = (prevValues, curValues) => { + if (!field.condition || field.condition.length === 0) { + return false; + } + + let shouldDisplay = resolveConditions(field.condition, curValues); + if (shouldDisplay !== display) { + setDisplay(shouldDisplay); + return true; + } + + return false; + }; return (