You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by gi...@apache.org on 2020/08/13 19:21:14 UTC

[druid] branch master updated: Web console: fix json input (#10271)

This is an automated email from the ASF dual-hosted git repository.

gian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new 748a83c  Web console: fix json input (#10271)
748a83c is described below

commit 748a83cb78832f098cac6ab24c9db6713509d38e
Author: Vadim Ogievetsky <va...@ogievetsky.com>
AuthorDate: Thu Aug 13 12:20:58 2020 -0700

    Web console: fix json input (#10271)
    
    * fix json input
    
    * tidy up
    
    * add error extraction test
---
 .../__snapshots__/auto-form.spec.tsx.snap          | 624 +++------------
 .../src/components/auto-form/auto-form.spec.tsx    |   9 +-
 .../__snapshots__/json-input.spec.tsx.snap         | 264 +++----
 .../src/components/json-input/json-input.scss      |  22 +
 .../src/components/json-input/json-input.spec.tsx  |  24 +-
 .../src/components/json-input/json-input.tsx       | 156 ++--
 .../__snapshots__/compaction-dialog.spec.tsx.snap  | 846 +++------------------
 .../compaction-dialog/compaction-dialog.spec.tsx   |   9 +-
 .../__snapshots__/lookup-edit-dialog.spec.tsx.snap | 829 ++++++++++----------
 .../lookup-edit-dialog/lookup-edit-dialog.spec.tsx |   9 +-
 10 files changed, 929 insertions(+), 1863 deletions(-)

diff --git a/web-console/src/components/auto-form/__snapshots__/auto-form.spec.tsx.snap b/web-console/src/components/auto-form/__snapshots__/auto-form.spec.tsx.snap
index c30d781..d450aeb 100644
--- a/web-console/src/components/auto-form/__snapshots__/auto-form.spec.tsx.snap
+++ b/web-console/src/components/auto-form/__snapshots__/auto-form.spec.tsx.snap
@@ -2,521 +2,135 @@
 
 exports[`auto-form snapshot matches snapshot 1`] = `
 <div
-  class="auto-form"
+  className="auto-form"
 >
-  <div
-    class="bp3-form-group form-group-with-info"
+  <Memo(FormGroupWithInfo)
+    key="testOne"
+    label="Test one"
   >
-    <label
-      class="bp3-label"
-    >
-      Test one
-       
-      <span
-        class="bp3-text-muted"
-      />
-    </label>
-    <div
-      class="bp3-form-content"
-    >
-      <div
-        class="bp3-control-group bp3-fill bp3-numeric-input"
-      >
-        <div
-          class="bp3-input-group"
-        >
-          <input
-            autocomplete="off"
-            class="bp3-input"
-            min="0"
-            placeholder=""
-            style="padding-right: 10px;"
-            type="text"
-            value=""
-          />
-        </div>
-        <div
-          class="bp3-button-group bp3-vertical bp3-fixed"
-        >
-          <button
-            class="bp3-button"
-            type="button"
-          >
-            <span
-              class="bp3-icon bp3-icon-chevron-up"
-              icon="chevron-up"
-            >
-              <svg
-                data-icon="chevron-up"
-                height="16"
-                viewBox="0 0 16 16"
-                width="16"
-              >
-                <desc>
-                  chevron-up
-                </desc>
-                <path
-                  d="M12.71 9.29l-4-4C8.53 5.11 8.28 5 8 5s-.53.11-.71.29l-4 4a1.003 1.003 0 001.42 1.42L8 7.41l3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71z"
-                  fill-rule="evenodd"
-                />
-              </svg>
-            </span>
-          </button>
-          <button
-            class="bp3-button"
-            type="button"
-          >
-            <span
-              class="bp3-icon bp3-icon-chevron-down"
-              icon="chevron-down"
-            >
-              <svg
-                data-icon="chevron-down"
-                height="16"
-                viewBox="0 0 16 16"
-                width="16"
-              >
-                <desc>
-                  chevron-down
-                </desc>
-                <path
-                  d="M12 5c-.28 0-.53.11-.71.29L8 8.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42l4 4c.18.18.43.29.71.29s.53-.11.71-.29l4-4A1.003 1.003 0 0012 5z"
-                  fill-rule="evenodd"
-                />
-              </svg>
-            </span>
-          </button>
-        </div>
-      </div>
-    </div>
-  </div>
-  <div
-    class="bp3-form-group form-group-with-info"
+    <Blueprint3.NumericInput
+      allowNumericCharactersOnly={true}
+      buttonPosition="right"
+      clampValueOnBlur={false}
+      disabled={false}
+      fill={true}
+      large={false}
+      majorStepSize={10}
+      min={0}
+      minorStepSize={0.1}
+      onBlur={[Function]}
+      onValueChange={[Function]}
+      placeholder=""
+      selectAllOnFocus={false}
+      selectAllOnIncrement={false}
+      stepSize={1}
+      value=""
+    />
+  </Memo(FormGroupWithInfo)>
+  <Memo(FormGroupWithInfo)
+    key="testTwo"
+    label="Test two"
   >
-    <label
-      class="bp3-label"
-    >
-      Test two
-       
-      <span
-        class="bp3-text-muted"
-      />
-    </label>
-    <div
-      class="bp3-form-content"
-    >
-      <div
-        class="bp3-control-group bp3-fill bp3-numeric-input"
-      >
-        <div
-          class="bp3-input-group"
-        >
-          <input
-            autocomplete="off"
-            class="bp3-input"
-            min="0"
-            style="padding-right: 10px;"
-            type="text"
-            value=""
-          />
-        </div>
-        <div
-          class="bp3-button-group bp3-vertical bp3-fixed"
-        >
-          <button
-            class="bp3-button"
-            type="button"
-          >
-            <span
-              class="bp3-icon bp3-icon-chevron-up"
-              icon="chevron-up"
-            >
-              <svg
-                data-icon="chevron-up"
-                height="16"
-                viewBox="0 0 16 16"
-                width="16"
-              >
-                <desc>
-                  chevron-up
-                </desc>
-                <path
-                  d="M12.71 9.29l-4-4C8.53 5.11 8.28 5 8 5s-.53.11-.71.29l-4 4a1.003 1.003 0 001.42 1.42L8 7.41l3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71z"
-                  fill-rule="evenodd"
-                />
-              </svg>
-            </span>
-          </button>
-          <button
-            class="bp3-button"
-            type="button"
-          >
-            <span
-              class="bp3-icon bp3-icon-chevron-down"
-              icon="chevron-down"
-            >
-              <svg
-                data-icon="chevron-down"
-                height="16"
-                viewBox="0 0 16 16"
-                width="16"
-              >
-                <desc>
-                  chevron-down
-                </desc>
-                <path
-                  d="M12 5c-.28 0-.53.11-.71.29L8 8.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42l4 4c.18.18.43.29.71.29s.53-.11.71-.29l4-4A1.003 1.003 0 0012 5z"
-                  fill-rule="evenodd"
-                />
-              </svg>
-            </span>
-          </button>
-        </div>
-      </div>
-    </div>
-  </div>
-  <div
-    class="bp3-form-group form-group-with-info"
+    <Blueprint3.NumericInput
+      allowNumericCharactersOnly={true}
+      buttonPosition="right"
+      clampValueOnBlur={false}
+      disabled={false}
+      fill={true}
+      large={false}
+      majorStepSize={1000000}
+      min={0}
+      minorStepSize={0.1}
+      onBlur={[Function]}
+      onValueChange={[Function]}
+      selectAllOnFocus={false}
+      selectAllOnIncrement={false}
+      stepSize={1000}
+      value=""
+    />
+  </Memo(FormGroupWithInfo)>
+  <Memo(FormGroupWithInfo)
+    key="testThree"
+    label="Test three"
   >
-    <label
-      class="bp3-label"
-    >
-      Test three
-       
-      <span
-        class="bp3-text-muted"
-      />
-    </label>
-    <div
-      class="bp3-form-content"
-    >
-      <div
-        class="bp3-input-group suggestible-input"
-      >
-        <input
-          class="bp3-input"
-          placeholder=""
-          style="padding-right: 10px;"
-          type="text"
-          value=""
-        />
-      </div>
-    </div>
-  </div>
-  <div
-    class="bp3-form-group form-group-with-info"
+    <SuggestibleInput
+      disabled={false}
+      onBlur={[Function]}
+      onValueChange={[Function]}
+      placeholder=""
+      value=""
+    />
+  </Memo(FormGroupWithInfo)>
+  <Memo(FormGroupWithInfo)
+    key="testFour"
+    label="Test four"
   >
-    <label
-      class="bp3-label"
-    >
-      Test four
-       
-      <span
-        class="bp3-text-muted"
-      />
-    </label>
-    <div
-      class="bp3-form-content"
-    >
-      <div
-        class="bp3-button-group"
+    <Blueprint3.ButtonGroup>
+      <Blueprint3.Button
+        active={false}
+        disabled={false}
+        onClick={[Function]}
+      >
+        False
+      </Blueprint3.Button>
+      <Blueprint3.Button
+        active={false}
+        disabled={false}
+        onClick={[Function]}
       >
-        <button
-          class="bp3-button"
-          type="button"
-        >
-          <span
-            class="bp3-button-text"
-          >
-            False
-          </span>
-        </button>
-        <button
-          class="bp3-button"
-          type="button"
-        >
-          <span
-            class="bp3-button-text"
-          >
-            True
-          </span>
-        </button>
-      </div>
-    </div>
-  </div>
-  <div
-    class="bp3-form-group form-group-with-info"
+        True
+      </Blueprint3.Button>
+    </Blueprint3.ButtonGroup>
+  </Memo(FormGroupWithInfo)>
+  <Memo(FormGroupWithInfo)
+    key="testFourWithDefault"
+    label="Test four with default"
   >
-    <label
-      class="bp3-label"
-    >
-      Test four with default
-       
-      <span
-        class="bp3-text-muted"
-      />
-    </label>
-    <div
-      class="bp3-form-content"
-    >
-      <div
-        class="bp3-button-group"
+    <Blueprint3.ButtonGroup>
+      <Blueprint3.Button
+        active={true}
+        disabled={false}
+        onClick={[Function]}
       >
-        <button
-          class="bp3-button bp3-active"
-          type="button"
-        >
-          <span
-            class="bp3-button-text"
-          >
-            False
-          </span>
-        </button>
-        <button
-          class="bp3-button"
-          type="button"
-        >
-          <span
-            class="bp3-button-text"
-          >
-            True
-          </span>
-        </button>
-      </div>
-    </div>
-  </div>
-  <div
-    class="bp3-form-group form-group-with-info"
+        False
+      </Blueprint3.Button>
+      <Blueprint3.Button
+        active={false}
+        disabled={false}
+        onClick={[Function]}
+      >
+        True
+      </Blueprint3.Button>
+    </Blueprint3.ButtonGroup>
+  </Memo(FormGroupWithInfo)>
+  <Memo(FormGroupWithInfo)
+    key="testFive"
+    label="Test five"
   >
-    <label
-      class="bp3-label"
-    >
-      Test five
-       
-      <span
-        class="bp3-text-muted"
-      />
-    </label>
-    <div
-      class="bp3-form-content"
-    >
-      <textarea
-        class="bp3-input bp3-fill"
-        placeholder=""
-      />
-    </div>
-  </div>
-  <div
-    class="bp3-form-group form-group-with-info"
+    <Memo(ArrayInput)
+      disabled={false}
+      onChange={[Function]}
+      placeholder=""
+      values={Array []}
+    />
+  </Memo(FormGroupWithInfo)>
+  <Memo(FormGroupWithInfo)
+    key="testSix"
+    label="Test six"
   >
-    <label
-      class="bp3-label"
-    >
-      Test six
-       
-      <span
-        class="bp3-text-muted"
-      />
-    </label>
-    <div
-      class="bp3-form-content"
-    >
-      <div
-        class=" ace_editor ace-tm json-input"
-        id="brace-editor"
-        style="width: 100%; height: 8vh;"
-      >
-        <textarea
-          autocapitalize="off"
-          autocorrect="off"
-          class="ace_text-input"
-          spellcheck="false"
-          style="opacity: 0;"
-          wrap="off"
-        />
-        <div
-          aria-hidden="true"
-          class="ace_gutter"
-          style="display: none;"
-        >
-          <div
-            class="ace_layer ace_gutter-layer ace_folding-enabled"
-          />
-          <div
-            class="ace_gutter-active-line"
-          />
-        </div>
-        <div
-          class="ace_scroller"
-        >
-          <div
-            class="ace_content"
-          >
-            <div
-              class="ace_layer ace_print-margin-layer"
-            >
-              <div
-                class="ace_print-margin"
-                style="left: 4px; visibility: hidden;"
-              />
-            </div>
-            <div
-              class="ace_layer ace_marker-layer"
-            />
-            <div
-              class="ace_layer ace_text-layer"
-              style="padding: 0px 4px;"
-            />
-            <div
-              class="ace_layer ace_marker-layer"
-            />
-            <div
-              class="ace_layer ace_cursor-layer ace_hidden-cursors"
-            >
-              <div
-                class="ace_cursor"
-              />
-            </div>
-          </div>
-        </div>
-        <div
-          class="ace_scrollbar ace_scrollbar-v"
-          style="display: none; width: 20px;"
-        >
-          <div
-            class="ace_scrollbar-inner"
-            style="width: 20px;"
-          />
-        </div>
-        <div
-          class="ace_scrollbar ace_scrollbar-h"
-          style="display: none; height: 20px;"
-        >
-          <div
-            class="ace_scrollbar-inner"
-            style="height: 20px;"
-          />
-        </div>
-        <div
-          style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
-        >
-          <div
-            style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-          />
-          <div
-            style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-          >
-            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-  <div
-    class="bp3-form-group form-group-with-info"
+    <Memo(JsonInput)
+      onChange={[Function]}
+      placeholder=""
+    />
+  </Memo(FormGroupWithInfo)>
+  <Memo(FormGroupWithInfo)
+    key="testSeven"
+    label="Test seven"
   >
-    <label
-      class="bp3-label"
-    >
-      Test seven
-       
-      <span
-        class="bp3-text-muted"
-      />
-    </label>
-    <div
-      class="bp3-form-content"
-    >
-      <div
-        class=" ace_editor ace-tm json-input"
-        id="brace-editor"
-        style="width: 100%; height: 8vh;"
-      >
-        <textarea
-          autocapitalize="off"
-          autocorrect="off"
-          class="ace_text-input"
-          spellcheck="false"
-          style="opacity: 0;"
-          wrap="off"
-        />
-        <div
-          aria-hidden="true"
-          class="ace_gutter"
-          style="display: none;"
-        >
-          <div
-            class="ace_layer ace_gutter-layer ace_folding-enabled"
-          />
-          <div
-            class="ace_gutter-active-line"
-          />
-        </div>
-        <div
-          class="ace_scroller"
-        >
-          <div
-            class="ace_content"
-          >
-            <div
-              class="ace_layer ace_print-margin-layer"
-            >
-              <div
-                class="ace_print-margin"
-                style="left: 4px; visibility: hidden;"
-              />
-            </div>
-            <div
-              class="ace_layer ace_marker-layer"
-            />
-            <div
-              class="ace_layer ace_text-layer"
-              style="padding: 0px 4px;"
-            />
-            <div
-              class="ace_layer ace_marker-layer"
-            />
-            <div
-              class="ace_layer ace_cursor-layer ace_hidden-cursors"
-            >
-              <div
-                class="ace_cursor"
-              />
-            </div>
-          </div>
-        </div>
-        <div
-          class="ace_scrollbar ace_scrollbar-v"
-          style="display: none; width: 20px;"
-        >
-          <div
-            class="ace_scrollbar-inner"
-            style="width: 20px;"
-          />
-        </div>
-        <div
-          class="ace_scrollbar ace_scrollbar-h"
-          style="display: none; height: 20px;"
-        >
-          <div
-            class="ace_scrollbar-inner"
-            style="height: 20px;"
-          />
-        </div>
-        <div
-          style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
-        >
-          <div
-            style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-          />
-          <div
-            style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-          >
-            XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
+    <Memo(JsonInput)
+      onChange={[Function]}
+      placeholder=""
+    />
+  </Memo(FormGroupWithInfo)>
 </div>
 `;
diff --git a/web-console/src/components/auto-form/auto-form.spec.tsx b/web-console/src/components/auto-form/auto-form.spec.tsx
index 06a5839..89bd645 100644
--- a/web-console/src/components/auto-form/auto-form.spec.tsx
+++ b/web-console/src/components/auto-form/auto-form.spec.tsx
@@ -16,14 +16,14 @@
  * limitations under the License.
  */
 
-import { render } from '@testing-library/react';
+import { shallow } from 'enzyme';
 import React from 'react';
 
 import { AutoForm } from './auto-form';
 
 describe('auto-form snapshot', () => {
   it('matches snapshot', () => {
-    const autoForm = (
+    const autoForm = shallow(
       <AutoForm
         fields={[
           { name: 'testOne', type: 'number' },
@@ -37,9 +37,8 @@ describe('auto-form snapshot', () => {
         ]}
         model={String}
         onChange={() => {}}
-      />
+      />,
     );
-    const { container } = render(autoForm);
-    expect(container.firstChild).toMatchSnapshot();
+    expect(autoForm).toMatchSnapshot();
   });
 });
diff --git a/web-console/src/components/json-input/__snapshots__/json-input.spec.tsx.snap b/web-console/src/components/json-input/__snapshots__/json-input.spec.tsx.snap
index 3c94735..21590d3 100644
--- a/web-console/src/components/json-input/__snapshots__/json-input.spec.tsx.snap
+++ b/web-console/src/components/json-input/__snapshots__/json-input.spec.tsx.snap
@@ -2,184 +2,192 @@
 
 exports[`json input matches snapshot (null) 1`] = `
 <div
-  class=" ace_editor ace-tm json-input"
-  id="brace-editor"
-  style="width: 100%; height: 8vh;"
+  class="json-input"
 >
-  <textarea
-    autocapitalize="off"
-    autocorrect="off"
-    class="ace_text-input"
-    spellcheck="false"
-    style="opacity: 0;"
-    wrap="off"
-  />
   <div
-    aria-hidden="true"
-    class="ace_gutter"
-    style="display: none;"
+    class=" ace_editor ace-tm"
+    id="brace-editor"
+    style="width: 100%; height: 8vh;"
   >
-    <div
-      class="ace_layer ace_gutter-layer ace_folding-enabled"
+    <textarea
+      autocapitalize="off"
+      autocorrect="off"
+      class="ace_text-input"
+      spellcheck="false"
+      style="opacity: 0;"
+      wrap="off"
     />
     <div
-      class="ace_gutter-active-line"
-    />
-  </div>
-  <div
-    class="ace_scroller"
-  >
+      aria-hidden="true"
+      class="ace_gutter"
+      style="display: none;"
+    >
+      <div
+        class="ace_layer ace_gutter-layer ace_folding-enabled"
+      />
+      <div
+        class="ace_gutter-active-line"
+      />
+    </div>
     <div
-      class="ace_content"
+      class="ace_scroller"
     >
       <div
-        class="ace_layer ace_print-margin-layer"
+        class="ace_content"
       >
         <div
-          class="ace_print-margin"
-          style="left: 4px; visibility: hidden;"
+          class="ace_layer ace_print-margin-layer"
+        >
+          <div
+            class="ace_print-margin"
+            style="left: 4px; visibility: hidden;"
+          />
+        </div>
+        <div
+          class="ace_layer ace_marker-layer"
         />
+        <div
+          class="ace_layer ace_text-layer"
+          style="padding: 0px 4px;"
+        />
+        <div
+          class="ace_layer ace_marker-layer"
+        />
+        <div
+          class="ace_layer ace_cursor-layer ace_hidden-cursors"
+        >
+          <div
+            class="ace_cursor"
+          />
+        </div>
       </div>
+    </div>
+    <div
+      class="ace_scrollbar ace_scrollbar-v"
+      style="display: none; width: 20px;"
+    >
       <div
-        class="ace_layer ace_marker-layer"
+        class="ace_scrollbar-inner"
+        style="width: 20px;"
       />
+    </div>
+    <div
+      class="ace_scrollbar ace_scrollbar-h"
+      style="display: none; height: 20px;"
+    >
       <div
-        class="ace_layer ace_text-layer"
-        style="padding: 0px 4px;"
+        class="ace_scrollbar-inner"
+        style="height: 20px;"
       />
+    </div>
+    <div
+      style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
+    >
       <div
-        class="ace_layer ace_marker-layer"
+        style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
       />
       <div
-        class="ace_layer ace_cursor-layer ace_hidden-cursors"
+        style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
       >
-        <div
-          class="ace_cursor"
-        />
+        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
       </div>
     </div>
   </div>
-  <div
-    class="ace_scrollbar ace_scrollbar-v"
-    style="display: none; width: 20px;"
-  >
-    <div
-      class="ace_scrollbar-inner"
-      style="width: 20px;"
-    />
-  </div>
-  <div
-    class="ace_scrollbar ace_scrollbar-h"
-    style="display: none; height: 20px;"
-  >
-    <div
-      class="ace_scrollbar-inner"
-      style="height: 20px;"
-    />
-  </div>
-  <div
-    style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
-  >
-    <div
-      style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-    />
-    <div
-      style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-    >
-      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-    </div>
-  </div>
 </div>
 `;
 
 exports[`json input matches snapshot (value) 1`] = `
 <div
-  class=" ace_editor ace-tm json-input"
-  id="brace-editor"
-  style="width: 100%; height: 8vh;"
+  class="json-input"
 >
-  <textarea
-    autocapitalize="off"
-    autocorrect="off"
-    class="ace_text-input"
-    spellcheck="false"
-    style="opacity: 0;"
-    wrap="off"
-  />
   <div
-    aria-hidden="true"
-    class="ace_gutter"
-    style="display: none;"
+    class=" ace_editor ace-tm"
+    id="brace-editor"
+    style="width: 100%; height: 8vh;"
   >
-    <div
-      class="ace_layer ace_gutter-layer ace_folding-enabled"
+    <textarea
+      autocapitalize="off"
+      autocorrect="off"
+      class="ace_text-input"
+      spellcheck="false"
+      style="opacity: 0;"
+      wrap="off"
     />
     <div
-      class="ace_gutter-active-line"
-    />
-  </div>
-  <div
-    class="ace_scroller"
-  >
+      aria-hidden="true"
+      class="ace_gutter"
+      style="display: none;"
+    >
+      <div
+        class="ace_layer ace_gutter-layer ace_folding-enabled"
+      />
+      <div
+        class="ace_gutter-active-line"
+      />
+    </div>
     <div
-      class="ace_content"
+      class="ace_scroller"
     >
       <div
-        class="ace_layer ace_print-margin-layer"
+        class="ace_content"
       >
         <div
-          class="ace_print-margin"
-          style="left: 4px; visibility: hidden;"
+          class="ace_layer ace_print-margin-layer"
+        >
+          <div
+            class="ace_print-margin"
+            style="left: 4px; visibility: hidden;"
+          />
+        </div>
+        <div
+          class="ace_layer ace_marker-layer"
         />
+        <div
+          class="ace_layer ace_text-layer"
+          style="padding: 0px 4px;"
+        />
+        <div
+          class="ace_layer ace_marker-layer"
+        />
+        <div
+          class="ace_layer ace_cursor-layer ace_hidden-cursors"
+        >
+          <div
+            class="ace_cursor"
+          />
+        </div>
       </div>
+    </div>
+    <div
+      class="ace_scrollbar ace_scrollbar-v"
+      style="display: none; width: 20px;"
+    >
       <div
-        class="ace_layer ace_marker-layer"
+        class="ace_scrollbar-inner"
+        style="width: 20px;"
       />
+    </div>
+    <div
+      class="ace_scrollbar ace_scrollbar-h"
+      style="display: none; height: 20px;"
+    >
       <div
-        class="ace_layer ace_text-layer"
-        style="padding: 0px 4px;"
+        class="ace_scrollbar-inner"
+        style="height: 20px;"
       />
+    </div>
+    <div
+      style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
+    >
       <div
-        class="ace_layer ace_marker-layer"
+        style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
       />
       <div
-        class="ace_layer ace_cursor-layer ace_hidden-cursors"
+        style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
       >
-        <div
-          class="ace_cursor"
-        />
+        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
       </div>
     </div>
   </div>
-  <div
-    class="ace_scrollbar ace_scrollbar-v"
-    style="display: none; width: 20px;"
-  >
-    <div
-      class="ace_scrollbar-inner"
-      style="width: 20px;"
-    />
-  </div>
-  <div
-    class="ace_scrollbar ace_scrollbar-h"
-    style="display: none; height: 20px;"
-  >
-    <div
-      class="ace_scrollbar-inner"
-      style="height: 20px;"
-    />
-  </div>
-  <div
-    style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
-  >
-    <div
-      style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-    />
-    <div
-      style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-    >
-      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-    </div>
-  </div>
 </div>
 `;
diff --git a/web-console/src/components/json-input/json-input.scss b/web-console/src/components/json-input/json-input.scss
index 1580c61c5..26b0050 100644
--- a/web-console/src/components/json-input/json-input.scss
+++ b/web-console/src/components/json-input/json-input.scss
@@ -17,6 +17,9 @@
  */
 
 .json-input {
+  height: 100%;
+  position: relative;
+
   &.invalid::after {
     content: '';
     position: absolute;
@@ -26,5 +29,24 @@
     right: 0;
     border: 1px solid #ff4852;
     pointer-events: none;
+    z-index: 10;
+  }
+
+  .json-error {
+    position: absolute;
+    bottom: 1px;
+    left: 1px;
+    max-width: 80%;
+    max-height: 100px;
+    background: rgba(121, 44, 44, 0.8);
+    padding: 3px 7px;
+    z-index: 10;
+    white-space: pre-wrap;
+    cursor: pointer;
+    overflow: hidden;
+
+    &:hover {
+      background: rgba(121, 44, 44, 1);
+    }
   }
 }
diff --git a/web-console/src/components/json-input/json-input.spec.tsx b/web-console/src/components/json-input/json-input.spec.tsx
index 411d2a5..6af8876 100644
--- a/web-console/src/components/json-input/json-input.spec.tsx
+++ b/web-console/src/components/json-input/json-input.spec.tsx
@@ -17,9 +17,10 @@
  */
 
 import { render } from '@testing-library/react';
+import Hjson from 'hjson';
 import React from 'react';
 
-import { JsonInput } from './json-input';
+import { extractRowColumnFromHjsonError, JsonInput } from './json-input';
 
 describe('json input', () => {
   it('matches snapshot (null)', () => {
@@ -36,4 +37,25 @@ describe('json input', () => {
     const { container } = render(jsonCollapse);
     expect(container.firstChild).toMatchSnapshot();
   });
+
+  it('extractRowColumnFromHjsonError is ok with non matching error', () => {
+    expect(extractRowColumnFromHjsonError(new Error('blah blah'))).toBeUndefined();
+  });
+
+  it('extractRowColumnFromHjsonError works with real error', () => {
+    let error: Error | undefined;
+    try {
+      Hjson.parse(`{\n"Hello" "World"\n}`);
+    } catch (e) {
+      error = e;
+    }
+
+    expect(error).toBeDefined();
+
+    const rc = extractRowColumnFromHjsonError(error!);
+    expect(rc).toEqual({
+      column: 8,
+      row: 1,
+    });
+  });
 });
diff --git a/web-console/src/components/json-input/json-input.tsx b/web-console/src/components/json-input/json-input.tsx
index 3cbfd38..f1dd512 100644
--- a/web-console/src/components/json-input/json-input.tsx
+++ b/web-console/src/components/json-input/json-input.tsx
@@ -16,9 +16,10 @@
  * limitations under the License.
  */
 
-import classNames = require('classnames');
+import { Editor } from 'brace';
+import classNames from 'classnames';
 import Hjson from 'hjson';
-import React, { useState } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
 import AceEditor from 'react-ace';
 
 import './json-input.scss';
@@ -29,6 +30,18 @@ function parseHjson(str: string) {
   return Hjson.parse(str);
 }
 
+export function extractRowColumnFromHjsonError(
+  error: Error,
+): { row: number; column: number } | undefined {
+  // Message would be something like:
+  // `Found '}' where a key name was expected at line 26,7`
+  // Use this to extract the row and column (subtract 1) and jump the cursor to the right place on click
+  const m = error.message.match(/line (\d+),(\d+)/);
+  if (!m) return;
+
+  return { row: Number(m[1]) - 1, column: Number(m[2]) - 1 };
+}
+
 function stringifyJson(item: any): string {
   if (item != null) {
     return JSON.stringify(item, null, 2);
@@ -37,6 +50,17 @@ function stringifyJson(item: any): string {
   }
 }
 
+// Not the best way to check for deep equality but good enough for what we need
+function deepEqual(a: any, b: any): boolean {
+  return JSON.stringify(a) === JSON.stringify(b);
+}
+
+interface InternalValue {
+  value?: any;
+  error?: Error;
+  stringified: string;
+}
+
 interface JsonInputProps {
   value: any;
   onChange: (value: any) => void;
@@ -48,52 +72,90 @@ interface JsonInputProps {
 
 export const JsonInput = React.memo(function JsonInput(props: JsonInputProps) {
   const { onChange, placeholder, focus, width, height, value } = props;
-  const stringifiedValue = stringifyJson(value);
-  const [stringValue, setStringValue] = useState(stringifiedValue);
-  const [blurred, setBlurred] = useState(false);
-
-  let parsedValue: any;
-  try {
-    parsedValue = parseHjson(stringValue);
-  } catch {}
-  if (typeof parsedValue !== 'object') parsedValue = undefined;
-
-  if (parsedValue !== undefined && stringifyJson(parsedValue) !== stringifiedValue) {
-    setStringValue(stringifiedValue);
-  }
+  const [internalValue, setInternalValue] = useState<InternalValue>(() => ({
+    value,
+    stringified: stringifyJson(value),
+  }));
+  const [showErrorIfNeeded, setShowErrorIfNeeded] = useState(false);
+  const aceEditor = useRef<Editor | undefined>();
+
+  useEffect(() => {
+    if (!deepEqual(value, internalValue.value)) {
+      setInternalValue({
+        value,
+        stringified: stringifyJson(value),
+      });
+    }
+  }, [value]);
 
+  const internalValueError = internalValue.error;
   return (
-    <AceEditor
-      className={classNames('json-input', { invalid: parsedValue === undefined && blurred })}
-      mode="hjson"
-      theme="solarized_dark"
-      onChange={(inputJson: string) => {
-        try {
-          const value = parseHjson(inputJson);
-          onChange(value);
-        } catch {}
-        setStringValue(inputJson);
-      }}
-      onFocus={() => setBlurred(false)}
-      onBlur={() => setBlurred(true)}
-      focus={focus}
-      fontSize={12}
-      width={width || '100%'}
-      height={height || '8vh'}
-      showPrintMargin={false}
-      showGutter={false}
-      value={stringValue}
-      placeholder={placeholder}
-      editorProps={{
-        $blockScrolling: Infinity,
-      }}
-      setOptions={{
-        enableBasicAutocompletion: false,
-        enableLiveAutocompletion: false,
-        showLineNumbers: false,
-        tabSize: 2,
-      }}
-      style={{}}
-    />
+    <div className={classNames('json-input', { invalid: showErrorIfNeeded && internalValueError })}>
+      <AceEditor
+        mode="hjson"
+        theme="solarized_dark"
+        onChange={(inputJson: string) => {
+          let value: any;
+          let error: Error | undefined;
+          try {
+            value = parseHjson(inputJson);
+          } catch (e) {
+            error = e;
+          }
+
+          setInternalValue({
+            value,
+            error,
+            stringified: inputJson,
+          });
+
+          if (!error) {
+            onChange(value);
+          }
+
+          if (showErrorIfNeeded) {
+            setShowErrorIfNeeded(false);
+          }
+        }}
+        onBlur={() => setShowErrorIfNeeded(true)}
+        focus={focus}
+        fontSize={12}
+        width={width || '100%'}
+        height={height || '8vh'}
+        showPrintMargin={false}
+        showGutter={false}
+        value={internalValue.stringified}
+        placeholder={placeholder}
+        editorProps={{
+          $blockScrolling: Infinity,
+        }}
+        setOptions={{
+          enableBasicAutocompletion: false,
+          enableLiveAutocompletion: false,
+          showLineNumbers: false,
+          tabSize: 2,
+        }}
+        style={{}}
+        onLoad={(editor: any) => {
+          aceEditor.current = editor;
+        }}
+      />
+      {showErrorIfNeeded && internalValueError && (
+        <div
+          className="json-error"
+          onClick={() => {
+            if (!aceEditor.current || !internalValueError) return;
+
+            const rc = extractRowColumnFromHjsonError(internalValueError);
+            if (!rc) return;
+
+            aceEditor.current.getSelection().moveCursorTo(rc.row, rc.column);
+            aceEditor.current.focus(); // Grab the focus also
+          }}
+        >
+          {internalValueError.message}
+        </div>
+      )}
+    </div>
   );
 });
diff --git a/web-console/src/dialogs/compaction-dialog/__snapshots__/compaction-dialog.spec.tsx.snap b/web-console/src/dialogs/compaction-dialog/__snapshots__/compaction-dialog.spec.tsx.snap
index e502e4a..f3b66e8 100644
--- a/web-console/src/dialogs/compaction-dialog/__snapshots__/compaction-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/compaction-dialog/__snapshots__/compaction-dialog.spec.tsx.snap
@@ -1,766 +1,102 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`compaction dialog matches snapshot 1`] = `
-<div
-  class="bp3-portal"
+<Blueprint3.Dialog
+  canOutsideClickClose={false}
+  className="compaction-dialog"
+  isOpen={true}
+  onClose={[Function]}
+  title="Compaction config: test"
 >
-  <div
-    class="bp3-overlay bp3-overlay-open bp3-overlay-scroll-container"
-  >
-    <div
-      class="bp3-overlay-backdrop bp3-overlay-appear bp3-overlay-appear-active"
-    />
-    <div
-      class="bp3-dialog-container bp3-overlay-content bp3-overlay-appear bp3-overlay-appear-active"
-      tabindex="0"
-    >
-      <div
-        class="bp3-dialog compaction-dialog"
-      >
-        <div
-          class="bp3-dialog-header"
-        >
-          <h4
-            class="bp3-heading"
-          >
-            Compaction config: test
-          </h4>
-          <button
-            aria-label="Close"
-            class="bp3-button bp3-minimal bp3-dialog-close-button"
-            type="button"
-          >
-            <span
-              class="bp3-icon bp3-icon-small-cross"
-              icon="small-cross"
-            >
-              <svg
-                data-icon="small-cross"
-                height="20"
-                viewBox="0 0 20 20"
-                width="20"
-              >
-                <desc>
-                  small-cross
-                </desc>
-                <path
-                  d="M11.41 10l3.29-3.29c.19-.18.3-.43.3-.71a1.003 1.003 0 00-1.71-.71L10 8.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42L8.59 10 5.3 13.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71l3.29-3.3 3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71L11.41 10z"
-                  fill-rule="evenodd"
-                />
-              </svg>
-            </span>
-          </button>
-        </div>
-        <div
-          class="auto-form"
-        >
-          <div
-            class="bp3-form-group form-group-with-info"
-          >
-            <label
-              class="bp3-label"
-            >
-              Input segment size bytes
-               
-              <span
-                class="bp3-text-muted"
-              >
-                <span
-                  class="bp3-popover-wrapper"
-                >
-                  <span
-                    class="bp3-popover-target"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-info-sign"
-                      icon="info-sign"
-                    >
-                      <svg
-                        data-icon="info-sign"
-                        height="14"
-                        viewBox="0 0 16 16"
-                        width="14"
-                      >
-                        <desc>
-                          info-sign
-                        </desc>
-                        <path
-                          d="M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zM7 3h2v2H7V3zm3 10H6v-1h1V7H6V6h3v6h1v1z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </span>
-                </span>
-              </span>
-            </label>
-            <div
-              class="bp3-form-content"
-            >
-              <div
-                class="bp3-control-group bp3-fill bp3-numeric-input"
-              >
-                <div
-                  class="bp3-input-group"
-                >
-                  <input
-                    autocomplete="off"
-                    class="bp3-input"
-                    min="0"
-                    placeholder=""
-                    style="padding-right: 10px;"
-                    type="text"
-                    value="419430400"
-                  />
-                </div>
-                <div
-                  class="bp3-button-group bp3-vertical bp3-fixed"
-                >
-                  <button
-                    class="bp3-button"
-                    type="button"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-chevron-up"
-                      icon="chevron-up"
-                    >
-                      <svg
-                        data-icon="chevron-up"
-                        height="16"
-                        viewBox="0 0 16 16"
-                        width="16"
-                      >
-                        <desc>
-                          chevron-up
-                        </desc>
-                        <path
-                          d="M12.71 9.29l-4-4C8.53 5.11 8.28 5 8 5s-.53.11-.71.29l-4 4a1.003 1.003 0 001.42 1.42L8 7.41l3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </button>
-                  <button
-                    class="bp3-button"
-                    type="button"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-chevron-down"
-                      icon="chevron-down"
-                    >
-                      <svg
-                        data-icon="chevron-down"
-                        height="16"
-                        viewBox="0 0 16 16"
-                        width="16"
-                      >
-                        <desc>
-                          chevron-down
-                        </desc>
-                        <path
-                          d="M12 5c-.28 0-.53.11-.71.29L8 8.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42l4 4c.18.18.43.29.71.29s.53-.11.71-.29l4-4A1.003 1.003 0 0012 5z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </button>
-                </div>
-              </div>
-            </div>
-          </div>
-          <div
-            class="bp3-form-group form-group-with-info"
-          >
-            <label
-              class="bp3-label"
-            >
-              Skip offset from latest
-               
-              <span
-                class="bp3-text-muted"
-              >
-                <span
-                  class="bp3-popover-wrapper"
-                >
-                  <span
-                    class="bp3-popover-target"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-info-sign"
-                      icon="info-sign"
-                    >
-                      <svg
-                        data-icon="info-sign"
-                        height="14"
-                        viewBox="0 0 16 16"
-                        width="14"
-                      >
-                        <desc>
-                          info-sign
-                        </desc>
-                        <path
-                          d="M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zM7 3h2v2H7V3zm3 10H6v-1h1V7H6V6h3v6h1v1z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </span>
-                </span>
-              </span>
-            </label>
-            <div
-              class="bp3-form-content"
-            >
-              <div
-                class="bp3-input-group suggestible-input"
-              >
-                <input
-                  class="bp3-input"
-                  placeholder=""
-                  style="padding-right: 10px;"
-                  type="text"
-                  value="P1D"
-                />
-              </div>
-            </div>
-          </div>
-          <div
-            class="bp3-form-group form-group-with-info"
-          >
-            <label
-              class="bp3-label"
-            >
-              Max rows per segment
-               
-              <span
-                class="bp3-text-muted"
-              >
-                <span
-                  class="bp3-popover-wrapper"
-                >
-                  <span
-                    class="bp3-popover-target"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-info-sign"
-                      icon="info-sign"
-                    >
-                      <svg
-                        data-icon="info-sign"
-                        height="14"
-                        viewBox="0 0 16 16"
-                        width="14"
-                      >
-                        <desc>
-                          info-sign
-                        </desc>
-                        <path
-                          d="M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zM7 3h2v2H7V3zm3 10H6v-1h1V7H6V6h3v6h1v1z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </span>
-                </span>
-              </span>
-            </label>
-            <div
-              class="bp3-form-content"
-            >
-              <div
-                class="bp3-control-group bp3-fill bp3-numeric-input"
-              >
-                <div
-                  class="bp3-input-group"
-                >
-                  <input
-                    autocomplete="off"
-                    class="bp3-input"
-                    min="0"
-                    placeholder=""
-                    style="padding-right: 10px;"
-                    type="text"
-                    value="5000000"
-                  />
-                </div>
-                <div
-                  class="bp3-button-group bp3-vertical bp3-fixed"
-                >
-                  <button
-                    class="bp3-button"
-                    type="button"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-chevron-up"
-                      icon="chevron-up"
-                    >
-                      <svg
-                        data-icon="chevron-up"
-                        height="16"
-                        viewBox="0 0 16 16"
-                        width="16"
-                      >
-                        <desc>
-                          chevron-up
-                        </desc>
-                        <path
-                          d="M12.71 9.29l-4-4C8.53 5.11 8.28 5 8 5s-.53.11-.71.29l-4 4a1.003 1.003 0 001.42 1.42L8 7.41l3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </button>
-                  <button
-                    class="bp3-button"
-                    type="button"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-chevron-down"
-                      icon="chevron-down"
-                    >
-                      <svg
-                        data-icon="chevron-down"
-                        height="16"
-                        viewBox="0 0 16 16"
-                        width="16"
-                      >
-                        <desc>
-                          chevron-down
-                        </desc>
-                        <path
-                          d="M12 5c-.28 0-.53.11-.71.29L8 8.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42l4 4c.18.18.43.29.71.29s.53-.11.71-.29l4-4A1.003 1.003 0 0012 5z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </button>
-                </div>
-              </div>
-            </div>
-          </div>
-          <div
-            class="bp3-form-group form-group-with-info"
-          >
-            <label
-              class="bp3-label"
+  <AutoForm
+    fields={
+      Array [
+        Object {
+          "defaultValue": 419430400,
+          "info": <p>
+            Maximum number of total segment bytes processed per compaction task. Since a time chunk must be processed in its entirety, if the segments for a particular time chunk have a total size in bytes greater than this parameter, compaction will not run for that time chunk. Because each compaction task runs with a single thread, setting this value too far above 1–2GB will result in compaction tasks taking an excessive amount of time.
+          </p>,
+          "name": "inputSegmentSizeBytes",
+          "type": "number",
+        },
+        Object {
+          "defaultValue": "P1D",
+          "info": <p>
+            The offset for searching segments to be compacted. Strongly recommended to set for realtime dataSources.
+          </p>,
+          "name": "skipOffsetFromLatest",
+          "type": "string",
+        },
+        Object {
+          "defaultValue": 5000000,
+          "info": <p>
+            Determines how many rows are in each segment.
+          </p>,
+          "name": "maxRowsPerSegment",
+          "type": "number",
+        },
+        Object {
+          "info": <p>
+            <Memo(ExternalLink)
+              href="https://druid.apache.org/docs/0.19.0/ingestion/tasks.html#task-context"
             >
               Task context
-               
-              <span
-                class="bp3-text-muted"
-              >
-                <span
-                  class="bp3-popover-wrapper"
-                >
-                  <span
-                    class="bp3-popover-target"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-info-sign"
-                      icon="info-sign"
-                    >
-                      <svg
-                        data-icon="info-sign"
-                        height="14"
-                        viewBox="0 0 16 16"
-                        width="14"
-                      >
-                        <desc>
-                          info-sign
-                        </desc>
-                        <path
-                          d="M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zM7 3h2v2H7V3zm3 10H6v-1h1V7H6V6h3v6h1v1z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </span>
-                </span>
-              </span>
-            </label>
-            <div
-              class="bp3-form-content"
-            >
-              <div
-                class=" ace_editor ace-tm json-input"
-                id="brace-editor"
-                style="width: 100%; height: 8vh;"
-              >
-                <textarea
-                  autocapitalize="off"
-                  autocorrect="off"
-                  class="ace_text-input"
-                  spellcheck="false"
-                  style="opacity: 0;"
-                  wrap="off"
-                />
-                <div
-                  aria-hidden="true"
-                  class="ace_gutter"
-                  style="display: none;"
-                >
-                  <div
-                    class="ace_layer ace_gutter-layer ace_folding-enabled"
-                  />
-                  <div
-                    class="ace_gutter-active-line"
-                  />
-                </div>
-                <div
-                  class="ace_scroller"
-                >
-                  <div
-                    class="ace_content"
-                  >
-                    <div
-                      class="ace_layer ace_print-margin-layer"
-                    >
-                      <div
-                        class="ace_print-margin"
-                        style="left: 4px; visibility: hidden;"
-                      />
-                    </div>
-                    <div
-                      class="ace_layer ace_marker-layer"
-                    />
-                    <div
-                      class="ace_layer ace_text-layer"
-                      style="padding: 0px 4px;"
-                    />
-                    <div
-                      class="ace_layer ace_marker-layer"
-                    />
-                    <div
-                      class="ace_layer ace_cursor-layer ace_hidden-cursors"
-                    >
-                      <div
-                        class="ace_cursor"
-                      />
-                    </div>
-                  </div>
-                </div>
-                <div
-                  class="ace_scrollbar ace_scrollbar-v"
-                  style="display: none; width: 20px;"
-                >
-                  <div
-                    class="ace_scrollbar-inner"
-                    style="width: 20px;"
-                  />
-                </div>
-                <div
-                  class="ace_scrollbar ace_scrollbar-h"
-                  style="display: none; height: 20px;"
-                >
-                  <div
-                    class="ace_scrollbar-inner"
-                    style="height: 20px;"
-                  />
-                </div>
-                <div
-                  style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
-                >
-                  <div
-                    style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-                  />
-                  <div
-                    style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-                  >
-                    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-          <div
-            class="bp3-form-group form-group-with-info"
-          >
-            <label
-              class="bp3-label"
-            >
-              Task priority
-               
-              <span
-                class="bp3-text-muted"
-              >
-                <span
-                  class="bp3-popover-wrapper"
-                >
-                  <span
-                    class="bp3-popover-target"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-info-sign"
-                      icon="info-sign"
-                    >
-                      <svg
-                        data-icon="info-sign"
-                        height="14"
-                        viewBox="0 0 16 16"
-                        width="14"
-                      >
-                        <desc>
-                          info-sign
-                        </desc>
-                        <path
-                          d="M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zM7 3h2v2H7V3zm3 10H6v-1h1V7H6V6h3v6h1v1z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </span>
-                </span>
-              </span>
-            </label>
-            <div
-              class="bp3-form-content"
-            >
-              <div
-                class="bp3-control-group bp3-fill bp3-numeric-input"
-              >
-                <div
-                  class="bp3-input-group"
-                >
-                  <input
-                    autocomplete="off"
-                    class="bp3-input"
-                    min="0"
-                    placeholder=""
-                    style="padding-right: 10px;"
-                    type="text"
-                    value="25"
-                  />
-                </div>
-                <div
-                  class="bp3-button-group bp3-vertical bp3-fixed"
-                >
-                  <button
-                    class="bp3-button"
-                    type="button"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-chevron-up"
-                      icon="chevron-up"
-                    >
-                      <svg
-                        data-icon="chevron-up"
-                        height="16"
-                        viewBox="0 0 16 16"
-                        width="16"
-                      >
-                        <desc>
-                          chevron-up
-                        </desc>
-                        <path
-                          d="M12.71 9.29l-4-4C8.53 5.11 8.28 5 8 5s-.53.11-.71.29l-4 4a1.003 1.003 0 001.42 1.42L8 7.41l3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </button>
-                  <button
-                    class="bp3-button"
-                    type="button"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-chevron-down"
-                      icon="chevron-down"
-                    >
-                      <svg
-                        data-icon="chevron-down"
-                        height="16"
-                        viewBox="0 0 16 16"
-                        width="16"
-                      >
-                        <desc>
-                          chevron-down
-                        </desc>
-                        <path
-                          d="M12 5c-.28 0-.53.11-.71.29L8 8.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42l4 4c.18.18.43.29.71.29s.53-.11.71-.29l4-4A1.003 1.003 0 0012 5z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </button>
-                </div>
-              </div>
-            </div>
-          </div>
-          <div
-            class="bp3-form-group form-group-with-info"
-          >
-            <label
-              class="bp3-label"
+            </Memo(ExternalLink)>
+             
+            for compaction tasks.
+          </p>,
+          "name": "taskContext",
+          "type": "json",
+        },
+        Object {
+          "defaultValue": 25,
+          "info": <p>
+            Priority of the compaction task.
+          </p>,
+          "name": "taskPriority",
+          "type": "number",
+        },
+        Object {
+          "info": <p>
+            <Memo(ExternalLink)
+              href="https://druid.apache.org/docs/0.19.0/configuration/index.html#compact-task-tuningconfig"
             >
               Tuning config
-               
-              <span
-                class="bp3-text-muted"
-              >
-                <span
-                  class="bp3-popover-wrapper"
-                >
-                  <span
-                    class="bp3-popover-target"
-                  >
-                    <span
-                      class="bp3-icon bp3-icon-info-sign"
-                      icon="info-sign"
-                    >
-                      <svg
-                        data-icon="info-sign"
-                        height="14"
-                        viewBox="0 0 16 16"
-                        width="14"
-                      >
-                        <desc>
-                          info-sign
-                        </desc>
-                        <path
-                          d="M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zM7 3h2v2H7V3zm3 10H6v-1h1V7H6V6h3v6h1v1z"
-                          fill-rule="evenodd"
-                        />
-                      </svg>
-                    </span>
-                  </span>
-                </span>
-              </span>
-            </label>
-            <div
-              class="bp3-form-content"
-            >
-              <div
-                class=" ace_editor ace-tm json-input"
-                id="brace-editor"
-                style="width: 100%; height: 8vh;"
-              >
-                <textarea
-                  autocapitalize="off"
-                  autocorrect="off"
-                  class="ace_text-input"
-                  spellcheck="false"
-                  style="opacity: 0;"
-                  wrap="off"
-                />
-                <div
-                  aria-hidden="true"
-                  class="ace_gutter"
-                  style="display: none;"
-                >
-                  <div
-                    class="ace_layer ace_gutter-layer ace_folding-enabled"
-                  />
-                  <div
-                    class="ace_gutter-active-line"
-                  />
-                </div>
-                <div
-                  class="ace_scroller"
-                >
-                  <div
-                    class="ace_content"
-                  >
-                    <div
-                      class="ace_layer ace_print-margin-layer"
-                    >
-                      <div
-                        class="ace_print-margin"
-                        style="left: 4px; visibility: hidden;"
-                      />
-                    </div>
-                    <div
-                      class="ace_layer ace_marker-layer"
-                    />
-                    <div
-                      class="ace_layer ace_text-layer"
-                      style="padding: 0px 4px;"
-                    />
-                    <div
-                      class="ace_layer ace_marker-layer"
-                    />
-                    <div
-                      class="ace_layer ace_cursor-layer ace_hidden-cursors"
-                    >
-                      <div
-                        class="ace_cursor"
-                      />
-                    </div>
-                  </div>
-                </div>
-                <div
-                  class="ace_scrollbar ace_scrollbar-v"
-                  style="display: none; width: 20px;"
-                >
-                  <div
-                    class="ace_scrollbar-inner"
-                    style="width: 20px;"
-                  />
-                </div>
-                <div
-                  class="ace_scrollbar ace_scrollbar-h"
-                  style="display: none; height: 20px;"
-                >
-                  <div
-                    class="ace_scrollbar-inner"
-                    style="height: 20px;"
-                  />
-                </div>
-                <div
-                  style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
-                >
-                  <div
-                    style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-                  />
-                  <div
-                    style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-                  >
-                    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div
-          class="bp3-dialog-footer"
-        >
-          <div
-            class="bp3-dialog-footer-actions"
-          >
-            <button
-              class="bp3-button bp3-intent-danger"
-              type="button"
-            >
-              <span
-                class="bp3-button-text"
-              >
-                Delete
-              </span>
-            </button>
-            <button
-              class="bp3-button"
-              type="button"
-            >
-              <span
-                class="bp3-button-text"
-              >
-                Close
-              </span>
-            </button>
-            <button
-              class="bp3-button bp3-intent-primary"
-              type="button"
-            >
-              <span
-                class="bp3-button-text"
-              >
-                Submit
-              </span>
-            </button>
-          </div>
-        </div>
-      </div>
+            </Memo(ExternalLink)>
+             
+            for compaction tasks.
+          </p>,
+          "name": "tuningConfig",
+          "type": "json",
+        },
+      ]
+    }
+    model={Object {}}
+    onChange={[Function]}
+  />
+  <div
+    className="bp3-dialog-footer"
+  >
+    <div
+      className="bp3-dialog-footer-actions"
+    >
+      <Blueprint3.Button
+        disabled={false}
+        intent="danger"
+        onClick={[Function]}
+        text="Delete"
+      />
+      <Blueprint3.Button
+        onClick={[Function]}
+        text="Close"
+      />
+      <Blueprint3.Button
+        disabled={false}
+        intent="primary"
+        onClick={[Function]}
+        text="Submit"
+      />
     </div>
   </div>
-</div>
+</Blueprint3.Dialog>
 `;
diff --git a/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx b/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx
index c944313..34068c9 100644
--- a/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx
+++ b/web-console/src/dialogs/compaction-dialog/compaction-dialog.spec.tsx
@@ -16,23 +16,22 @@
  * limitations under the License.
  */
 
-import { render } from '@testing-library/react';
+import { shallow } from 'enzyme';
 import React from 'react';
 
 import { CompactionDialog } from './compaction-dialog';
 
 describe('compaction dialog', () => {
   it('matches snapshot', () => {
-    const compactionDialog = (
+    const compactionDialog = shallow(
       <CompactionDialog
         onClose={() => {}}
         onSave={() => {}}
         onDelete={() => {}}
         datasource={'test'}
         compactionConfig={{}}
-      />
+      />,
     );
-    render(compactionDialog);
-    expect(document.body.lastChild).toMatchSnapshot();
+    expect(compactionDialog).toMatchSnapshot();
   });
 });
diff --git a/web-console/src/dialogs/lookup-edit-dialog/__snapshots__/lookup-edit-dialog.spec.tsx.snap b/web-console/src/dialogs/lookup-edit-dialog/__snapshots__/lookup-edit-dialog.spec.tsx.snap
index eb62735..1fe5202 100644
--- a/web-console/src/dialogs/lookup-edit-dialog/__snapshots__/lookup-edit-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/lookup-edit-dialog/__snapshots__/lookup-edit-dialog.spec.tsx.snap
@@ -1,424 +1,429 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`lookup edit dialog matches snapshot 1`] = `
-<div
-  class="bp3-portal"
+<Blueprint3.Dialog
+  canOutsideClickClose={true}
+  className="lookup-edit-dialog"
+  isOpen={true}
+  onClose={[Function]}
+  title="Add lookup"
 >
-  <div
-    class="bp3-overlay bp3-overlay-open bp3-overlay-scroll-container"
+  <Blueprint3.FormGroup
+    className="lookup-label"
+    label="Name"
   >
-    <div
-      class="bp3-overlay-backdrop bp3-overlay-appear bp3-overlay-appear-active"
-      tabindex="0"
+    <Blueprint3.InputGroup
+      disabled={false}
+      onChange={[Function]}
+      placeholder="Enter the lookup name"
+      value="test"
     />
-    <div
-      class="bp3-dialog-container bp3-overlay-content bp3-overlay-appear bp3-overlay-appear-active"
-      tabindex="0"
+  </Blueprint3.FormGroup>
+  <Blueprint3.FormGroup
+    className="lookup-label"
+    label="Tier"
+  >
+    <HTMLSelect
+      disabled={false}
+      onChange={[Function]}
+      value="test"
     >
-      <div
-        class="bp3-dialog lookup-edit-dialog"
+      <option
+        key="a"
+        value="a"
       >
-        <div
-          class="bp3-dialog-header"
-        >
-          <h4
-            class="bp3-heading"
-          >
-            Add lookup
-          </h4>
-          <button
-            aria-label="Close"
-            class="bp3-button bp3-minimal bp3-dialog-close-button"
-            type="button"
-          >
-            <span
-              class="bp3-icon bp3-icon-small-cross"
-              icon="small-cross"
-            >
-              <svg
-                data-icon="small-cross"
-                height="20"
-                viewBox="0 0 20 20"
-                width="20"
-              >
-                <desc>
-                  small-cross
-                </desc>
-                <path
-                  d="M11.41 10l3.29-3.29c.19-.18.3-.43.3-.71a1.003 1.003 0 00-1.71-.71L10 8.59l-3.29-3.3a1.003 1.003 0 00-1.42 1.42L8.59 10 5.3 13.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71l3.29-3.3 3.29 3.29c.18.19.43.3.71.3a1.003 1.003 0 00.71-1.71L11.41 10z"
-                  fill-rule="evenodd"
-                />
-              </svg>
-            </span>
-          </button>
-        </div>
-        <div
-          class="bp3-form-group lookup-label"
-        >
-          <label
-            class="bp3-label"
-          >
-            Name
-             
-            <span
-              class="bp3-text-muted"
-            />
-          </label>
-          <div
-            class="bp3-form-content"
-          >
-            <div
-              class="bp3-input-group"
-            >
-              <input
-                class="bp3-input"
-                placeholder="Enter the lookup name"
-                style="padding-right: 10px;"
-                type="text"
-                value="test"
-              />
-            </div>
-          </div>
-        </div>
-        <div
-          class="bp3-form-group lookup-label"
-        >
-          <label
-            class="bp3-label"
-          >
-            Tier
-             
-            <span
-              class="bp3-text-muted"
-            />
-          </label>
-          <div
-            class="bp3-form-content"
-          >
-            <div
-              class="bp3-html-select"
-            >
-              <select>
-                <option
-                  value="a"
-                >
-                  a
-                </option>
-                <option
-                  value="b"
-                >
-                  b
-                </option>
-                <option
-                  value="c"
-                >
-                  c
-                </option>
-                <option
-                  value="d"
-                >
-                  d
-                </option>
-                <option
-                  value="e"
-                >
-                  e
-                </option>
-                <option
-                  value="f"
-                >
-                  f
-                </option>
-                <option
-                  value="g"
-                >
-                  g
-                </option>
-                <option
-                  value="h"
-                >
-                  h
-                </option>
-                <option
-                  value="i"
-                >
-                  i
-                </option>
-                <option
-                  value="j"
-                >
-                  j
-                </option>
-              </select>
-              <span
-                class="bp3-icon bp3-icon-double-caret-vertical"
-                icon="double-caret-vertical"
-              >
-                <svg
-                  data-icon="double-caret-vertical"
-                  height="16"
-                  viewBox="0 0 16 16"
-                  width="16"
-                >
-                  <desc>
-                    double-caret-vertical
-                  </desc>
-                  <path
-                    d="M5 7h6a1.003 1.003 0 00.71-1.71l-3-3C8.53 2.11 8.28 2 8 2s-.53.11-.71.29l-3 3A1.003 1.003 0 005 7zm6 2H5a1.003 1.003 0 00-.71 1.71l3 3c.18.18.43.29.71.29s.53-.11.71-.29l3-3A1.003 1.003 0 0011 9z"
-                    fill-rule="evenodd"
-                  />
-                </svg>
-              </span>
-            </div>
-          </div>
-        </div>
-        <div
-          class="bp3-form-group lookup-label"
-        >
-          <label
-            class="bp3-label"
-          >
-            Version
-             
-            <span
-              class="bp3-text-muted"
-            />
-          </label>
-          <div
-            class="bp3-form-content"
-          >
-            <div
-              class="bp3-input-group"
-            >
-              <input
-                class="bp3-input"
-                placeholder="Enter the lookup version"
-                style="padding-right: 0px;"
-                type="text"
-                value="test"
-              />
-              <span
-                class="bp3-input-action"
-              >
-                <button
-                  class="bp3-button bp3-minimal"
-                  type="button"
-                >
-                  <span
-                    class="bp3-button-text"
-                  >
-                    Use ISO as version
-                  </span>
-                </button>
-              </span>
-            </div>
-          </div>
-        </div>
-        <div
-          class="auto-form"
-        >
-          <div
-            class="bp3-form-group form-group-with-info"
-          >
-            <label
-              class="bp3-label"
-            >
-              Type
-               
-              <span
-                class="bp3-text-muted"
-              />
-            </label>
-            <div
-              class="bp3-form-content"
-            >
-              <div
-                class="bp3-input-group suggestible-input"
-              >
-                <input
-                  class="bp3-input"
-                  placeholder=""
-                  style="padding-right: 0px;"
-                  suggestions="map,cachedNamespace"
-                  type="text"
-                  value="map"
-                />
-                <span
-                  class="bp3-input-action"
-                >
-                  <span
-                    class="bp3-popover-wrapper"
-                  >
-                    <span
-                      class="bp3-popover-target"
-                    >
-                      <button
-                        class="bp3-button bp3-minimal"
-                        type="button"
-                      >
-                        <span
-                          class="bp3-icon bp3-icon-caret-down"
-                          icon="caret-down"
-                        >
-                          <svg
-                            data-icon="caret-down"
-                            height="16"
-                            viewBox="0 0 16 16"
-                            width="16"
-                          >
-                            <desc>
-                              caret-down
-                            </desc>
-                            <path
-                              d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
-                              fill-rule="evenodd"
-                            />
-                          </svg>
-                        </span>
-                      </button>
-                    </span>
-                  </span>
-                </span>
-              </div>
-            </div>
-          </div>
-          <div
-            class="bp3-form-group form-group-with-info"
-          >
-            <label
-              class="bp3-label"
-            >
-              Map
+        a
+      </option>
+      <option
+        key="b"
+        value="b"
+      >
+        b
+      </option>
+      <option
+        key="c"
+        value="c"
+      >
+        c
+      </option>
+      <option
+        key="d"
+        value="d"
+      >
+        d
+      </option>
+      <option
+        key="e"
+        value="e"
+      >
+        e
+      </option>
+      <option
+        key="f"
+        value="f"
+      >
+        f
+      </option>
+      <option
+        key="g"
+        value="g"
+      >
+        g
+      </option>
+      <option
+        key="h"
+        value="h"
+      >
+        h
+      </option>
+      <option
+        key="i"
+        value="i"
+      >
+        i
+      </option>
+      <option
+        key="j"
+        value="j"
+      >
+        j
+      </option>
+    </HTMLSelect>
+  </Blueprint3.FormGroup>
+  <Blueprint3.FormGroup
+    className="lookup-label"
+    label="Version"
+  >
+    <Blueprint3.InputGroup
+      onChange={[Function]}
+      placeholder="Enter the lookup version"
+      rightElement={
+        <Blueprint3.Button
+          minimal={true}
+          onClick={[Function]}
+          text="Use ISO as version"
+        />
+      }
+      value="test"
+    />
+  </Blueprint3.FormGroup>
+  <AutoForm
+    fields={
+      Array [
+        Object {
+          "adjustment": [Function],
+          "name": "type",
+          "suggestions": Array [
+            "map",
+            "cachedNamespace",
+          ],
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "name": "map",
+          "type": "json",
+        },
+        Object {
+          "defined": [Function],
+          "label": "Globally cached lookup type",
+          "name": "extractionNamespace.type",
+          "placeholder": "uri",
+          "suggestions": Array [
+            "uri",
+            "jdbc",
+          ],
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": "A URI which specifies a directory (or other searchable resource) in which to search for files",
+          "label": "URI prefix",
+          "name": "extractionNamespace.uriPrefix",
+          "placeholder": "s3://bucket/some/key/prefix/",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": "Optional regex for matching the file name under uriPrefix. Only used if uriPrefix is used",
+          "label": "File regex",
+          "name": "extractionNamespace.fileRegex",
+          "placeholder": "(optional)",
+          "type": "string",
+        },
+        Object {
+          "defaultValue": "csv",
+          "defined": [Function],
+          "label": "Format",
+          "name": "extractionNamespace.namespaceParseSpec.format",
+          "suggestions": Array [
+            "csv",
+            "tsv",
+            "customJson",
+            "simpleJson",
+          ],
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": "The list of columns in the csv file",
+          "label": "Columns",
+          "name": "extractionNamespace.namespaceParseSpec.columns",
+          "placeholder": "[\\"key\\", \\"value\\"]",
+          "type": "string-array",
+        },
+        Object {
+          "defined": [Function],
+          "info": "The name of the column containing the key",
+          "label": "Key column",
+          "name": "extractionNamespace.namespaceParseSpec.keyColumn",
+          "placeholder": "Key",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": "The name of the column containing the value",
+          "label": "Value column",
+          "name": "extractionNamespace.namespaceParseSpec.valueColumn",
+          "placeholder": "Value",
+          "type": "string",
+        },
+        Object {
+          "defaultValue": false,
+          "defined": [Function],
+          "info": "A flag to indicate that column information can be extracted from the input files' header row",
+          "label": "Has header row",
+          "name": "extractionNamespace.namespaceParseSpec.hasHeaderRow",
+          "type": "boolean",
+        },
+        Object {
+          "defined": [Function],
+          "info": "Number of header rows to be skipped. The default number of header rows to be skipped is 0.",
+          "label": "Skip header rows",
+          "name": "extractionNamespace.namespaceParseSpec.skipHeaderRows",
+          "placeholder": "(optional)",
+          "type": "number",
+        },
+        Object {
+          "defined": [Function],
+          "label": "Delimiter",
+          "name": "extractionNamespace.namespaceParseSpec.delimiter",
+          "placeholder": "(optional)",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "label": "List delimiter",
+          "name": "extractionNamespace.namespaceParseSpec.listDelimiter",
+          "placeholder": "(optional)",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "label": "Key field name",
+          "name": "extractionNamespace.namespaceParseSpec.keyFieldName",
+          "placeholder": "key",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "label": "Value field name",
+          "name": "extractionNamespace.namespaceParseSpec.valueFieldName",
+          "placeholder": "value",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": <React.Fragment>
+            <p>
+              The namespace value in the SQL query:
+            </p>
+            <p>
+              SELECT keyColumn, valueColumn, tsColumn? FROM 
+              <strong>
+                namespace
+              </strong>
+              .table WHERE filter
+            </p>
+          </React.Fragment>,
+          "label": "Namespace",
+          "name": "extractionNamespace.namespace",
+          "placeholder": "some_lookup",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": "Defines the connectURI value on the The connector config to used",
+          "label": "CreateTables",
+          "name": "extractionNamespace.connectorConfig.createTables",
+          "type": "boolean",
+        },
+        Object {
+          "defined": [Function],
+          "info": "Defines the connectURI value on the The connector config to used",
+          "label": "Connect URI",
+          "name": "extractionNamespace.connectorConfig.connectURI",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": "Defines the user to be used by the connector config",
+          "label": "User",
+          "name": "extractionNamespace.connectorConfig.user",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": "Defines the password to be used by the connector config",
+          "label": "Password",
+          "name": "extractionNamespace.connectorConfig.password",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": <React.Fragment>
+            <p>
+              The table which contains the key value pairs. This will become the table value in the SQL query:
+            </p>
+            <p>
+              SELECT keyColumn, valueColumn, tsColumn? FROM namespace.
+              <strong>
+                table
+              </strong>
+               WHERE filter
+            </p>
+          </React.Fragment>,
+          "label": "Table",
+          "name": "extractionNamespace.table",
+          "placeholder": "some_lookup_table",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": <React.Fragment>
+            <p>
+              The column in the table which contains the keys. This will become the keyColumn value in the SQL query:
+            </p>
+            <p>
+              SELECT 
+              <strong>
+                keyColumn
+              </strong>
+              , valueColumn, tsColumn? FROM namespace.table WHERE filter
+            </p>
+          </React.Fragment>,
+          "label": "Key column",
+          "name": "extractionNamespace.keyColumn",
+          "placeholder": "my_key_value",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": <React.Fragment>
+            <p>
+              The column in table which contains the values. This will become the valueColumn value in the SQL query:
+            </p>
+            <p>
+              SELECT keyColumn, 
+              <strong>
+                valueColumn
+              </strong>
+              , tsColumn? FROM namespace.table WHERE filter
+            </p>
+          </React.Fragment>,
+          "label": "Value column",
+          "name": "extractionNamespace.valueColumn",
+          "placeholder": "my_column_value",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": <React.Fragment>
+            <p>
+              The filter to be used when selecting lookups, this is used to create a where clause on lookup population. This will become the expression filter in the SQL query:
+            </p>
+            <p>
+              SELECT keyColumn, valueColumn, tsColumn? FROM namespace.table WHERE
                
-              <span
-                class="bp3-text-muted"
-              />
-            </label>
-            <div
-              class="bp3-form-content"
-            >
-              <div
-                class=" ace_editor ace-tm json-input"
-                id="brace-editor"
-                style="width: 100%; height: 8vh;"
-              >
-                <textarea
-                  autocapitalize="off"
-                  autocorrect="off"
-                  class="ace_text-input"
-                  spellcheck="false"
-                  style="opacity: 0;"
-                  wrap="off"
-                />
-                <div
-                  aria-hidden="true"
-                  class="ace_gutter"
-                  style="display: none;"
-                >
-                  <div
-                    class="ace_layer ace_gutter-layer ace_folding-enabled"
-                  />
-                  <div
-                    class="ace_gutter-active-line"
-                  />
-                </div>
-                <div
-                  class="ace_scroller"
-                >
-                  <div
-                    class="ace_content"
-                  >
-                    <div
-                      class="ace_layer ace_print-margin-layer"
-                    >
-                      <div
-                        class="ace_print-margin"
-                        style="left: 4px; visibility: hidden;"
-                      />
-                    </div>
-                    <div
-                      class="ace_layer ace_marker-layer"
-                    />
-                    <div
-                      class="ace_layer ace_text-layer"
-                      style="padding: 0px 4px;"
-                    />
-                    <div
-                      class="ace_layer ace_marker-layer"
-                    />
-                    <div
-                      class="ace_layer ace_cursor-layer ace_hidden-cursors"
-                    >
-                      <div
-                        class="ace_cursor"
-                      />
-                    </div>
-                  </div>
-                </div>
-                <div
-                  class="ace_scrollbar ace_scrollbar-v"
-                  style="display: none; width: 20px;"
-                >
-                  <div
-                    class="ace_scrollbar-inner"
-                    style="width: 20px;"
-                  />
-                </div>
-                <div
-                  class="ace_scrollbar ace_scrollbar-h"
-                  style="display: none; height: 20px;"
-                >
-                  <div
-                    class="ace_scrollbar-inner"
-                    style="height: 20px;"
-                  />
-                </div>
-                <div
-                  style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
-                >
-                  <div
-                    style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-                  />
-                  <div
-                    style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
-                  >
-                    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div
-          class="bp3-dialog-footer"
-        >
-          <div
-            class="bp3-dialog-footer-actions"
-          >
-            <button
-              class="bp3-button"
-              type="button"
-            >
-              <span
-                class="bp3-button-text"
-              >
-                Close
-              </span>
-            </button>
-            <button
-              class="bp3-button bp3-intent-primary"
-              type="button"
-            >
-              <span
-                class="bp3-button-text"
-              >
-                Submit
-              </span>
-            </button>
-          </div>
-        </div>
-      </div>
+              <strong>
+                filter
+              </strong>
+            </p>
+          </React.Fragment>,
+          "label": "Filter",
+          "name": "extractionNamespace.filter",
+          "placeholder": "(optional)",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": <React.Fragment>
+            <p>
+              The column in table which contains when the key was updated. This will become the Value in the SQL query:
+            </p>
+            <p>
+              SELECT keyColumn, valueColumn, 
+              <strong>
+                tsColumn
+              </strong>
+              ? FROM namespace.table WHERE filter
+            </p>
+          </React.Fragment>,
+          "label": "TsColumn",
+          "name": "extractionNamespace.tsColumn",
+          "placeholder": "(optional)",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": "Period between polling for updates",
+          "label": "Poll period",
+          "name": "extractionNamespace.pollPeriod",
+          "placeholder": "(optional)",
+          "type": "string",
+        },
+        Object {
+          "defined": [Function],
+          "info": "How long to wait (in ms) for the first run of the cache to populate. 0 indicates to not wait",
+          "label": "First cache timeout",
+          "name": "firstCacheTimeout",
+          "placeholder": "(optional)",
+          "type": "number",
+        },
+        Object {
+          "defaultValue": false,
+          "defined": [Function],
+          "info": "If the underlying map is injective (keys and values are unique) then optimizations can occur internally by setting this to true",
+          "name": "injective",
+          "type": "boolean",
+        },
+      ]
+    }
+    model={
+      Object {
+        "map": Object {},
+        "type": "map",
+      }
+    }
+    onChange={[Function]}
+  />
+  <div
+    className="bp3-dialog-footer"
+  >
+    <div
+      className="bp3-dialog-footer-actions"
+    >
+      <Blueprint3.Button
+        onClick={[Function]}
+        text="Close"
+      />
+      <Blueprint3.Button
+        disabled={false}
+        intent="primary"
+        onClick={[Function]}
+        text="Submit"
+      />
     </div>
   </div>
-</div>
+</Blueprint3.Dialog>
 `;
diff --git a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx
index 6a20281..b969bc8 100644
--- a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx
+++ b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx
@@ -16,14 +16,14 @@
  * limitations under the License.
  */
 
-import { render } from '@testing-library/react';
+import { shallow } from 'enzyme';
 import React from 'react';
 
 import { isDisabled, LookupEditDialog } from './lookup-edit-dialog';
 
 describe('lookup edit dialog', () => {
   it('matches snapshot', () => {
-    const lookupEditDialog = (
+    const lookupEditDialog = shallow(
       <LookupEditDialog
         onClose={() => {}}
         onSubmit={() => {}}
@@ -34,11 +34,10 @@ describe('lookup edit dialog', () => {
         lookupSpec={{ type: 'map', map: {} }}
         isEdit={false}
         allLookupTiers={['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']}
-      />
+      />,
     );
 
-    render(lookupEditDialog);
-    expect(document.body.lastChild).toMatchSnapshot();
+    expect(lookupEditDialog).toMatchSnapshot();
   });
 });
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org