You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by fj...@apache.org on 2019/07/30 19:53:56 UTC

[incubator-druid] branch master updated: Web-console: add Supervisor statistics table and show json query manager (#8176)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4e60afc  Web-console: add Supervisor statistics table and show json query manager (#8176)
4e60afc is described below

commit 4e60afc86ecbf876e733e37ef3b7bc1e1ab29a89
Author: mcbrewster <37...@users.noreply.github.com>
AuthorDate: Tue Jul 30 12:53:46 2019 -0700

    Web-console: add Supervisor statistics table and show json query manager (#8176)
    
    * add statistics table
    
    * change error message
    
    * add query managers
    
    * update snapshots
    
    * fixes
    
    * add stricter types
    
    * fix error type
    
    * prettier fic
    
    * fix undefined
    
    * add typing
    
    * fixe query manager
---
 web-console/sasslint.json                          |   3 +-
 .../__snapshots__/show-json.spec.tsx.snap          |  37 +----
 web-console/src/components/show-json/show-json.tsx |  58 +++----
 .../supervisor-statistics-table.spec.tsx.snap}     |  27 +---
 .../supervisor-statistics-table.scss               |  49 ++++++
 .../supervisor-statistics-table.spec.tsx           |  30 ++++
 .../supervisor-statistics-table.tsx                | 178 +++++++++++++++++++++
 .../segment-table-action-dialog.spec.tsx.snap      |  37 +----
 .../supervisor-table-action-dialog.spec.tsx.snap   |  37 +----
 .../supervisor-table-action-dialog.tsx             |   3 +-
 .../task-table-action-dialog.spec.tsx.snap         |  37 +----
 11 files changed, 296 insertions(+), 200 deletions(-)

diff --git a/web-console/sasslint.json b/web-console/sasslint.json
index f4880c9..6f2dce1 100644
--- a/web-console/sasslint.json
+++ b/web-console/sasslint.json
@@ -1,5 +1,4 @@
 {
   "extends": "awesome-code-style/sasslint.json",
-  "rules": {
-  }
+  "rules": {}
 }
diff --git a/web-console/src/components/show-json/__snapshots__/show-json.spec.tsx.snap b/web-console/src/components/show-json/__snapshots__/show-json.spec.tsx.snap
index 690e8fe..f10d5b3 100644
--- a/web-console/src/components/show-json/__snapshots__/show-json.spec.tsx.snap
+++ b/web-console/src/components/show-json/__snapshots__/show-json.spec.tsx.snap
@@ -50,41 +50,6 @@ exports[`rule editor matches snapshot 1`] = `
   </div>
   <div
     class="main-area"
-  >
-    <div
-      class="loader"
-    >
-      <div
-        class="loader-logo"
-      >
-        <svg
-          viewBox="0 0 100 100"
-        >
-          <path
-            class="one"
-            d="M54.2,69.8h-2.7c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h2.7c11.5,0,23.8-7.4,23.8-23.7
-          c0-9.1-6.9-15.8-16.4-15.8H38c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h23.6c5.3,0,10.1,1.9,13.6,5.3c3.5,3.4,5.4,8,5.4,13.1
-          c0,6.6-2.3,13-6.3,17.7C69.5,66.8,62.5,69.8,54.2,69.8z"
-          />
-          <path
-            class="two"
-            d="M55.7,59.5h-26c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h26c7.5,0,11.5-5.8,11.5-11.5
-            c0-4.2-3.2-7.3-7.7-7.3h-26c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h26c5.9,0,10.3,4.3,10.3,9.9c0,3.7-1.3,7.2-3.7,9.8
-            C63.5,58,59.9,59.5,55.7,59.5z"
-          />
-          <path
-            class="three"
-            d="M27.2,38h-6.3c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h6.3c0.7,0,1.3,0.6,1.3,1.3S27.9,38,27.2,38z"
-          />
-          <path
-            class="four"
-            d="M45.1,69.8h-5.8c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h5.8c0.7,0,1.3,0.6,1.3,1.3
-            C46.4,69.2,45.8,69.8,45.1,69.8z"
-          />
-        </svg>
-      </div>
-    </div>
-    
-  </div>
+  />
 </div>
 `;
diff --git a/web-console/src/components/show-json/show-json.tsx b/web-console/src/components/show-json/show-json.tsx
index 75d4867..15fcdde 100644
--- a/web-console/src/components/show-json/show-json.tsx
+++ b/web-console/src/components/show-json/show-json.tsx
@@ -23,7 +23,7 @@ import React from 'react';
 
 import { AppToaster } from '../../singletons/toaster';
 import { UrlBaser } from '../../singletons/url-baser';
-import { downloadFile } from '../../utils';
+import { downloadFile, QueryManager } from '../../utils';
 import { Loader } from '../loader/loader';
 
 import './show-json.scss';
@@ -35,39 +35,44 @@ export interface ShowJsonProps {
 }
 
 export interface ShowJsonState {
-  jsonValue: string;
+  jsonValue?: string;
+  loading: boolean;
+  error?: string;
 }
 
 export class ShowJson extends React.PureComponent<ShowJsonProps, ShowJsonState> {
+  private showJsonQueryManager: QueryManager<null, string>;
   constructor(props: ShowJsonProps, context: any) {
     super(props, context);
     this.state = {
       jsonValue: '',
+      loading: false,
     };
-
-    this.getJsonInfo();
+    this.showJsonQueryManager = new QueryManager({
+      processQuery: async () => {
+        const { endpoint, transform } = this.props;
+        const resp = await axios.get(endpoint);
+        let data = resp.data;
+        if (transform) data = transform(data);
+        return typeof data === 'string' ? data : JSON.stringify(data, undefined, 2);
+      },
+      onStateChange: ({ result, loading, error }) => {
+        this.setState({
+          loading,
+          error,
+          jsonValue: result,
+        });
+      },
+    });
   }
 
-  private getJsonInfo = async (): Promise<void> => {
-    const { endpoint, transform } = this.props;
-
-    try {
-      const resp = await axios.get(endpoint);
-      let data = resp.data;
-      if (transform) data = transform(data);
-      this.setState({
-        jsonValue: typeof data === 'string' ? data : JSON.stringify(data, undefined, 2),
-      });
-    } catch (e) {
-      this.setState({
-        jsonValue: `Error: ` + e.response.data,
-      });
-    }
-  };
+  componentDidMount(): void {
+    this.showJsonQueryManager.runQuery(null);
+  }
 
   render(): JSX.Element {
     const { endpoint, downloadFilename } = this.props;
-    const { jsonValue } = this.state;
+    const { jsonValue, error, loading } = this.state;
 
     return (
       <div className="show-json">
@@ -75,18 +80,18 @@ export class ShowJson extends React.PureComponent<ShowJsonProps, ShowJsonState>
           <ButtonGroup className="right-buttons">
             {downloadFilename && (
               <Button
-                disabled={!jsonValue}
+                disabled={loading}
                 text="Save"
                 minimal
-                onClick={() => downloadFile(jsonValue, 'json', downloadFilename)}
+                onClick={() => downloadFile(jsonValue ? jsonValue : '', 'json', downloadFilename)}
               />
             )}
             <Button
               text="Copy"
-              disabled={!jsonValue}
               minimal
+              disabled={loading}
               onClick={() => {
-                copy(jsonValue, { format: 'text/plain' });
+                copy(jsonValue ? jsonValue : '', { format: 'text/plain' });
                 AppToaster.show({
                   message: 'JSON copied to clipboard',
                   intent: Intent.SUCCESS,
@@ -102,8 +107,7 @@ export class ShowJson extends React.PureComponent<ShowJsonProps, ShowJsonState>
           </ButtonGroup>
         </div>
         <div className="main-area">
-          {!jsonValue && <Loader loadingText="" loading />}
-          {jsonValue && <TextArea readOnly value={jsonValue} />}
+          {loading ? <Loader /> : <TextArea readOnly value={!error ? jsonValue : error} />}
         </div>
       </div>
     );
diff --git a/web-console/src/components/show-json/__snapshots__/show-json.spec.tsx.snap b/web-console/src/components/supervisor-statistics-table/__snapshots__/supervisor-statistics-table.spec.tsx.snap
similarity index 77%
copy from web-console/src/components/show-json/__snapshots__/show-json.spec.tsx.snap
copy to web-console/src/components/supervisor-statistics-table/__snapshots__/supervisor-statistics-table.spec.tsx.snap
index 690e8fe..aeaa9c5 100644
--- a/web-console/src/components/show-json/__snapshots__/show-json.spec.tsx.snap
+++ b/web-console/src/components/supervisor-statistics-table/__snapshots__/supervisor-statistics-table.spec.tsx.snap
@@ -2,7 +2,7 @@
 
 exports[`rule editor matches snapshot 1`] = `
 <div
-  class="show-json"
+  class="supervisor-statistics-table"
 >
   <div
     class="top-actions"
@@ -19,30 +19,6 @@ exports[`rule editor matches snapshot 1`] = `
         <span
           class="bp3-button-text"
         >
-          Save
-        </span>
-      </button>
-      <button
-        class="bp3-button bp3-disabled bp3-minimal"
-        disabled=""
-        tabindex="-1"
-        type="button"
-      >
-        <span
-          class="bp3-button-text"
-        >
-          Copy
-        </span>
-      </button>
-      <button
-        class="bp3-button bp3-disabled bp3-minimal"
-        disabled=""
-        tabindex="-1"
-        type="button"
-      >
-        <span
-          class="bp3-button-text"
-        >
           View raw
         </span>
       </button>
@@ -84,7 +60,6 @@ exports[`rule editor matches snapshot 1`] = `
         </svg>
       </div>
     </div>
-    
   </div>
 </div>
 `;
diff --git a/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.scss b/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.scss
new file mode 100644
index 0000000..0e7051f
--- /dev/null
+++ b/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.scss
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.supervisor-statistics-table {
+  position: relative;
+  height: 100%;
+
+  .top-actions {
+    text-align: right;
+    padding-bottom: 10px;
+
+    & > * {
+      display: inline-block;
+    }
+  }
+
+  .main-area {
+    height: calc(100% - 40px);
+
+    textarea {
+      height: 100%;
+      width: 100%;
+      resize: none;
+    }
+
+    .loader {
+      position: relative;
+    }
+
+    .ReactTable {
+      height: 100%;
+    }
+  }
+}
diff --git a/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.spec.tsx b/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.spec.tsx
new file mode 100644
index 0000000..5f41522
--- /dev/null
+++ b/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.spec.tsx
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { render } from '@testing-library/react';
+import React from 'react';
+
+import { SupervisorStatisticsTable } from './supervisor-statistics-table';
+
+describe('rule editor', () => {
+  it('matches snapshot', () => {
+    const showJson = <SupervisorStatisticsTable endpoint={'test'} downloadFilename={'test'} />;
+    const { container } = render(showJson);
+    expect(container.firstChild).toMatchSnapshot();
+  });
+});
diff --git a/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.tsx b/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.tsx
new file mode 100644
index 0000000..4f8baf7
--- /dev/null
+++ b/web-console/src/components/supervisor-statistics-table/supervisor-statistics-table.tsx
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Button, ButtonGroup } from '@blueprintjs/core';
+import axios from 'axios';
+import React from 'react';
+import ReactTable, { Column } from 'react-table';
+
+import { Loader } from '..';
+import { UrlBaser } from '../../singletons/url-baser';
+import { QueryManager } from '../../utils';
+import { deepGet } from '../../utils/object-change';
+
+import './supervisor-statistics-table.scss';
+
+interface TaskSummary {
+  totals: Record<string, StatsEntry>;
+  movingAverages: Record<string, Record<string, StatsEntry>>;
+}
+
+interface StatsEntry {
+  processed?: number;
+  processedWithError?: number;
+  thrownAway?: number;
+  unparseable?: number;
+  [key: string]: number | undefined;
+}
+
+interface TableRow {
+  taskId: string;
+  summary: TaskSummary;
+}
+
+export interface SupervisorStatisticsTableProps {
+  endpoint: string;
+  downloadFilename?: string;
+}
+
+export interface SupervisorStatisticsTableState {
+  data?: TableRow[];
+  loading: boolean;
+  error?: string;
+}
+
+export class SupervisorStatisticsTable extends React.PureComponent<
+  SupervisorStatisticsTableProps,
+  SupervisorStatisticsTableState
+> {
+  private supervisorStatisticsTableQueryManager: QueryManager<null, TableRow[]>;
+
+  constructor(props: SupervisorStatisticsTableProps, context: any) {
+    super(props, context);
+    this.state = {
+      loading: true,
+    };
+    this.supervisorStatisticsTableQueryManager = new QueryManager({
+      processQuery: async () => {
+        const { endpoint } = this.props;
+        const resp = await axios.get(endpoint);
+        const data: Record<string, Record<string, TaskSummary>> = resp.data;
+
+        return Object.values(data).flatMap(v =>
+          Object.keys(v).map(k => ({ taskId: k, summary: v[k] })),
+        );
+      },
+      onStateChange: ({ result, loading, error }) => {
+        this.setState({
+          data: result,
+          error,
+          loading,
+        });
+      },
+    });
+  }
+
+  componentDidMount(): void {
+    this.supervisorStatisticsTableQueryManager.runQuery(null);
+  }
+
+  renderCell(data: StatsEntry | undefined) {
+    if (!data) {
+      return <div>No data found</div>;
+    }
+    return Object.keys(data).map(key => (
+      <div key={key}>{`${key}: ${Number(data[key]).toFixed(1)}`}</div>
+    ));
+  }
+
+  renderTable(error?: string) {
+    const { data } = this.state;
+    console.log(data);
+    let columns: Column<TableRow>[] = [
+      {
+        Header: 'Task Id',
+        id: 'task_id',
+        accessor: d => d.taskId,
+      },
+      {
+        Header: 'Totals',
+        id: 'total',
+        accessor: d => {
+          return deepGet(d, 'summary.totals.buildSegments') as StatsEntry;
+        },
+        Cell: d => {
+          return this.renderCell(d.value ? d.value : undefined);
+        },
+      },
+    ];
+
+    if (data && data.length) {
+      columns = columns.concat(
+        Object.keys(deepGet(data[0], 'summary.movingAverages.buildSegments'))
+          .sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))
+          .map(
+            (interval: string): Column<TableRow> => {
+              return {
+                Header: interval,
+                id: interval,
+                accessor: d => {
+                  return deepGet(d, `summary.movingAverages.buildSegments.${interval}`);
+                },
+                Cell: d => {
+                  return this.renderCell(d.value ? d.value : null);
+                },
+              };
+            },
+          ),
+      );
+    }
+
+    return (
+      <ReactTable
+        data={this.state.data ? this.state.data : []}
+        showPagination={false}
+        defaultPageSize={6}
+        columns={columns}
+        noDataText={error ? error : 'No statistics data found'}
+      />
+    );
+  }
+
+  render() {
+    const { endpoint } = this.props;
+    const { loading, error } = this.state;
+    return (
+      <div className="supervisor-statistics-table">
+        <div className="top-actions">
+          <ButtonGroup className="right-buttons">
+            <Button
+              text="View raw"
+              disabled={loading}
+              minimal
+              onClick={() => window.open(UrlBaser.base(endpoint), '_blank')}
+            />
+          </ButtonGroup>
+        </div>
+        <div className="main-area">
+          {loading ? <Loader loadingText="" loading /> : !loading && this.renderTable(error)}
+        </div>
+      </div>
+    );
+  }
+}
diff --git a/web-console/src/dialogs/segments-table-action-dialog/__snapshots__/segment-table-action-dialog.spec.tsx.snap b/web-console/src/dialogs/segments-table-action-dialog/__snapshots__/segment-table-action-dialog.spec.tsx.snap
index f6e3e4a..0227fd6 100644
--- a/web-console/src/dialogs/segments-table-action-dialog/__snapshots__/segment-table-action-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/segments-table-action-dialog/__snapshots__/segment-table-action-dialog.spec.tsx.snap
@@ -140,42 +140,7 @@ exports[`task table action dialog matches snapshot 1`] = `
               </div>
               <div
                 class="main-area"
-              >
-                <div
-                  class="loader"
-                >
-                  <div
-                    class="loader-logo"
-                  >
-                    <svg
-                      viewBox="0 0 100 100"
-                    >
-                      <path
-                        class="one"
-                        d="M54.2,69.8h-2.7c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h2.7c11.5,0,23.8-7.4,23.8-23.7
-          c0-9.1-6.9-15.8-16.4-15.8H38c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h23.6c5.3,0,10.1,1.9,13.6,5.3c3.5,3.4,5.4,8,5.4,13.1
-          c0,6.6-2.3,13-6.3,17.7C69.5,66.8,62.5,69.8,54.2,69.8z"
-                      />
-                      <path
-                        class="two"
-                        d="M55.7,59.5h-26c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h26c7.5,0,11.5-5.8,11.5-11.5
-            c0-4.2-3.2-7.3-7.7-7.3h-26c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h26c5.9,0,10.3,4.3,10.3,9.9c0,3.7-1.3,7.2-3.7,9.8
-            C63.5,58,59.9,59.5,55.7,59.5z"
-                      />
-                      <path
-                        class="three"
-                        d="M27.2,38h-6.3c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h6.3c0.7,0,1.3,0.6,1.3,1.3S27.9,38,27.2,38z"
-                      />
-                      <path
-                        class="four"
-                        d="M45.1,69.8h-5.8c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h5.8c0.7,0,1.3,0.6,1.3,1.3
-            C46.4,69.2,45.8,69.8,45.1,69.8z"
-                      />
-                    </svg>
-                  </div>
-                </div>
-                
-              </div>
+              />
             </div>
           </div>
         </div>
diff --git a/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap b/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap
index da9b49b..6c887c8 100755
--- a/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/supervisor-table-action-dialog/__snapshots__/supervisor-table-action-dialog.spec.tsx.snap
@@ -227,42 +227,7 @@ exports[`supervisor table action dialog matches snapshot 1`] = `
               </div>
               <div
                 class="main-area"
-              >
-                <div
-                  class="loader"
-                >
-                  <div
-                    class="loader-logo"
-                  >
-                    <svg
-                      viewBox="0 0 100 100"
-                    >
-                      <path
-                        class="one"
-                        d="M54.2,69.8h-2.7c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h2.7c11.5,0,23.8-7.4,23.8-23.7
-          c0-9.1-6.9-15.8-16.4-15.8H38c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h23.6c5.3,0,10.1,1.9,13.6,5.3c3.5,3.4,5.4,8,5.4,13.1
-          c0,6.6-2.3,13-6.3,17.7C69.5,66.8,62.5,69.8,54.2,69.8z"
-                      />
-                      <path
-                        class="two"
-                        d="M55.7,59.5h-26c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h26c7.5,0,11.5-5.8,11.5-11.5
-            c0-4.2-3.2-7.3-7.7-7.3h-26c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h26c5.9,0,10.3,4.3,10.3,9.9c0,3.7-1.3,7.2-3.7,9.8
-            C63.5,58,59.9,59.5,55.7,59.5z"
-                      />
-                      <path
-                        class="three"
-                        d="M27.2,38h-6.3c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h6.3c0.7,0,1.3,0.6,1.3,1.3S27.9,38,27.2,38z"
-                      />
-                      <path
-                        class="four"
-                        d="M45.1,69.8h-5.8c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h5.8c0.7,0,1.3,0.6,1.3,1.3
-            C46.4,69.2,45.8,69.8,45.1,69.8z"
-                      />
-                    </svg>
-                  </div>
-                </div>
-                
-              </div>
+              />
             </div>
           </div>
         </div>
diff --git a/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx b/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx
index d941de5..94acb90 100644
--- a/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx
+++ b/web-console/src/dialogs/supervisor-table-action-dialog/supervisor-table-action-dialog.tsx
@@ -21,6 +21,7 @@ import React from 'react';
 
 import { ShowJson } from '../../components';
 import { ShowHistory } from '../../components/show-history/show-history';
+import { SupervisorStatisticsTable } from '../../components/supervisor-statistics-table/supervisor-statistics-table';
 import { BasicAction, basicActionsToButtons } from '../../utils/basic-action';
 import { deepGet } from '../../utils/object-change';
 import { SideButtonMetaData, TableActionDialog } from '../table-action-dialog/table-action-dialog';
@@ -92,7 +93,7 @@ export class SupervisorTableActionDialog extends React.PureComponent<
           />
         )}
         {activeTab === 'stats' && (
-          <ShowJson
+          <SupervisorStatisticsTable
             endpoint={`/druid/indexer/v1/supervisor/${supervisorId}/stats`}
             downloadFilename={`supervisor-stats-${supervisorId}.json`}
           />
diff --git a/web-console/src/dialogs/task-table-action-dialog/__snapshots__/task-table-action-dialog.spec.tsx.snap b/web-console/src/dialogs/task-table-action-dialog/__snapshots__/task-table-action-dialog.spec.tsx.snap
index 0538167..2a79dff 100644
--- a/web-console/src/dialogs/task-table-action-dialog/__snapshots__/task-table-action-dialog.spec.tsx.snap
+++ b/web-console/src/dialogs/task-table-action-dialog/__snapshots__/task-table-action-dialog.spec.tsx.snap
@@ -227,42 +227,7 @@ exports[`task table action dialog matches snapshot 1`] = `
               </div>
               <div
                 class="main-area"
-              >
-                <div
-                  class="loader"
-                >
-                  <div
-                    class="loader-logo"
-                  >
-                    <svg
-                      viewBox="0 0 100 100"
-                    >
-                      <path
-                        class="one"
-                        d="M54.2,69.8h-2.7c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h2.7c11.5,0,23.8-7.4,23.8-23.7
-          c0-9.1-6.9-15.8-16.4-15.8H38c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h23.6c5.3,0,10.1,1.9,13.6,5.3c3.5,3.4,5.4,8,5.4,13.1
-          c0,6.6-2.3,13-6.3,17.7C69.5,66.8,62.5,69.8,54.2,69.8z"
-                      />
-                      <path
-                        class="two"
-                        d="M55.7,59.5h-26c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h26c7.5,0,11.5-5.8,11.5-11.5
-            c0-4.2-3.2-7.3-7.7-7.3h-26c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h26c5.9,0,10.3,4.3,10.3,9.9c0,3.7-1.3,7.2-3.7,9.8
-            C63.5,58,59.9,59.5,55.7,59.5z"
-                      />
-                      <path
-                        class="three"
-                        d="M27.2,38h-6.3c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3h6.3c0.7,0,1.3,0.6,1.3,1.3S27.9,38,27.2,38z"
-                      />
-                      <path
-                        class="four"
-                        d="M45.1,69.8h-5.8c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3h5.8c0.7,0,1.3,0.6,1.3,1.3
-            C46.4,69.2,45.8,69.8,45.1,69.8z"
-                      />
-                    </svg>
-                  </div>
-                </div>
-                
-              </div>
+              />
             </div>
           </div>
         </div>


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