From 6d13daf35e5a15e235cd14a855f60f03a370ee43 Mon Sep 17 00:00:00 2001
From: Timothy Bula <trbula@us.ibm.com>
Date: Mon, 11 Sep 2023 20:03:14 -0500
Subject: [PATCH] feat: get params working

---
 src/ApiServer/fixtures/changelogs.js          | 24 ++++-----
 src/ApiServer/fixtures/workflowCompose.js     |  1 +
 src/ApiServer/index.js                        |  3 +-
 src/Features/Editor/ChangeLog/ChangeLog.tsx   | 37 +++----------
 .../ChangeLogTable/ChangeLogTable.tsx         | 22 ++++----
 src/Features/Editor/Configure/Configure.tsx   | 18 -------
 src/Features/Editor/Editor.tsx                | 54 ++++++++++---------
 src/Features/Editor/Parameters/Parameters.tsx | 36 +++----------
 .../PropertiesModal/PropertiesModal.tsx       |  5 +-
 .../PropertiesModalContent.tsx                | 35 +++++-------
 src/State/reducers/workflowRevision.ts        | 12 +++--
 src/Types/index.tsx                           |  1 +
 12 files changed, 93 insertions(+), 155 deletions(-)

diff --git a/src/ApiServer/fixtures/changelogs.js b/src/ApiServer/fixtures/changelogs.js
index f4db770c6..ad5ee6f3b 100644
--- a/src/ApiServer/fixtures/changelogs.js
+++ b/src/ApiServer/fixtures/changelogs.js
@@ -1,21 +1,21 @@
 const changelog = [
   {
-    date: "2020-05-28T19:32:48.710+0000",
-    reason: "Sorry. Removing changes.",
-    revisionId: "5ed011e0eddd5f0001eeb7d0",
-    userId: "5dbb17ed418ad600013cedfc",
-    userName: "Boomerang/chicago/ibm Boomerang/chicago/ibm",
+    author: null,
+    reason: "400ms",
+    date: "2023-09-11T23:06:16.346+00:00",
+    version: 3,
+  },
+  {
+    author: "61d38d133aa9034ded32cae6",
+    reason: "",
+    date: "2022-01-07T07:43:05.304+00:00",
     version: 2,
-    workflowId: "5eb2c4085a92d80001a16d87",
   },
   {
-    date: "2020-05-28T17:42:18.593+0000",
-    reason: "hello sir",
-    revisionId: "5ecff7faeddd5f0001ee5473",
-    userId: "5dbb17ed418ad600013cedfc",
-    userName: "Boomerang/chicago/ibm Boomerang/chicago/ibm",
+    author: "61d38d133aa9034ded32cae6",
+    reason: "Create workflow",
+    date: "2022-01-07T07:42:50.919+00:00",
     version: 1,
-    workflowId: "5eb2c4085a92d80001a16d87",
   },
 ];
 
diff --git a/src/ApiServer/fixtures/workflowCompose.js b/src/ApiServer/fixtures/workflowCompose.js
index 0fd4ebc5e..ef641eacb 100644
--- a/src/ApiServer/fixtures/workflowCompose.js
+++ b/src/ApiServer/fixtures/workflowCompose.js
@@ -16,6 +16,7 @@ const workflowsCompose = [
       webhook: { enable: false, token: "", topic: null },
       custom: { enable: false, token: null, topic: null },
     },
+    config: [],
     tokens: [{ token: "268CD9268194A7B58888DC4B8FB4E6BF1358D01CEBB97F8670C544B4F076DD63", label: "default" }],
     nodes: [
       {
diff --git a/src/ApiServer/index.js b/src/ApiServer/index.js
index f91117420..a4948aeb5 100644
--- a/src/ApiServer/index.js
+++ b/src/ApiServer/index.js
@@ -373,8 +373,7 @@ export function startApiServer({ environment = "test", timing = 0 } = {}) {
 
       // Workflow Changelog
       this.get(serviceUrl.getWorkflowChangelog({ id: ":id" }), (schema, request) => {
-        let { workflowId } = request.params;
-        return schema.changelogs.where({ workflowId });
+        return schema.db.changelogs;
       });
 
       //Workflow Available Parameters
diff --git a/src/Features/Editor/ChangeLog/ChangeLog.tsx b/src/Features/Editor/ChangeLog/ChangeLog.tsx
index b5e199579..9ef6083ca 100644
--- a/src/Features/Editor/ChangeLog/ChangeLog.tsx
+++ b/src/Features/Editor/ChangeLog/ChangeLog.tsx
@@ -1,47 +1,22 @@
 import React from "react";
 import { Helmet } from "react-helmet";
-import qs from "query-string";
-import { useQuery } from "Hooks";
-import { DataTableSkeleton, SearchSkeleton } from "@carbon/react";
-import { DelayedRender } from "@boomerang-io/carbon-addons-boomerang-react";
-import ErrorDragon from "Components/ErrorDragon";
 import ChangeLogTable from "./ChangeLogTable";
-import { serviceUrl } from "Config/servicesConfig";
-import { WorkflowSummary } from "Types";
+import { ChangeLog as ChangeLogType } from "Types";
 import styles from "./changeLog.module.scss";
 
 interface ChangeLogProps {
-  summaryData: WorkflowSummary;
+  changeLogData: ChangeLogType;
 }
 
-const ChangeLog: React.FC<ChangeLogProps> = ({ summaryData }) => {
-  const getWorkflowChangelogUrl = serviceUrl.getWorkflowChangelog({
-    workflowId: summaryData.id,
-    query: qs.stringify({ sort: "version", order: "DESC" }),
-  });
-  const { data, error, isLoading } = useQuery(getWorkflowChangelogUrl);
-  if (isLoading)
-    return (
-      <DelayedRender>
-        <div className={styles.container}>
-          <div className={styles.searchSkeleton}>
-            <SearchSkeleton small />
-          </div>
-          <DataTableSkeleton />
-        </div>
-      </DelayedRender>
-    );
-
-  if (error) return <ErrorDragon />;
-
+function ChangeLog({ changeLogData }: ChangeLogProps) {
   return (
     <div className={styles.container}>
       <Helmet>
-        <title>{`Change Log - ${summaryData.name}`}</title>
+        <title>Change Log</title>
       </Helmet>
-      <ChangeLogTable changeLog={data} />
+      <ChangeLogTable changeLog={changeLogData} />
     </div>
   );
-};
+}
 
 export default ChangeLog;
diff --git a/src/Features/Editor/ChangeLog/ChangeLogTable/ChangeLogTable.tsx b/src/Features/Editor/ChangeLog/ChangeLogTable/ChangeLogTable.tsx
index 32d69cd64..81abda9f1 100644
--- a/src/Features/Editor/ChangeLog/ChangeLogTable/ChangeLogTable.tsx
+++ b/src/Features/Editor/ChangeLog/ChangeLogTable/ChangeLogTable.tsx
@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import { matchSorter } from "match-sorter";
 import PropTypes from "prop-types";
 import moment from "moment";
-import { DataTable, Search, Pagination } from "@carbon/react";
+import { DataTable, Pagination, Layer, Search } from "@carbon/react";
 import EmptyState from "Components/EmptyState";
 import { ChangeLog } from "Types";
 import styles from "./changeLogTable.module.scss";
@@ -58,7 +58,7 @@ class ChangeLogTable extends Component<ChangeLogTableProps> {
   handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
     const searchQuery = e.target.value;
     const { changeLog } = this.props;
-    const changeLogList = changeLog.length !== 0 ? changeLog.map((log) => ({ ...log, id: log.revisionId })) : [];
+    const changeLogList = changeLog.length !== 0 ? changeLog.map((log) => ({ ...log, id: log.version })) : [];
 
     const newLogs = searchQuery
       ? matchSorter(changeLogList, searchQuery, { keys: ["version", "userName", "reason"] })
@@ -90,14 +90,16 @@ class ChangeLogTable extends Component<ChangeLogTableProps> {
 
     return (
       <div className={styles.tableContainer}>
-        <Search
-          className={styles.search}
-          data-testid="change-log-search"
-          id="change-log-table-search"
-          labelText="Search"
-          onChange={this.handleSearchChange}
-          placeholder="Search"
-        />
+        <Layer>
+          <Search
+            className={styles.search}
+            data-testid="change-log-search"
+            id="change-log-table-search"
+            labelText="Search"
+            onChange={this.handleSearchChange}
+            placeholder="Search"
+          />
+        </Layer>
         {totalItems > 0 ? (
           <>
             <DataTable
diff --git a/src/Features/Editor/Configure/Configure.tsx b/src/Features/Editor/Configure/Configure.tsx
index 1d0fbaffc..767272712 100644
--- a/src/Features/Editor/Configure/Configure.tsx
+++ b/src/Features/Editor/Configure/Configure.tsx
@@ -631,24 +631,6 @@ class Configure extends Component<ConfigureProps, ConfigureState> {
               <CustomLabel formikPropsSetFieldValue={setFieldValue} labels={values.labels} />
             </div>
           </div>
-          <hr className={styles.delimiter} />
-          <div className={styles.saveChangesContainer}>
-            <Button
-              size="md"
-              disabled={!dirty || isLoading}
-              iconDescription="Save"
-              onClick={(e: any) => {
-                e.preventDefault();
-                handleSubmit();
-              }}
-              renderIcon={Save}
-            >
-              {isLoading ? "Saving..." : "Save"}
-            </Button>
-            <p className={styles.saveText}>
-              Save the configuration. Versioning functionality only applies to the Workflow.
-            </p>
-          </div>
         </section>
       </div>
     );
diff --git a/src/Features/Editor/Editor.tsx b/src/Features/Editor/Editor.tsx
index a4f554f0f..64dcb861d 100644
--- a/src/Features/Editor/Editor.tsx
+++ b/src/Features/Editor/Editor.tsx
@@ -24,9 +24,11 @@ import {
   TaskTemplate,
   WorkflowView,
   WorkflowCanvas,
+  DataDrivenInput,
 } from "Types";
 import type { ReactFlowInstance } from "reactflow";
 import styles from "./editor.module.scss";
+import { set } from "cypress/types/lodash";
 
 export default function EditorContainer() {
   const { team } = useTeamContext();
@@ -52,12 +54,12 @@ export default function EditorContainer() {
   /**
    * Queries
    */
-  const changeLogQuery = useQuery(getChangelogUrl);
+  const changeLogQuery = useQuery<ChangeLogType>(getChangelogUrl);
   const workflowQuery = useQuery<WorkflowCanvas>(getWorkflowUrl);
   const workflowsQuery = useQuery<PaginatedWorkflowResponse>(getWorkflowsUrl);
   const taskTemplatesQuery = useQuery(getTaskTemplatesUrl);
   const taskTemplatesTeamQuery = useQuery(getTaskTemplatesTeamUrl);
-  const availableParametersQuery = useQuery(getAvailableParametersUrl);
+  const availableParametersQuery = useQuery(getAvailableParametersUrl, {});
 
   /**
    * Mutations
@@ -165,25 +167,7 @@ const EditorStateContainer: React.FC<EditorStateContainerProps> = ({
   );
 
   const [workflow, setWorkflow] = React.useState<ReactFlowInstance | null>(null);
-
-  // //Triggers the POST request for refresh availableParameters
-  // useEffect(() => {
-  //   if (JSON.stringify(revisionConfig) !== JSON.stringify(revisionState)) {
-  //     const normilzedConfig = Object.values(revisionState.config).map((config: any) => ({
-  //       ...config,
-  //       currentVersion: undefined,
-  //       taskVersion: config.currentVersion || config.taskVersion,
-  //     }));
-  //     const revisionConfig = { nodes: Object.values(normilzedConfig) };
-  //     const revision = {
-  //       changelog: revisionState.changelog,
-  //       config: revisionConfig,
-  //       dag: revisionState.dag,
-  //     };
-  //     setRevisionConfig(revisionState);
-  //     parametersMutator.mutateAsync({ workflowId, body: revision });
-  //   }
-  // }, [parametersMutator, workflowId, revisionState, revisionConfig]);
+  const [availableParameters, setAvailableParameters] = React.useState(availableParametersQueryData);
 
   const handleCreateRevision = useCallback(
     async ({ reason = "Update workflow", callback }) => {
@@ -255,6 +239,24 @@ const EditorStateContainer: React.FC<EditorStateContainerProps> = ({
     [revisionDispatch]
   );
 
+  const handleUpdateParams = useCallback(
+    (parameters: Array<DataDrivenInput>) => {
+      revisionDispatch({
+        type: RevisionActionTypes.UpdateConfig,
+        data: { parameters },
+      });
+
+      // Create new available parameters values so user doesn't have to create a
+      // a new version to use newly created parameters
+      const newAvailableParameters = [...availableParameters];
+      newAvailableParameters.push(
+        ...parameters.map((param) => [`workflow.params.${param.key}`, `params.${param.key}`]).flat()
+      );
+      setAvailableParameters(Array.from(new Set(newAvailableParameters)));
+    },
+    [revisionDispatch, availableParameters, setAvailableParameters]
+  );
+
   /**
    *  Simply update the parent state to use a different revision to fetch it w/ react-query
    * @param {string} revisionNumber
@@ -270,15 +272,15 @@ const EditorStateContainer: React.FC<EditorStateContainerProps> = ({
   const store = useMemo(() => {
     const taskTemplatesData = groupTaskTemplatesByName(taskTemplatesList);
     return {
-      availableParametersQueryData,
+      availableParameters,
       mode,
       revisionDispatch,
       revisionState,
       taskTemplatesData,
       workflowsQueryData,
     };
-  }, [availableParametersQueryData, mode, revisionDispatch, revisionState, taskTemplatesList, workflowsQueryData]);
-
+  }, [availableParameters, mode, revisionDispatch, revisionState, taskTemplatesList, workflowsQueryData]);
+  console.log({ availableParameters });
   return (
     // Must create context to share state w/ nodes that are created by the DAG engine
     <EditorContextProvider value={store}>
@@ -314,13 +316,13 @@ const EditorStateContainer: React.FC<EditorStateContainerProps> = ({
               />
             </Route>
             <Route path={AppPath.EditorProperties}>
-              <Parameters workflow={revisionState} />
+              <Parameters workflow={revisionState} handleUpdateParams={handleUpdateParams} />
             </Route>
             <Route path={AppPath.EditorSchedule}>
               <Schedule summaryData={revisionState} />
             </Route>
             <Route path={AppPath.EditorChangelog}>
-              <ChangeLog summaryData={revisionState} />
+              <ChangeLog changeLogData={changeLogData} />
             </Route>
           </Switch>
           <Route
diff --git a/src/Features/Editor/Parameters/Parameters.tsx b/src/Features/Editor/Parameters/Parameters.tsx
index 5e38d3e99..e7777ede7 100644
--- a/src/Features/Editor/Parameters/Parameters.tsx
+++ b/src/Features/Editor/Parameters/Parameters.tsx
@@ -1,18 +1,14 @@
-// @ts-nocheck
 import React from "react";
-import { useMutation, useQueryClient } from "react-query";
 import { Helmet } from "react-helmet";
-import capitalize from "lodash/capitalize";
-import { ConfirmModal, notify, ToastNotification } from "@boomerang-io/carbon-addons-boomerang-react";
+import { ConfirmModal } from "@boomerang-io/carbon-addons-boomerang-react";
 import WorkflowCloseButton from "./WorkflowCloseButton";
 import WorkflowPropertiesModal from "./PropertiesModal";
-import { serviceUrl, resolver } from "Config/servicesConfig";
 import { InputType, WorkflowPropertyUpdateType } from "Constants";
 import { DataDrivenInput, ModalTriggerProps, WorkflowCanvas } from "Types";
 import { stringToPassword } from "Utils/stringHelper";
 import styles from "./Parameters.module.scss";
 
-const formatDefaultValue = ({ type, value }: { type: string | undefined; value: string | undefined }) => {
+const formatDefaultValue = ({ type, value }: { type?: string; value?: string }) => {
   if (!value) {
     return "---";
   } else if (type === InputType.Password) {
@@ -37,8 +33,8 @@ const WorkflowPropertyRow: React.FC<WorkflowPropertyRowProps> = ({ title, value
 };
 
 interface WorkflowPropertyHeaderProps {
-  label: string;
-  description: string | undefined;
+  label?: string;
+  description?: string;
 }
 
 const WorkflowPropertyHeader: React.FC<WorkflowPropertyHeaderProps> = ({ label, description }) => {
@@ -52,12 +48,10 @@ const WorkflowPropertyHeader: React.FC<WorkflowPropertyHeaderProps> = ({ label,
 
 interface ParametersProps {
   workflow: WorkflowCanvas;
+  handleUpdateParams: (parameters: Array<DataDrivenInput>) => void;
 }
 
-const Parameters: React.FC<ParametersProps> = ({ workflow }) => {
-  const queryClient = useQueryClient();
-  const configMutator = useMutation(resolver.patchUpdateWorkflowProperties);
-
+const Parameters: React.FC<ParametersProps> = ({ workflow, handleUpdateParams }) => {
   const handleUpdateProperties = async ({ param, type }: { param: DataDrivenInput; type: string }) => {
     let parameters = [...workflow.config];
     if (type === WorkflowPropertyUpdateType.Update) {
@@ -74,21 +68,7 @@ const Parameters: React.FC<ParametersProps> = ({ workflow }) => {
       parameters.push(param);
     }
 
-    try {
-      //TODO - update the compose object and send back - there is no individual params endpoint
-      const { data } = await configMutator.mutateAsync({ workflowId: workflow.id, body: parameters });
-      queryClient.invalidateQueries(serviceUrl.workflowAvailableParameters({ workflowId: workflow.id }));
-      notify(
-        <ToastNotification
-          kind="success"
-          title={`${capitalize(type)} parameter`}
-          subtitle={`Successfully performed operation`}
-        />
-      );
-      queryClient.setQueryData(serviceUrl.getWorkflowCompose({ id: workflow.id }), data);
-    } catch (e) {
-      notify(<ToastNotification kind="error" title="Something's wrong" subtitle={`Failed to ${type} parameter`} />);
-    }
+    handleUpdateParams(parameters);
   };
 
   const deleteParameter = (param: DataDrivenInput) => {
@@ -134,7 +114,6 @@ const Parameters: React.FC<ParametersProps> = ({ workflow }) => {
               <>
                 <WorkflowPropertiesModal
                   isEdit
-                  isLoading={configMutator.isLoading}
                   propertyKeys={paramKeys.filter((propertyName: string) => propertyName !== configParam.key)}
                   property={configParam}
                   updateWorkflowProperties={handleUpdateProperties}
@@ -164,7 +143,6 @@ const Parameters: React.FC<ParametersProps> = ({ workflow }) => {
         ))}
       <WorkflowPropertiesModal
         isEdit={false}
-        isloading={configMutator.isLoading}
         propertyKeys={paramKeys}
         updateWorkflowProperties={handleUpdateProperties}
       />
diff --git a/src/Features/Editor/Parameters/PropertiesModal/PropertiesModal.tsx b/src/Features/Editor/Parameters/PropertiesModal/PropertiesModal.tsx
index 9c90cae9a..ac23f5ff8 100644
--- a/src/Features/Editor/Parameters/PropertiesModal/PropertiesModal.tsx
+++ b/src/Features/Editor/Parameters/PropertiesModal/PropertiesModal.tsx
@@ -8,10 +8,9 @@ import styles from "./PropertiesModal.module.scss";
 
 interface PropertiesModalProps {
   isEdit: boolean;
-  isLoading: boolean;
   property: DataDrivenInput;
   propertyKeys: Array<string>;
-  updateWorkflowProperties: (args: { property: DataDrivenInput; type: string }) => Promise<any>;
+  updateWorkflowProperties: (args: { param: DataDrivenInput; type: string }) => Promise<any>;
 }
 
 const PropertiesModal: React.FC<PropertiesModalProps> = (props) => {
@@ -32,7 +31,7 @@ const PropertiesModal: React.FC<PropertiesModalProps> = (props) => {
         ) : (
           <button className={styles.createPropertyCard} onClick={openModal} data-testid="create-parameter-button">
             <div className={styles.createContainer}>
-              <Add className={styles.createIcon} aria-label="Add" size={32}/>
+              <Add className={styles.createIcon} aria-label="Add" size={32} />
               <p className={styles.createText}>Create a new parameter</p>
             </div>
           </button>
diff --git a/src/Features/Editor/Parameters/PropertiesModal/PropertiesModalContent/PropertiesModalContent.tsx b/src/Features/Editor/Parameters/PropertiesModal/PropertiesModalContent/PropertiesModalContent.tsx
index 87515ec1c..2ab53ff2c 100644
--- a/src/Features/Editor/Parameters/PropertiesModal/PropertiesModalContent/PropertiesModalContent.tsx
+++ b/src/Features/Editor/Parameters/PropertiesModal/PropertiesModalContent/PropertiesModalContent.tsx
@@ -3,7 +3,6 @@ import React, { Component } from "react";
 import {
   ComboBox,
   Creatable,
-  Loading,
   ModalFlowForm,
   TextArea,
   TextInput,
@@ -41,10 +40,9 @@ const inputTypeItems = [
 interface PropertiesModalContentProps {
   closeModal(): void;
   isEdit: boolean;
-  isLoading: boolean;
   property: DataDrivenInput;
   propertyKeys: string[];
-  updateWorkflowProperties: (args: { property: DataDrivenInput; type: string }) => Promise<any>;
+  updateWorkflowProperties: (args: { param: DataDrivenInput; type: string }) => Promise<any>;
 }
 
 class PropertiesModalContent extends Component<PropertiesModalContentProps> {
@@ -73,25 +71,25 @@ class PropertiesModalContent extends Component<PropertiesModalContentProps> {
   };
 
   handleConfirm = (values: DataDrivenInput) => {
-    let property = clonedeep(values);
-    property.type = property.type.value;
+    let param = clonedeep(values);
+    param.type = param.type.value;
 
     // Remove in case they are present if the user changed their mind
-    if (property.type !== InputType.Select) {
-      delete property.options;
+    if (param.type !== InputType.Select) {
+      delete param.options;
     } else {
       // Create options in correct type for service - { key, value }
-      property.options = property?.options.map((property) => ({ key: property, value: property }));
+      param.options = param?.options.map((param) => ({ key: param, value: param }));
     }
 
-    if (property.type === InputType.Boolean) {
-      if (!property.defaultValue) property.defaultValue = false;
+    if (param.type === InputType.Boolean) {
+      if (!param.defaultValue) param.defaultValue = false;
     }
 
     if (this.props.isEdit) {
       this.props
         .updateWorkflowProperties({
-          property,
+          param,
           type: WorkflowPropertyUpdateType.Update,
         })
         .then(() => {
@@ -101,7 +99,7 @@ class PropertiesModalContent extends Component<PropertiesModalContentProps> {
     } else {
       this.props
         .updateWorkflowProperties({
-          property,
+          param,
           type: WorkflowPropertyUpdateType.Create,
         })
         .then(() => {
@@ -213,7 +211,7 @@ class PropertiesModalContent extends Component<PropertiesModalContentProps> {
   };
 
   render() {
-    const { property, isEdit, propertyKeys, isLoading } = this.props;
+    const { property, isEdit, propertyKeys } = this.props;
     let defaultValueType = this.state.defaultValueType;
 
     return (
@@ -260,9 +258,8 @@ class PropertiesModalContent extends Component<PropertiesModalContentProps> {
           const { dirty, values, touched, errors, handleBlur, handleChange, handleSubmit, setFieldValue, isValid } =
             formikProps;
           return (
-            <ModalFlowForm onSubmit={handleSubmit} disabled={isLoading}>
+            <ModalFlowForm onSubmit={handleSubmit}>
               <ModalBody aria-label="inputs" className={styles.container}>
-                {isLoading && <Loading />}
                 <TextInput
                   readOnly={isEdit}
                   helperText="Reference value for parameter in workflow. It can't be changed after parameter creation."
@@ -336,12 +333,8 @@ class PropertiesModalContent extends Component<PropertiesModalContentProps> {
                 <Button kind="secondary" onClick={this.props.closeModal} type="button">
                   Cancel
                 </Button>
-                <Button
-                  disabled={!isValid || !dirty || isLoading}
-                  type="submit"
-                  data-testid="parameter-modal-confirm-button"
-                >
-                  {isEdit ? (isLoading ? "Saving..." : "Save") : isLoading ? "Creating..." : "Create"}
+                <Button disabled={!isValid || !dirty} type="submit" data-testid="parameter-modal-confirm-button">
+                  {isEdit ? "Save" : "Create"}
                 </Button>
               </ModalFooter>
             </ModalFlowForm>
diff --git a/src/State/reducers/workflowRevision.ts b/src/State/reducers/workflowRevision.ts
index e1ac02cf8..660ef41fd 100644
--- a/src/State/reducers/workflowRevision.ts
+++ b/src/State/reducers/workflowRevision.ts
@@ -4,6 +4,7 @@ import { WorkflowCanvas, WorkflowCanvasState } from "Types";
 export const RevisionActionTypes = {
   UpdateNodes: "UPDATE_NODES",
   UpdateEdges: "UPDATE_EDGES",
+  UpdateConfig: "UPDATE_CONFIG",
   Reset: "RESET",
   Set: "SET",
   UpdateNodeConfig: "UPDATE_NODE_CONFIG",
@@ -13,17 +14,17 @@ export const RevisionActionTypes = {
 
 type RevisionActionType = typeof RevisionActionTypes[keyof typeof RevisionActionTypes];
 
-
 export function revisionReducer(state: WorkflowCanvasState, action: { data: any; type: RevisionActionType }) {
+  console.log({ action });
   switch (action.type) {
     case RevisionActionTypes.UpdateEdges: {
       state.hasUnsavedUpdates = true;
-      state.edges = action.data
+      state.edges = action.data;
       return state;
     }
     case RevisionActionTypes.UpdateNodes: {
       state.hasUnsavedUpdates = true;
-      state.nodes = action.data
+      state.nodes = action.data;
       return state;
     }
     case RevisionActionTypes.UpdateNotes: {
@@ -35,6 +36,11 @@ export function revisionReducer(state: WorkflowCanvasState, action: { data: any;
     case RevisionActionTypes.Set: {
       return action.data;
     }
+    case RevisionActionTypes.UpdateConfig: {
+      const { parameters } = action.data;
+      state.config = parameters;
+      return state;
+    }
     case RevisionActionTypes.Reset: {
       return action.data;
     }
diff --git a/src/Types/index.tsx b/src/Types/index.tsx
index 4975748fb..2485ce885 100644
--- a/src/Types/index.tsx
+++ b/src/Types/index.tsx
@@ -89,6 +89,7 @@ export interface DataDrivenInput {
   type: string;
   min?: number;
   max?: number;
+  jsonPath?: string;
 }
 
 export interface ResultParameter {