mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Explore & Dashboard: New Refresh picker (#16505)
* Added RefreshButton
* Added RefreshSelect
* Added RefreshSelectButton
* Added RefreshPicker
* Removed the magic string Paused
* Minor style changes and using Off instead of Pause
* Added HeadlessSelect
* Added HeadlessSelect story
* Added SelectButton
* Removed RefreshSelectButton
* Added TimePicker and moved ClickOutsideWrapper to ui/components
* Added TimePickerPopOver
* Added react-calendar
* Missed yarn lock file
* Added inputs to popover
* Added TimePicker and RefreshPicker to DashNav
* Moved TimePicker and RefreshPicker to app/core
* Added react-calendar to app and removed from ui/components
* Fixed PopOver onClick
* Moved everything back to ui components because of typings problems
* Exporing RefreshPicker and TimePicker
* Added Apply and inputs
* Added typings
* Added TimePickerInput and logic
* Fixed parsing of string to Moments
* Fixed range string
* Styling and connecting the calendars and inputs
* Changed Calendar styling
* Added backward forward and zoom
* Fixed responsive styles
* Moved TimePicker and RefreshPicker into app core
* Renamed menuIsOpen to isOpen
* Changed from className={} to className=""
* Moved Popover to TimePickerOptionGroup
* Renamed all PopOver to Popover
* Renamed popOver to popover and some minor refactorings
* Renamed files with git mv
* Added ButtonSelect and refactored RefreshPicker
* Refactored TimePicker to use new ButtonSelect
* Removed HeadlessSelect as suggested
* fix: Fix typings and misc errors after rebase
* wip: Enable time picker on dashboard and add tooltip
* Merge branch 'master' into hugoh/new-timepicker-and-unified-component
# Conflicts:
# packages/grafana-ui/package.json
# packages/grafana-ui/src/components/Input/Input.test.tsx
# packages/grafana-ui/src/components/Input/Input.tsx
# packages/grafana-ui/src/utils/validate.ts
# public/app/features/dashboard/panel_editor/QueryOptions.tsx
# yarn.lock
* fix: Snapshot update
* Move TimePicker default options into the TimePicker as statics, pass the tooltipContent down the line when wanted and wrap the button in a tooltip element
* fix: Override internal state prop if we provide one in a prop
* Updated snapshots
* Let dashnav control refreshPicker state
* feat: Add a stringToMs function
* wip: RefreshPicker
* wip: Move RefreshPicker to @grafana/ui
* wip: Move TimePicker to @grafana/ui
* wip: Remove comments
* wip: Add refreshPicker to explore
* wip: Use default intervals if the prop is missing
* wip: Nicer way of setting defaults
* fix: Control the select component
* wip: Add onMoveForward/onMoveBack
* Remove code related to the new time picker and refresh picker from dashnav
* Fix: Typings after merge
* chore: Minor fix after merge
* chore: Remove _.map usage
* chore: Moved refresh-picker logic out of the refresh picker since it will work a little differently in explore and dashboards until we have replaced the TimeSrv
* feat: Add an Interval component to @grafana/ui
* chore: Remove intervalId from redux state and move setInterval logic from ExploreToolbar to its own Interval component
* feat: Add refreshInterval to Explore's URL state
* feat: Pick up refreshInterval from url on page load
* fix: Set default refreshInterval when no value can be retained from URL
* fix: Update test initial state with refreshInterval
* fix: Handle URLs before RefreshPicker
* fix: Move RefreshInterval to url position 3 since the segments can take multiple positions
* fix: A better way of detecting urls without RefreshInterval in Explore
* chore: Some Explore typings
* fix: Attach refresh picker to interval picker
* chore: Sass fix for refresh button border radius
* fix: Remove refreshInterval from URL
* fix: Intervals now start when previous interval is finished
* fix: Use clearTimeout instead of clearInterval
* fix: Make sure there's a delay set before adding a timeout when we have slow explore queries
* wip: Add refresh picker to dashboard
* feat: Add util for removing keys with empty values
* feat: RefreshPicker in dashboards and tmp rem out old RefreshPicker
* fix: Remove the jumpy:ness in the refreshpicker
* Changed placement and made it hide when your in dashboard settings
* chore: Move logic related to refresh picker out of DashNav to its own component
* feat: Add tooltip to refreshpicker
* fix: Fix bug with refreshpicker not updating when setting to 'off'
* fix: Make it possible to override refresh intervals using the dashboard intervals
* chore: Change name of Interval to SetInterval to align with ecmascripts naming since its basically the same but declarative and async
* fix: Use default intervals when auto refresh is empty in dashboard settings
* fix: Hide time/interval picker when hidden is true on the model, such as on the home dashboard
* fix: Interval picker will have to handle location changes since timeSrv wont
* RefreshPicker: Refactoring refresh picker
* RefreshPicker: minor refactoring
This commit is contained in:
committed by
Torkel Ödegaard
parent
d23f50ab23
commit
406ef962fc
@@ -22,6 +22,7 @@ import {
|
||||
import { updateLocation } from 'app/core/actions';
|
||||
|
||||
// Types
|
||||
import { ResultGetter } from 'app/types/explore';
|
||||
import { ThunkResult } from 'app/types';
|
||||
import {
|
||||
RawTimeRange,
|
||||
@@ -44,6 +45,8 @@ import {
|
||||
import {
|
||||
updateDatasourceInstanceAction,
|
||||
changeQueryAction,
|
||||
changeRefreshIntervalAction,
|
||||
ChangeRefreshIntervalPayload,
|
||||
changeSizeAction,
|
||||
ChangeSizePayload,
|
||||
changeTimeAction,
|
||||
@@ -164,7 +167,7 @@ export function changeSize(
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the time range of Explore. Usually called from the Timepicker or a graph interaction.
|
||||
* Change the time range of Explore. Usually called from the Time picker or a graph interaction.
|
||||
*/
|
||||
export function changeTime(exploreId: ExploreId, range: TimeRange): ThunkResult<void> {
|
||||
return dispatch => {
|
||||
@@ -173,6 +176,16 @@ export function changeTime(exploreId: ExploreId, range: TimeRange): ThunkResult<
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the refresh interval of Explore. Called from the Refresh picker.
|
||||
*/
|
||||
export function changeRefreshInterval(
|
||||
exploreId: ExploreId,
|
||||
refreshInterval: string
|
||||
): ActionOf<ChangeRefreshIntervalPayload> {
|
||||
return changeRefreshIntervalAction({ exploreId, refreshInterval });
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all queries and results.
|
||||
*/
|
||||
@@ -526,7 +539,7 @@ export function queryTransactionSuccess(
|
||||
/**
|
||||
* Main action to run queries and dispatches sub-actions based on which result viewers are active
|
||||
*/
|
||||
export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkResult<void> {
|
||||
export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkResult<Promise<any>> {
|
||||
return (dispatch, getState) => {
|
||||
const {
|
||||
datasourceInstance,
|
||||
@@ -543,13 +556,13 @@ export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkRe
|
||||
|
||||
if (datasourceError) {
|
||||
// let's not run any queries if data source is in a faulty state
|
||||
return;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!hasNonEmptyQuery(queries)) {
|
||||
dispatch(clearQueriesAction({ exploreId }));
|
||||
dispatch(stateSave()); // Remember to saves to state and update location
|
||||
return;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Some datasource's query builders allow per-query interval limits,
|
||||
@@ -558,41 +571,46 @@ export function runQueries(exploreId: ExploreId, ignoreUIState = false): ThunkRe
|
||||
|
||||
dispatch(runQueriesAction({ exploreId }));
|
||||
// Keep table queries first since they need to return quickly
|
||||
if ((ignoreUIState || showingTable) && supportsTable) {
|
||||
dispatch(
|
||||
runQueriesForType(
|
||||
exploreId,
|
||||
'Table',
|
||||
{
|
||||
interval,
|
||||
format: 'table',
|
||||
instant: true,
|
||||
valueWithRefId: true,
|
||||
},
|
||||
(data: any) => data[0]
|
||||
)
|
||||
);
|
||||
}
|
||||
if ((ignoreUIState || showingGraph) && supportsGraph) {
|
||||
dispatch(
|
||||
runQueriesForType(
|
||||
exploreId,
|
||||
'Graph',
|
||||
{
|
||||
interval,
|
||||
format: 'time_series',
|
||||
instant: false,
|
||||
maxDataPoints: containerWidth,
|
||||
},
|
||||
makeTimeSeriesList
|
||||
)
|
||||
);
|
||||
}
|
||||
if ((ignoreUIState || showingLogs) && supportsLogs) {
|
||||
dispatch(runQueriesForType(exploreId, 'Logs', { interval, format: 'logs' }));
|
||||
}
|
||||
const tableQueriesPromise =
|
||||
(ignoreUIState || showingTable) && supportsTable
|
||||
? dispatch(
|
||||
runQueriesForType(
|
||||
exploreId,
|
||||
'Table',
|
||||
{
|
||||
interval,
|
||||
format: 'table',
|
||||
instant: true,
|
||||
valueWithRefId: true,
|
||||
},
|
||||
(data: any[]) => data[0]
|
||||
)
|
||||
)
|
||||
: undefined;
|
||||
const typeQueriesPromise =
|
||||
(ignoreUIState || showingGraph) && supportsGraph
|
||||
? dispatch(
|
||||
runQueriesForType(
|
||||
exploreId,
|
||||
'Graph',
|
||||
{
|
||||
interval,
|
||||
format: 'time_series',
|
||||
instant: false,
|
||||
maxDataPoints: containerWidth,
|
||||
},
|
||||
makeTimeSeriesList
|
||||
)
|
||||
)
|
||||
: undefined;
|
||||
const logsQueriesPromise =
|
||||
(ignoreUIState || showingLogs) && supportsLogs
|
||||
? dispatch(runQueriesForType(exploreId, 'Logs', { interval, format: 'logs' }))
|
||||
: undefined;
|
||||
|
||||
dispatch(stateSave());
|
||||
|
||||
return Promise.all([tableQueriesPromise, typeQueriesPromise, logsQueriesPromise]);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -607,14 +625,13 @@ function runQueriesForType(
|
||||
exploreId: ExploreId,
|
||||
resultType: ResultType,
|
||||
queryOptions: QueryOptions,
|
||||
resultGetter?: any
|
||||
resultGetter?: ResultGetter
|
||||
): ThunkResult<void> {
|
||||
return async (dispatch, getState) => {
|
||||
const { datasourceInstance, eventBridge, queries, queryIntervals, range, scanning } = getState().explore[exploreId];
|
||||
const datasourceId = datasourceInstance.meta.id;
|
||||
|
||||
// Run all queries concurrently
|
||||
queries.forEach(async (query, rowIndex) => {
|
||||
const queryPromises = queries.map(async (query, rowIndex) => {
|
||||
const transaction = buildQueryTransaction(
|
||||
query,
|
||||
rowIndex,
|
||||
@@ -638,6 +655,8 @@ function runQueriesForType(
|
||||
dispatch(queryTransactionFailure(exploreId, transaction.id, response, datasourceId));
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all(queryPromises);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -814,7 +833,6 @@ export function refreshExplore(exploreId: ExploreId): ThunkResult<void> {
|
||||
const { datasource, queries, range, ui } = urlState;
|
||||
const refreshQueries = queries.map(q => ({ ...q, ...generateEmptyQuery(itemState.queries) }));
|
||||
const refreshRange = { from: parseTime(range.from), to: parseTime(range.to) };
|
||||
|
||||
// need to refresh datasource
|
||||
if (update.datasource) {
|
||||
const initialQueries = ensureQueries(queries);
|
||||
|
||||
Reference in New Issue
Block a user