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 cd01a48  Web-console: add timed button  (#7912)
cd01a48 is described below

commit cd01a48eabd166add4344f36e7e8a721bfa94416
Author: mcbrewster <[email protected]>
AuthorDate: Mon Jun 24 21:18:19 2019 -0700

    Web-console: add timed button  (#7912)
    
    * add refresh button
    
    * update snapshots
    
    * fix spacing
    
    * add supervisors button
    
    * modify query manager
    
    * add icon
    
    * update snapshots
    
    * fix space
    
    * stop refreshing when option selected
    
    * small fixes
    
    * add default value
    
    * fix spelling mistake
    
    * fix query-input
    
    * rename class
---
 web-console/src/components/index.ts                |   2 +
 .../components/refresh-button/refresh-button.tsx   |  57 +++++++++
 .../{index.ts => timed-button/timed-button.scss}   |  21 +---
 .../src/components/timed-button/timed-button.tsx   | 131 +++++++++++++++++++++
 .../supervisor-table-action-dialog.tsx             |   1 -
 web-console/src/utils/local-storage-keys.tsx       |   5 +
 web-console/src/utils/query-manager.tsx            |   9 ++
 .../__snapshots__/datasource-view.spec.tsx.snap    |   7 +-
 .../src/views/datasource-view/datasource-view.tsx  |  15 ++-
 .../__snapshots__/segments-view.spec.tsx.snap      |   7 +-
 .../src/views/segments-view/segments-view.tsx      |  13 +-
 .../__snapshots__/servers-view.spec.tsx.snap       |   7 +-
 .../src/views/servers-view/servers-view.tsx        |   9 +-
 .../__snapshots__/tasks-view.spec.tsx.snap         |  14 +--
 web-console/src/views/task-view/tasks-view.tsx     |  16 ++-
 15 files changed, 250 insertions(+), 64 deletions(-)

diff --git a/web-console/src/components/index.ts 
b/web-console/src/components/index.ts
index 063875a..fb9475d 100644
--- a/web-console/src/components/index.ts
+++ b/web-console/src/components/index.ts
@@ -33,3 +33,5 @@ export * from './show-log/show-log';
 export * from './table-column-selector/table-column-selector';
 export * from './view-control-bar/view-control-bar';
 export * from './clearable-input/clearable-input';
+export * from './refresh-button/refresh-button';
+export * from './timed-button/timed-button';
diff --git a/web-console/src/components/refresh-button/refresh-button.tsx 
b/web-console/src/components/refresh-button/refresh-button.tsx
new file mode 100644
index 0000000..71905b6
--- /dev/null
+++ b/web-console/src/components/refresh-button/refresh-button.tsx
@@ -0,0 +1,57 @@
+/*
+ * 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 { IconNames } from '@blueprintjs/icons';
+import React from 'react';
+
+import { LocalStorageKeys } from '../../utils';
+import { TimedButton } from '../timed-button/timed-button';
+
+export interface RefreshButtonProps extends React.Props<any> {
+  onRefresh: (auto: boolean) => void;
+  localStorageKey?: LocalStorageKeys;
+}
+
+export class RefreshButton extends React.PureComponent<RefreshButtonProps> {
+  constructor(props: RefreshButtonProps, context: any) {
+    super(props, context);
+  }
+
+  render() {
+    const { onRefresh, localStorageKey } = this.props;
+    const intervals = [
+      { label: '5 seconds', value: 5000 },
+      { label: '10 seconds', value: 10000 },
+      { label: '30 seconds', value: 30000 },
+      { label: '1 minute', value: 60000 },
+      { label: '2 minutes', value: 120000 },
+      { label: 'None', value: 0 },
+    ];
+
+    return (
+      <TimedButton
+        defaultValue={30000}
+        label={'Auto refresh every:'}
+        intervals={intervals}
+        icon={IconNames.REFRESH}
+        text={'Refresh'}
+        onRefresh={onRefresh}
+        localStorageKey={localStorageKey}
+      />
+    );
+  }
+}
diff --git a/web-console/src/components/index.ts 
b/web-console/src/components/timed-button/timed-button.scss
similarity index 51%
copy from web-console/src/components/index.ts
copy to web-console/src/components/timed-button/timed-button.scss
index 063875a..2879880 100644
--- a/web-console/src/components/index.ts
+++ b/web-console/src/components/timed-button/timed-button.scss
@@ -16,20 +16,7 @@
  * limitations under the License.
  */
 
-export * from './action-cell/action-cell';
-export * from './array-input/array-input';
-export * from './auto-form/auto-form';
-export * from './center-message/center-message';
-export * from './external-link/external-link';
-export * from './header-bar/header-bar';
-export * from './json-collapse/json-collapse';
-export * from './json-input/json-input';
-export * from './loader/loader';
-export * from './menu-checkbox/menu-checkbox';
-export * from './table-cell/table-cell';
-export * from './rule-editor/rule-editor';
-export * from './show-json/show-json';
-export * from './show-log/show-log';
-export * from './table-column-selector/table-column-selector';
-export * from './view-control-bar/view-control-bar';
-export * from './clearable-input/clearable-input';
+.timed-button {
+    padding: 10px 10px 5px 10px;
+  }
+
diff --git a/web-console/src/components/timed-button/timed-button.tsx 
b/web-console/src/components/timed-button/timed-button.tsx
new file mode 100644
index 0000000..7b5d957
--- /dev/null
+++ b/web-console/src/components/timed-button/timed-button.tsx
@@ -0,0 +1,131 @@
+/*
+ * 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, IButtonProps, Popover, Radio, RadioGroup } from 
'@blueprintjs/core';
+import { IconNames } from '@blueprintjs/icons';
+import React from 'react';
+
+import { localStorageGet, LocalStorageKeys, localStorageSet } from 
'../../utils';
+
+import './timed-button.scss';
+
+export interface Interval {
+  label: string;
+  value: number;
+}
+
+export interface TimedButtonProps extends IButtonProps {
+  intervals: Interval[];
+  onRefresh: (auto: boolean) => void;
+  localStorageKey?: LocalStorageKeys;
+  label: string;
+  defaultValue: number;
+}
+
+export interface TimedButtonState {
+  interval: number;
+}
+
+export class TimedButton extends React.PureComponent<TimedButtonProps, 
TimedButtonState> {
+  constructor(props: TimedButtonProps, context: any) {
+    super(props, context);
+    this.state = {
+      interval:
+        this.props.localStorageKey && 
localStorageGet(this.props.localStorageKey)
+          ? Number(localStorageGet(this.props.localStorageKey))
+          : this.props.defaultValue,
+    };
+  }
+
+  private timer: any;
+
+  componentDidMount(): void {
+    if (this.state.interval) {
+      this.timer = setTimeout(() => {
+        this.continuousRefresh(this.state.interval);
+      }, this.state.interval);
+    }
+  }
+
+  componentWillUnmount(): void {
+    this.clearTimer();
+  }
+
+  clearTimer() {
+    if (this.timer) {
+      clearTimeout(this.timer);
+    }
+    this.timer = undefined;
+  }
+
+  continuousRefresh = (selectedInterval: number) => {
+    if (selectedInterval) {
+      this.timer = setTimeout(() => {
+        this.props.onRefresh(true);
+        this.continuousRefresh(selectedInterval);
+      }, selectedInterval);
+    }
+  };
+
+  handleSelection = (e: any) => {
+    const selectedInterval = Number(e.currentTarget.value);
+    this.clearTimer();
+    this.setState({ interval: selectedInterval });
+    if (this.props.localStorageKey) {
+      localStorageSet(this.props.localStorageKey, String(selectedInterval));
+    }
+    this.continuousRefresh(selectedInterval);
+  };
+
+  render() {
+    const {
+      label,
+      intervals,
+      onRefresh,
+      type,
+      text,
+      icon,
+      defaultValue,
+      localStorageKey,
+      ...other
+    } = this.props;
+    const { interval } = this.state;
+
+    return (
+      <ButtonGroup>
+        <Button {...other} text={text} icon={icon} onClick={() => 
onRefresh(false)} />
+        <Popover
+          content={
+            <RadioGroup
+              label={label}
+              className="timed-button"
+              onChange={this.handleSelection}
+              selectedValue={interval}
+            >
+              {intervals.map((interval: any) => (
+                <Radio label={interval.label} value={interval.value} 
key={interval.label} />
+              ))}
+            </RadioGroup>
+          }
+        >
+          <Button {...other} rightIcon={IconNames.CARET_DOWN} />
+        </Popover>
+      </ButtonGroup>
+    );
+  }
+}
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 44c9d29..49d6af4 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
@@ -44,7 +44,6 @@ export class SupervisorTableActionDialog extends 
React.PureComponent<
       activeTab: 'status',
     };
   }
-
   render(): React.ReactNode {
     const { supervisorId, actions, onClose } = this.props;
     const { activeTab } = this.state;
diff --git a/web-console/src/utils/local-storage-keys.tsx 
b/web-console/src/utils/local-storage-keys.tsx
index ab3ade7..cf70584 100644
--- a/web-console/src/utils/local-storage-keys.tsx
+++ b/web-console/src/utils/local-storage-keys.tsx
@@ -27,6 +27,11 @@ export const LocalStorageKeys = {
   QUERY_KEY: 'druid-console-query' as 'druid-console-query',
   TASKS_VIEW_PANE_SIZE: 'tasks-view-pane-size' as 'tasks-view-pane-size',
   QUERY_VIEW_PANE_SIZE: 'query-view-pane-size' as 'query-view-pane-size',
+  TASKS_REFRESH_RATE: 'task-refresh-rate' as 'task-refresh-rate',
+  DATASOURCES_REFRESH_RATE: 'datasources-refresh-rate' as 
'datasources-refresh-rate',
+  SEGMENTS_REFRESH_RATE: 'segments-refresh-rate' as 'segments-refresh-rate',
+  SERVERS_REFRESH_RATE: 'servers-refresh-rate' as 'servers-refresh-rate',
+  SUPERVISORS_REFRESH_RATE: 'supervisors-refresh-rate' as 
'supervisors-refresh-rate',
 };
 export type LocalStorageKeys = typeof LocalStorageKeys[keyof typeof 
LocalStorageKeys];
 
diff --git a/web-console/src/utils/query-manager.tsx 
b/web-console/src/utils/query-manager.tsx
index f5126f1..bf5e07a 100644
--- a/web-console/src/utils/query-manager.tsx
+++ b/web-console/src/utils/query-manager.tsx
@@ -125,6 +125,15 @@ export class QueryManager<Q, R> {
     this.trigger();
   }
 
+  public rerunLastQueryInBackground(auto: boolean): void {
+    this.nextQuery = this.lastQuery;
+    if (auto) {
+      this.runWhenIdle();
+    } else {
+      this.trigger();
+    }
+  }
+
   public getLastQuery(): Q {
     return this.lastQuery;
   }
diff --git 
a/web-console/src/views/datasource-view/__snapshots__/datasource-view.spec.tsx.snap
 
b/web-console/src/views/datasource-view/__snapshots__/datasource-view.spec.tsx.snap
index e74f634..64e34ba 100755
--- 
a/web-console/src/views/datasource-view/__snapshots__/datasource-view.spec.tsx.snap
+++ 
b/web-console/src/views/datasource-view/__snapshots__/datasource-view.spec.tsx.snap
@@ -7,10 +7,9 @@ exports[`data source view matches snapshot 1`] = `
   <ViewControlBar
     label="Datasources"
   >
-    <Blueprint3.Button
-      icon="refresh"
-      onClick={[Function]}
-      text="Refresh"
+    <RefreshButton
+      localStorageKey="datasources-refresh-rate"
+      onRefresh={[Function]}
     />
     <Blueprint3.Button
       icon="application"
diff --git a/web-console/src/views/datasource-view/datasource-view.tsx 
b/web-console/src/views/datasource-view/datasource-view.tsx
index 69f9f63..bf7f60a 100644
--- a/web-console/src/views/datasource-view/datasource-view.tsx
+++ b/web-console/src/views/datasource-view/datasource-view.tsx
@@ -31,7 +31,13 @@ import axios from 'axios';
 import React from 'react';
 import ReactTable, { Filter } from 'react-table';
 
-import { ActionCell, RuleEditor, TableColumnSelector, ViewControlBar } from 
'../../components';
+import {
+  ActionCell,
+  RefreshButton,
+  RuleEditor,
+  TableColumnSelector,
+  ViewControlBar,
+} from '../../components';
 import { ActionIcon } from '../../components/action-icon/action-icon';
 import { AsyncActionDialog, CompactionDialog, RetentionDialog } from 
'../../dialogs';
 import { AppToaster } from '../../singletons/toaster';
@@ -777,10 +783,9 @@ GROUP BY 1`);
     return (
       <div className="data-sources-view app-view">
         <ViewControlBar label="Datasources">
-          <Button
-            icon={IconNames.REFRESH}
-            text="Refresh"
-            onClick={() => this.datasourceQueryManager.rerunLastQuery()}
+          <RefreshButton
+            onRefresh={auto => 
this.datasourceQueryManager.rerunLastQueryInBackground(auto)}
+            localStorageKey={LocalStorageKeys.DATASOURCES_REFRESH_RATE}
           />
           {!noSqlMode && (
             <Button
diff --git 
a/web-console/src/views/segments-view/__snapshots__/segments-view.spec.tsx.snap 
b/web-console/src/views/segments-view/__snapshots__/segments-view.spec.tsx.snap
index fd2d81f..dae9fbe 100755
--- 
a/web-console/src/views/segments-view/__snapshots__/segments-view.spec.tsx.snap
+++ 
b/web-console/src/views/segments-view/__snapshots__/segments-view.spec.tsx.snap
@@ -7,10 +7,9 @@ exports[`segments-view matches snapshot 1`] = `
   <ViewControlBar
     label="Segments"
   >
-    <Blueprint3.Button
-      icon="refresh"
-      onClick={[Function]}
-      text="Refresh"
+    <RefreshButton
+      localStorageKey="segments-refresh-rate"
+      onRefresh={[Function]}
     />
     <Blueprint3.Button
       hidden={false}
diff --git a/web-console/src/views/segments-view/segments-view.tsx 
b/web-console/src/views/segments-view/segments-view.tsx
index 3924b9a..942caa2 100644
--- a/web-console/src/views/segments-view/segments-view.tsx
+++ b/web-console/src/views/segments-view/segments-view.tsx
@@ -24,7 +24,7 @@ import React from 'react';
 import ReactTable from 'react-table';
 import { Filter } from 'react-table';
 
-import { TableColumnSelector, ViewControlBar } from '../../components';
+import { RefreshButton, TableColumnSelector, ViewControlBar } from 
'../../components';
 import {
   addFilter,
   formatBytes,
@@ -454,14 +454,13 @@ export class SegmentsView extends 
React.PureComponent<SegmentsViewProps, Segment
     return (
       <div className="segments-view app-view">
         <ViewControlBar label="Segments">
-          <Button
-            icon={IconNames.REFRESH}
-            text="Refresh"
-            onClick={() =>
+          <RefreshButton
+            onRefresh={auto =>
               noSqlMode
-                ? this.segmentsJsonQueryManager.rerunLastQuery()
-                : this.segmentsSqlQueryManager.rerunLastQuery()
+                ? 
this.segmentsJsonQueryManager.rerunLastQueryInBackground(auto)
+                : this.segmentsSqlQueryManager.rerunLastQueryInBackground(auto)
             }
+            localStorageKey={LocalStorageKeys.SEGMENTS_REFRESH_RATE}
           />
           {!noSqlMode && (
             <Button
diff --git 
a/web-console/src/views/servers-view/__snapshots__/servers-view.spec.tsx.snap 
b/web-console/src/views/servers-view/__snapshots__/servers-view.spec.tsx.snap
index 197ac91..520323d 100755
--- 
a/web-console/src/views/servers-view/__snapshots__/servers-view.spec.tsx.snap
+++ 
b/web-console/src/views/servers-view/__snapshots__/servers-view.spec.tsx.snap
@@ -30,10 +30,9 @@ exports[`servers view action servers view 1`] = `
         Tier
       </Blueprint3.Button>
     </Blueprint3.ButtonGroup>
-    <Blueprint3.Button
-      icon="refresh"
-      onClick={[Function]}
-      text="Refresh"
+    <RefreshButton
+      localStorageKey="servers-refresh-rate"
+      onRefresh={[Function]}
     />
     <Blueprint3.Button
       icon="application"
diff --git a/web-console/src/views/servers-view/servers-view.tsx 
b/web-console/src/views/servers-view/servers-view.tsx
index b7503b1..af02784 100644
--- a/web-console/src/views/servers-view/servers-view.tsx
+++ b/web-console/src/views/servers-view/servers-view.tsx
@@ -24,7 +24,7 @@ import React from 'react';
 import ReactTable from 'react-table';
 import { Filter } from 'react-table';
 
-import { ActionCell, TableColumnSelector, ViewControlBar } from 
'../../components';
+import { ActionCell, RefreshButton, TableColumnSelector, ViewControlBar } from 
'../../components';
 import { AsyncActionDialog } from '../../dialogs';
 import {
   addFilter,
@@ -639,10 +639,9 @@ ORDER BY "rank" DESC, "server" DESC`);
               Tier
             </Button>
           </ButtonGroup>
-          <Button
-            icon={IconNames.REFRESH}
-            text="Refresh"
-            onClick={() => this.serverQueryManager.rerunLastQuery()}
+          <RefreshButton
+            onRefresh={auto => 
this.serverQueryManager.rerunLastQueryInBackground(auto)}
+            localStorageKey={LocalStorageKeys.SERVERS_REFRESH_RATE}
           />
           {!noSqlMode && (
             <Button
diff --git 
a/web-console/src/views/task-view/__snapshots__/tasks-view.spec.tsx.snap 
b/web-console/src/views/task-view/__snapshots__/tasks-view.spec.tsx.snap
index 8ba938c..9ced81f 100644
--- a/web-console/src/views/task-view/__snapshots__/tasks-view.spec.tsx.snap
+++ b/web-console/src/views/task-view/__snapshots__/tasks-view.spec.tsx.snap
@@ -20,10 +20,9 @@ exports[`tasks view matches snapshot 1`] = `
       <ViewControlBar
         label="Supervisors"
       >
-        <Blueprint3.Button
-          icon="refresh"
-          onClick={[Function]}
-          text="Refresh"
+        <RefreshButton
+          localStorageKey="supervisors-refresh-rate"
+          onRefresh={[Function]}
         />
         <Blueprint3.Popover
           boundary="scrollParent"
@@ -349,10 +348,9 @@ exports[`tasks view matches snapshot 1`] = `
             Status
           </Blueprint3.Button>
         </Blueprint3.ButtonGroup>
-        <Blueprint3.Button
-          icon="refresh"
-          onClick={[Function]}
-          text="Refresh"
+        <RefreshButton
+          localStorageKey="task-refresh-rate"
+          onRefresh={[Function]}
         />
         <Blueprint3.Button
           icon="application"
diff --git a/web-console/src/views/task-view/tasks-view.tsx 
b/web-console/src/views/task-view/tasks-view.tsx
index dcd8e81..0f7505d 100644
--- a/web-console/src/views/task-view/tasks-view.tsx
+++ b/web-console/src/views/task-view/tasks-view.tsx
@@ -34,7 +34,7 @@ import SplitterLayout from 'react-splitter-layout';
 import ReactTable from 'react-table';
 import { Filter } from 'react-table';
 
-import { ActionCell, TableColumnSelector, ViewControlBar } from 
'../../components';
+import { ActionCell, RefreshButton, TableColumnSelector, ViewControlBar } from 
'../../components';
 import {
   AsyncActionDialog,
   SpecDialog,
@@ -905,10 +905,9 @@ ORDER BY "rank" DESC, "created_time" DESC`);
         >
           <div className={'top-pane'}>
             <ViewControlBar label="Supervisors">
-              <Button
-                icon={IconNames.REFRESH}
-                text="Refresh"
-                onClick={() => this.supervisorQueryManager.rerunLastQuery()}
+              <RefreshButton
+                localStorageKey={LocalStorageKeys.SUPERVISORS_REFRESH_RATE}
+                onRefresh={auto => 
this.supervisorQueryManager.rerunLastQueryInBackground(auto)}
               />
               <Popover content={submitSupervisorMenu} 
position={Position.BOTTOM_LEFT}>
                 <Button icon={IconNames.PLUS} text="Submit supervisor" />
@@ -952,10 +951,9 @@ ORDER BY "rank" DESC, "created_time" DESC`);
                   Status
                 </Button>
               </ButtonGroup>
-              <Button
-                icon={IconNames.REFRESH}
-                text="Refresh"
-                onClick={() => this.taskQueryManager.rerunLastQuery()}
+              <RefreshButton
+                localStorageKey={LocalStorageKeys.TASKS_REFRESH_RATE}
+                onRefresh={auto => 
this.taskQueryManager.rerunLastQueryInBackground(auto)}
               />
               {!noSqlMode && (
                 <Button


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to