Explorar el Código

outward variable mapping

Ivan Galakhov hace 4 años
padre
commit
050563f7d5

+ 2 - 2
dashboard/src/components/form-refactor/PorterForm.tsx

@@ -20,7 +20,7 @@ interface Props {
 }
 
 const PorterForm: React.FC<Props> = (props) => {
-  const { formData, isReadOnly, validationInfo } = useContext(
+  const { formData, isReadOnly, validationInfo, onSubmit } = useContext(
     PorterFormContext
   );
 
@@ -102,7 +102,7 @@ const PorterForm: React.FC<Props> = (props) => {
       </TabRegion>
       <SaveButton
         text={props.saveButtonText || "Deploy"}
-        onClick={() => {}}
+        onClick={onSubmit}
         makeFlush
         status={validationInfo.validated ? "" : validationInfo.error}
         disabled={isReadOnly || !validationInfo.validated}

+ 49 - 2
dashboard/src/components/form-refactor/PorterFormContextProvider.tsx

@@ -5,11 +5,14 @@ import {
   PorterFormAction,
   PorterFormVariableList,
   PorterFormValidationInfo,
+  GetFinalVariablesFunction,
 } from "./types";
 import { ShowIf, ShowIfAnd, ShowIfNot, ShowIfOr } from "../../shared/types";
+import { getFinalVariablesForStringInput } from "./field-components/StringInput";
 
 interface Props {
   rawFormData: PorterFormData;
+  onSubmit: (vars: PorterFormVariableList) => void;
   initialVariables?: PorterFormVariableList;
   overrideVariables?: PorterFormVariableList;
   isReadOnly?: boolean;
@@ -18,6 +21,7 @@ interface Props {
 interface ContextProps {
   formData: PorterFormData;
   formState: PorterFormState;
+  onSubmit: () => void;
   dispatchAction: (event: PorterFormAction) => void;
   validationInfo: PorterFormValidationInfo;
   isReadOnly?: boolean;
@@ -38,6 +42,10 @@ export const PorterFormContextProvider: React.FC<Props> = (props) => {
         if (!(action.id in state.components)) {
           return {
             ...state,
+            variables: {
+              ...state.variables,
+              ...action.initVars,
+            },
             components: {
               ...state.components,
               [action.id]: {
@@ -168,6 +176,7 @@ export const PorterFormContextProvider: React.FC<Props> = (props) => {
       }),
     };
   };
+
   /*
     compute a list of field ids who's input is required and a map from a variable value
     to a list of fields that set it
@@ -195,8 +204,7 @@ export const PorterFormContextProvider: React.FC<Props> = (props) => {
   };
 
   /*
-    Validate the form based
-    Will get more complicated over time
+    Validate the form based on a list of required ids
    */
   const doValidation = (requiredIds: string[]) =>
     requiredIds
@@ -207,6 +215,44 @@ export const PorterFormContextProvider: React.FC<Props> = (props) => {
   const [requiredIds, varMapping] = computeRequiredVariables(formData);
   const isValidated = doValidation(requiredIds);
 
+  /*
+  Handle submit
+  This involves going through all the (currently active) fields in the form and
+  using functions for each input to finalize the variables
+  This can take care of things like appending units to strings
+ */
+  const onSubmitWrapper = () => {
+    // we start off with a base list of the current variables for fields
+    // that don't need any processing on top (for example: checkbox)
+    // the assign here is important because that way state.variable isn't mutated
+    const varList: PorterFormVariableList[] = [
+      Object.assign({}, state.variables),
+    ];
+    const finalFunctions: Record<string, GetFinalVariablesFunction> = {
+      "string-input": getFinalVariablesForStringInput,
+    };
+
+    formData.tabs.map((tab) =>
+      tab.sections.map((section) =>
+        section.contents.map((field) => {
+          if (finalFunctions[field.type])
+            varList.push(
+              finalFunctions[field.type](
+                state.variables,
+                field,
+                state.components[field.id]
+              )
+            );
+        })
+      )
+    );
+
+    console.log("??");
+    console.log(state.variables);
+
+    props.onSubmit(Object.assign.apply({}, varList));
+  };
+
   console.group("Validation Info:");
   console.log(requiredIds);
   console.log(varMapping);
@@ -224,6 +270,7 @@ export const PorterFormContextProvider: React.FC<Props> = (props) => {
           validated: isValidated,
           error: isValidated ? null : "Missing required fields",
         },
+        onSubmit: onSubmitWrapper,
       }}
     >
       {props.children}

+ 1 - 0
dashboard/src/components/form-refactor/field-components/Checkbox.tsx

@@ -21,6 +21,7 @@ const Checkbox: React.FC<Props> = ({
       initValidation: {
         validated: !required,
       },
+      initVars: {},
     }
   );
 

+ 21 - 1
dashboard/src/components/form-refactor/field-components/StringInput.tsx

@@ -3,6 +3,7 @@ import InputRow from "../../values-form/InputRow";
 import useFormField from "../hooks/useFormField";
 import {
   GenericInputField,
+  GetFinalVariablesFunction,
   StringInputField,
   StringInputFieldState,
 } from "../types";
@@ -29,7 +30,10 @@ const StringInput: React.FC<Props> = ({
   } = useFormField<StringInputFieldState>(id, {
     initValue: {},
     initValidation: {
-      validated: false,
+      validated: settings?.default != undefined,
+    },
+    initVars: {
+      [variable]: settings?.default,
     },
   });
 
@@ -77,4 +81,20 @@ const StringInput: React.FC<Props> = ({
   );
 };
 
+export const getFinalVariablesForStringInput: GetFinalVariablesFunction = (
+  vars,
+  props: StringInputField
+) => {
+  if (vars[props.variable])
+    return {
+      [props.variable]:
+        props.settings?.unit && !props.settings?.omitUnitFromValue
+          ? vars[props.variable] + props.settings.unit
+          : vars[props.variable],
+    };
+  return {
+    [props.variable]: props.settings?.default,
+  };
+};
+
 export default StringInput;

+ 3 - 1
dashboard/src/components/form-refactor/hooks/useFormField.tsx

@@ -23,11 +23,12 @@ interface FormFieldData<T> {
 interface Options<T> {
   initValue: T;
   initValidation?: Partial<PorterFormFieldValidationState>;
+  initVars?: PorterFormVariableList;
 }
 
 const useFormField = <T extends PorterFormFieldFieldState>(
   fieldId: string,
-  { initValue, initValidation }: Options<T>
+  { initValue, initVars, initValidation }: Options<T>
 ): FormFieldData<T> => {
   const { dispatchAction, formState } = useContext(PorterFormContext);
 
@@ -37,6 +38,7 @@ const useFormField = <T extends PorterFormFieldFieldState>(
       id: fieldId,
       initValue,
       initValidation,
+      initVars,
     });
   }, []);
 

+ 4 - 0
dashboard/src/components/form-refactor/types.ts

@@ -29,6 +29,7 @@ export interface StringInputFieldSettings {
   type?: "text"|"password"|"number";
   unit?: string;
   omitUnitFromValue?: boolean;
+  default: string|number;
 }
 
 export interface StringInputField extends GenericInputField {
@@ -118,6 +119,7 @@ export interface PorterFormInitFieldAction {
   id: string;
   initValue: PorterFormFieldFieldState;
   initValidation?: Partial<PorterFormFieldValidationState>
+  initVars?: PorterFormVariableList
 }
 
 export interface PorterFormUpdateFieldAction {
@@ -138,3 +140,5 @@ export interface PorterFormMutateVariablesAction {
 }
 
 export type PorterFormAction = PorterFormInitFieldAction|PorterFormUpdateFieldAction|PorterFormMutateVariablesAction|PorterFormUpdateValidationAction;
+
+export type GetFinalVariablesFunction = (vars: PorterFormVariableList, props: FormField, state: PorterFormFieldFieldState) => PorterFormVariableList;

+ 5 - 0
dashboard/src/components/values-form/FormDebugger.tsx

@@ -164,6 +164,10 @@ export default class FormDebugger extends Component<PropsType, StateType> {
             input_a: this.state.valuesToOverride?.input_a?.value,
           }}
           isReadOnly={this.state.isReadOnly}
+          onSubmit={(vars) => {
+            console.log("check console output");
+            console.log(vars);
+          }}
         >
           <PorterForm
             rightTabOptions={this.state.showBonusTabs ? tabOptions : []}
@@ -290,6 +294,7 @@ tabs:
       info: This is some info
       settings:
         type: text
+        default: hello
     - type: string-input
       placeholder: "ex: pilsner"
       label: Required String Input A with unit