Преглед изворни кода

refactor form data to context

Ivan Galakhov пре 4 година
родитељ
комит
cdaa8786da

+ 0 - 36
dashboard/src/components/form-refactor/PorterForm.tsx

@@ -31,43 +31,7 @@ const PorterForm: React.FC<Props> = () => {
     return <p>Not Implemented: {(field as any).type}</p>;
   };
 
-  const evalShowIf = (vals: ShowIf): boolean => {
-    if (!vals) {
-      return false;
-    }
-    if (typeof vals == "string") {
-      return !!formState.variables[vals];
-    }
-    if ((vals as ShowIfOr).or) {
-      vals = vals as ShowIfOr;
-      for (let i = 0; i < vals.or.length; i++) {
-        if (evalShowIf(vals.or[i])) {
-          return true;
-        }
-      }
-      return false;
-    }
-    if ((vals as ShowIfAnd).and) {
-      vals = vals as ShowIfAnd;
-      for (let i = 0; i < vals.and.length; i++) {
-        if (!evalShowIf(vals.and[i])) {
-          return false;
-        }
-      }
-      return true;
-    }
-    if ((vals as ShowIfNot).not) {
-      vals = vals as ShowIfNot;
-      return !evalShowIf(vals.not);
-    }
-
-    return false;
-  };
-
   const renderSection = (section: Section): JSX.Element => {
-    if (section.show_if && !evalShowIf(section.show_if)) {
-      return null;
-    }
     return (
       <>
         {section.contents.map((field, i) => {

+ 73 - 3
dashboard/src/components/form-refactor/PorterFormContextProvider.tsx

@@ -1,8 +1,14 @@
 import React, { createContext, useReducer } from "react";
-import { PorterFormData, PorterFormState, PorterFormAction } from "./types";
+import {
+  PorterFormData,
+  PorterFormState,
+  PorterFormAction,
+  PorterFormVariableList,
+} from "./types";
+import { ShowIf, ShowIfAnd, ShowIfNot, ShowIfOr } from "../../shared/types";
 
 interface Props {
-  formData: PorterFormData;
+  rawFormData: PorterFormData;
 }
 
 interface ContextProps {
@@ -69,10 +75,74 @@ export const PorterFormContextProvider: React.FC<Props> = (props) => {
     variables: {},
   });
 
+  const evalShowIf = (
+    vals: ShowIf,
+    variables: PorterFormVariableList
+  ): boolean => {
+    if (!vals) {
+      return false;
+    }
+    if (typeof vals == "string") {
+      return !!variables[vals];
+    }
+    if ((vals as ShowIfOr).or) {
+      vals = vals as ShowIfOr;
+      for (let i = 0; i < vals.or.length; i++) {
+        if (evalShowIf(vals.or[i], variables)) {
+          return true;
+        }
+      }
+      return false;
+    }
+    if ((vals as ShowIfAnd).and) {
+      vals = vals as ShowIfAnd;
+      for (let i = 0; i < vals.and.length; i++) {
+        if (!evalShowIf(vals.and[i], variables)) {
+          return false;
+        }
+      }
+      return true;
+    }
+    if ((vals as ShowIfNot).not) {
+      vals = vals as ShowIfNot;
+      return !evalShowIf(vals.not, variables);
+    }
+
+    return false;
+  };
+
+  /*
+  We don't want to have the actual <PorterForm> component to do as little form
+  logic as possible, so this structures the form object based on show_if statements
+
+  This computed structure also later lets us figure out which fields should be required
+  */
+  const computeFormStructure = (
+    data: PorterFormData,
+    variables: PorterFormVariableList
+  ) => {
+    console.log(state.variables);
+    console.log(props.rawFormData);
+
+    return {
+      ...data,
+      tabs: data.tabs.map((tab) => {
+        return {
+          ...tab,
+          sections: tab.sections.filter((section) => {
+            return !section.show_if || evalShowIf(section.show_if, variables);
+          }),
+        };
+      }),
+    };
+  };
+
+  const formData = computeFormStructure(props.rawFormData, state.variables);
+
   return (
     <Provider
       value={{
-        formData: props.formData,
+        formData: formData,
         formState: state,
         dispatchAction: dispatch,
       }}

+ 1 - 1
dashboard/src/components/values-form/FormDebugger.tsx

@@ -159,7 +159,7 @@ export default class FormDebugger extends Component<PropsType, StateType> {
 
         <Heading>🎨 Rendered Form</Heading>
         <Br />
-        <PorterFormContextProvider formData={formData as PorterFormData}>
+        <PorterFormContextProvider rawFormData={formData as PorterFormData}>
           <PorterForm />
         </PorterFormContextProvider>
         {/*<FormWrapper*/}