mirror of
https://github.com/apache/druid.git
synced 2025-02-17 07:25:02 +00:00
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
This commit is contained in:
parent
6cc8802b8e
commit
cd01a48eab
@ -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';
|
||||
|
57
web-console/src/components/refresh-button/refresh-button.tsx
Normal file
57
web-console/src/components/refresh-button/refresh-button.tsx
Normal file
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
22
web-console/src/components/timed-button/timed-button.scss
Normal file
22
web-console/src/components/timed-button/timed-button.scss
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.timed-button {
|
||||
padding: 10px 10px 5px 10px;
|
||||
}
|
||||
|
131
web-console/src/components/timed-button/timed-button.tsx
Normal file
131
web-console/src/components/timed-button/timed-button.tsx
Normal file
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user