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]