Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
40e87536
Unverified
Commit
40e87536
authored
Mar 25, 2020
by
kay delaney
Committed by
GitHub
Mar 25, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Explore: Allows a user to cancel a running query (#22545)
parent
910f65d2
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
91 additions
and
7 deletions
+91
-7
public/app/features/explore/ExploreToolbar.tsx
+8
-1
public/app/features/explore/RunButton.tsx
+12
-5
public/app/features/explore/state/actionTypes.ts
+5
-0
public/app/features/explore/state/actions.test.ts
+38
-1
public/app/features/explore/state/actions.ts
+14
-0
public/app/features/explore/state/reducers.ts
+9
-0
public/sass/components/_navbar.scss
+5
-0
No files found.
public/app/features/explore/ExploreToolbar.tsx
View file @
40e87536
...
@@ -13,6 +13,7 @@ import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
...
@@ -13,6 +13,7 @@ import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
import
{
StoreState
}
from
'app/types/store'
;
import
{
StoreState
}
from
'app/types/store'
;
import
{
import
{
changeDatasource
,
changeDatasource
,
cancelQueries
,
clearQueries
,
clearQueries
,
splitClose
,
splitClose
,
runQueries
,
runQueries
,
...
@@ -72,6 +73,7 @@ interface StateProps {
...
@@ -72,6 +73,7 @@ interface StateProps {
interface
DispatchProps
{
interface
DispatchProps
{
changeDatasource
:
typeof
changeDatasource
;
changeDatasource
:
typeof
changeDatasource
;
clearAll
:
typeof
clearQueries
;
clearAll
:
typeof
clearQueries
;
cancelQueries
:
typeof
cancelQueries
;
runQueries
:
typeof
runQueries
;
runQueries
:
typeof
runQueries
;
closeSplit
:
typeof
splitClose
;
closeSplit
:
typeof
splitClose
;
split
:
typeof
splitOpen
;
split
:
typeof
splitOpen
;
...
@@ -93,8 +95,12 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
...
@@ -93,8 +95,12 @@ export class UnConnectedExploreToolbar extends PureComponent<Props> {
this
.
props
.
clearAll
(
this
.
props
.
exploreId
);
this
.
props
.
clearAll
(
this
.
props
.
exploreId
);
};
};
onRunQuery
=
()
=>
{
onRunQuery
=
(
loading
=
false
)
=>
{
if
(
loading
)
{
return
this
.
props
.
cancelQueries
(
this
.
props
.
exploreId
);
}
else
{
return
this
.
props
.
runQueries
(
this
.
props
.
exploreId
);
return
this
.
props
.
runQueries
(
this
.
props
.
exploreId
);
}
};
};
onChangeRefreshInterval
=
(
item
:
string
)
=>
{
onChangeRefreshInterval
=
(
item
:
string
)
=>
{
...
@@ -388,6 +394,7 @@ const mapDispatchToProps: DispatchProps = {
...
@@ -388,6 +394,7 @@ const mapDispatchToProps: DispatchProps = {
updateLocation
,
updateLocation
,
changeRefreshInterval
,
changeRefreshInterval
,
clearAll
:
clearQueries
,
clearAll
:
clearQueries
,
cancelQueries
,
runQueries
,
runQueries
,
closeSplit
:
splitClose
,
closeSplit
:
splitClose
,
split
:
splitOpen
,
split
:
splitOpen
,
...
...
public/app/features/explore/RunButton.tsx
View file @
40e87536
...
@@ -20,7 +20,7 @@ const getStyles = memoizeOne(() => {
...
@@ -20,7 +20,7 @@ const getStyles = memoizeOne(() => {
type
Props
=
{
type
Props
=
{
splitted
:
boolean
;
splitted
:
boolean
;
loading
:
boolean
;
loading
:
boolean
;
onRun
:
()
=>
void
;
onRun
:
(
loading
:
boolean
)
=>
void
;
refreshInterval
?:
string
;
refreshInterval
?:
string
;
onChangeRefreshInterval
:
(
interval
:
string
)
=>
void
;
onChangeRefreshInterval
:
(
interval
:
string
)
=>
void
;
showDropdown
:
boolean
;
showDropdown
:
boolean
;
...
@@ -29,12 +29,17 @@ type Props = {
...
@@ -29,12 +29,17 @@ type Props = {
export
function
RunButton
(
props
:
Props
)
{
export
function
RunButton
(
props
:
Props
)
{
const
{
splitted
,
loading
,
onRun
,
onChangeRefreshInterval
,
refreshInterval
,
showDropdown
}
=
props
;
const
{
splitted
,
loading
,
onRun
,
onChangeRefreshInterval
,
refreshInterval
,
showDropdown
}
=
props
;
const
styles
=
getStyles
();
const
styles
=
getStyles
();
const
runButton
=
(
const
runButton
=
(
<
ResponsiveButton
<
ResponsiveButton
splitted=
{
splitted
}
splitted=
{
splitted
}
title=
"Run Query"
title=
{
loading
?
'Cancel'
:
'Run Query'
}
onClick=
{
onRun
}
onClick=
{
()
=>
onRun
(
loading
)
}
buttonClassName=
{
classNames
(
'navbar-button--secondary'
,
{
'btn--radius-right-0'
:
showDropdown
})
}
buttonClassName=
{
classNames
({
'navbar-button--secondary'
:
!
loading
,
'navbar-button--danger'
:
loading
,
'btn--radius-right-0'
:
showDropdown
,
})
}
iconClassName=
{
loading
?
'fa fa-spinner fa-fw fa-spin run-icon'
:
'fa fa-refresh fa-fw'
}
iconClassName=
{
loading
?
'fa fa-spinner fa-fw fa-spin run-icon'
:
'fa fa-refresh fa-fw'
}
/>
/>
);
);
...
@@ -44,7 +49,9 @@ export function RunButton(props: Props) {
...
@@ -44,7 +49,9 @@ export function RunButton(props: Props) {
<
RefreshPicker
<
RefreshPicker
onIntervalChanged=
{
onChangeRefreshInterval
}
onIntervalChanged=
{
onChangeRefreshInterval
}
value=
{
refreshInterval
}
value=
{
refreshInterval
}
buttonSelectClassName=
{
`navbar-button--secondary ${styles.selectButtonOverride}`
}
buttonSelectClassName=
{
`${loading ? 'navbar-button--danger' : 'navbar-button--secondary'} ${
styles.selectButtonOverride
}`
}
refreshButton=
{
runButton
}
refreshButton=
{
runButton
}
/>
/>
);
);
...
...
public/app/features/explore/state/actionTypes.ts
View file @
40e87536
...
@@ -218,6 +218,11 @@ export const changeRefreshIntervalAction = createAction<ChangeRefreshIntervalPay
...
@@ -218,6 +218,11 @@ export const changeRefreshIntervalAction = createAction<ChangeRefreshIntervalPay
export
const
clearQueriesAction
=
createAction
<
ClearQueriesPayload
>
(
'explore/clearQueries'
);
export
const
clearQueriesAction
=
createAction
<
ClearQueriesPayload
>
(
'explore/clearQueries'
);
/**
/**
* Cancel running queries.
*/
export
const
cancelQueriesAction
=
createAction
<
ClearQueriesPayload
>
(
'explore/cancelQueries'
);
/**
* Highlight expressions in the log results
* Highlight expressions in the log results
*/
*/
export
const
highlightLogsExpressionAction
=
createAction
<
HighlightLogsExpressionPayload
>
(
export
const
highlightLogsExpressionAction
=
createAction
<
HighlightLogsExpressionPayload
>
(
...
...
public/app/features/explore/state/actions.test.ts
View file @
40e87536
...
@@ -2,7 +2,7 @@ import { PayloadAction } from '@reduxjs/toolkit';
...
@@ -2,7 +2,7 @@ import { PayloadAction } from '@reduxjs/toolkit';
import
{
DataQuery
,
DefaultTimeZone
,
ExploreMode
,
LogsDedupStrategy
,
RawTimeRange
,
toUtc
}
from
'@grafana/data'
;
import
{
DataQuery
,
DefaultTimeZone
,
ExploreMode
,
LogsDedupStrategy
,
RawTimeRange
,
toUtc
}
from
'@grafana/data'
;
import
*
as
Actions
from
'./actions'
;
import
*
as
Actions
from
'./actions'
;
import
{
changeDatasource
,
loadDatasource
,
navigateToExplore
,
refreshExplore
}
from
'./actions'
;
import
{
changeDatasource
,
loadDatasource
,
navigateToExplore
,
refreshExplore
,
cancelQueries
}
from
'./actions'
;
import
{
ExploreId
,
ExploreUpdateState
,
ExploreUrlState
}
from
'app/types'
;
import
{
ExploreId
,
ExploreUpdateState
,
ExploreUrlState
}
from
'app/types'
;
import
{
thunkTester
}
from
'test/core/thunk/thunkTester'
;
import
{
thunkTester
}
from
'test/core/thunk/thunkTester'
;
import
{
import
{
...
@@ -13,6 +13,8 @@ import {
...
@@ -13,6 +13,8 @@ import {
setQueriesAction
,
setQueriesAction
,
updateDatasourceInstanceAction
,
updateDatasourceInstanceAction
,
updateUIStateAction
,
updateUIStateAction
,
cancelQueriesAction
,
scanStopAction
,
}
from
'./actionTypes'
;
}
from
'./actionTypes'
;
import
{
Emitter
}
from
'app/core/core'
;
import
{
Emitter
}
from
'app/core/core'
;
import
{
makeInitialUpdateState
}
from
'./reducers'
;
import
{
makeInitialUpdateState
}
from
'./reducers'
;
...
@@ -20,6 +22,7 @@ import { PanelModel } from 'app/features/dashboard/state';
...
@@ -20,6 +22,7 @@ import { PanelModel } from 'app/features/dashboard/state';
import
{
updateLocation
}
from
'../../../core/actions'
;
import
{
updateLocation
}
from
'../../../core/actions'
;
import
{
MockDataSourceApi
}
from
'../../../../test/mocks/datasource_srv'
;
import
{
MockDataSourceApi
}
from
'../../../../test/mocks/datasource_srv'
;
import
*
as
DatasourceSrv
from
'app/features/plugins/datasource_srv'
;
import
*
as
DatasourceSrv
from
'app/features/plugins/datasource_srv'
;
import
{
interval
}
from
'rxjs'
;
jest
.
mock
(
'app/features/plugins/datasource_srv'
);
jest
.
mock
(
'app/features/plugins/datasource_srv'
);
const
getDatasourceSrvMock
=
(
DatasourceSrv
.
getDatasourceSrv
as
any
)
as
jest
.
Mock
<
DatasourceSrv
.
DatasourceSrv
>
;
const
getDatasourceSrvMock
=
(
DatasourceSrv
.
getDatasourceSrv
as
any
)
as
jest
.
Mock
<
DatasourceSrv
.
DatasourceSrv
>
;
...
@@ -174,6 +177,40 @@ describe('refreshExplore', () => {
...
@@ -174,6 +177,40 @@ describe('refreshExplore', () => {
});
});
});
});
describe
(
'running queries'
,
()
=>
{
it
(
'should cancel running query when cancelQueries is dispatched'
,
async
()
=>
{
const
unsubscribable
=
interval
(
1000
);
unsubscribable
.
subscribe
();
const
exploreId
=
ExploreId
.
left
;
const
initialState
=
{
explore
:
{
[
exploreId
]:
{
datasourceInstance
:
'test-datasource'
,
initialized
:
true
,
loading
:
true
,
querySubscription
:
unsubscribable
,
queries
:
[
'A'
],
range
:
testRange
,
},
},
user
:
{
orgId
:
'A'
,
},
};
const
dispatchedActions
=
await
thunkTester
(
initialState
)
.
givenThunk
(
cancelQueries
)
.
whenThunkIsDispatched
(
exploreId
);
expect
(
dispatchedActions
).
toEqual
([
scanStopAction
({
exploreId
}),
cancelQueriesAction
({
exploreId
}),
expect
.
anything
(),
]);
});
});
describe
(
'changing datasource'
,
()
=>
{
describe
(
'changing datasource'
,
()
=>
{
it
(
'should switch to logs mode when changing from prometheus to loki'
,
async
()
=>
{
it
(
'should switch to logs mode when changing from prometheus to loki'
,
async
()
=>
{
const
lokiMock
=
{
const
lokiMock
=
{
...
...
public/app/features/explore/state/actions.ts
View file @
40e87536
...
@@ -85,6 +85,8 @@ import {
...
@@ -85,6 +85,8 @@ import {
ToggleTablePayload
,
ToggleTablePayload
,
updateDatasourceInstanceAction
,
updateDatasourceInstanceAction
,
updateUIStateAction
,
updateUIStateAction
,
changeLoadingStateAction
,
cancelQueriesAction
,
}
from
'./actionTypes'
;
}
from
'./actionTypes'
;
import
{
getTimeZone
}
from
'app/features/profile/state/selectors'
;
import
{
getTimeZone
}
from
'app/features/profile/state/selectors'
;
import
{
getShiftedTimeRange
}
from
'app/core/utils/timePicker'
;
import
{
getShiftedTimeRange
}
from
'app/core/utils/timePicker'
;
...
@@ -243,6 +245,17 @@ export function clearQueries(exploreId: ExploreId): ThunkResult<void> {
...
@@ -243,6 +245,17 @@ export function clearQueries(exploreId: ExploreId): ThunkResult<void> {
}
}
/**
/**
* Cancel running queries
*/
export
function
cancelQueries
(
exploreId
:
ExploreId
):
ThunkResult
<
void
>
{
return
dispatch
=>
{
dispatch
(
scanStopAction
({
exploreId
}));
dispatch
(
cancelQueriesAction
({
exploreId
}));
dispatch
(
stateSave
());
};
}
/**
* Loads all explore data sources and sets the chosen datasource.
* Loads all explore data sources and sets the chosen datasource.
* If there are no datasources a missing datasource action is dispatched.
* If there are no datasources a missing datasource action is dispatched.
*/
*/
...
@@ -460,6 +473,7 @@ export const runQueries = (exploreId: ExploreId): ThunkResult<void> => {
...
@@ -460,6 +473,7 @@ export const runQueries = (exploreId: ExploreId): ThunkResult<void> => {
const
transaction
=
buildQueryTransaction
(
queries
,
queryOptions
,
range
,
scanning
);
const
transaction
=
buildQueryTransaction
(
queries
,
queryOptions
,
range
,
scanning
);
let
firstResponse
=
true
;
let
firstResponse
=
true
;
dispatch
(
changeLoadingStateAction
({
exploreId
,
loadingState
:
LoadingState
.
Loading
}));
const
newQuerySub
=
runRequest
(
datasourceInstance
,
transaction
.
request
)
const
newQuerySub
=
runRequest
(
datasourceInstance
,
transaction
.
request
)
.
pipe
(
.
pipe
(
...
...
public/app/features/explore/state/reducers.ts
View file @
40e87536
...
@@ -65,6 +65,7 @@ import {
...
@@ -65,6 +65,7 @@ import {
toggleTableAction
,
toggleTableAction
,
updateDatasourceInstanceAction
,
updateDatasourceInstanceAction
,
updateUIStateAction
,
updateUIStateAction
,
cancelQueriesAction
,
}
from
'./actionTypes'
;
}
from
'./actionTypes'
;
import
{
ResultProcessor
}
from
'../utils/ResultProcessor'
;
import
{
ResultProcessor
}
from
'../utils/ResultProcessor'
;
import
{
updateLocation
}
from
'../../../core/actions'
;
import
{
updateLocation
}
from
'../../../core/actions'
;
...
@@ -236,6 +237,14 @@ export const itemReducer = (state: ExploreItemState = makeExploreItemState(), ac
...
@@ -236,6 +237,14 @@ export const itemReducer = (state: ExploreItemState = makeExploreItemState(), ac
};
};
}
}
if
(
cancelQueriesAction
.
match
(
action
))
{
stopQueryState
(
state
.
querySubscription
);
return
{
...
state
,
loading
:
false
,
};
}
if
(
highlightLogsExpressionAction
.
match
(
action
))
{
if
(
highlightLogsExpressionAction
.
match
(
action
))
{
const
{
expressions
}
=
action
.
payload
;
const
{
expressions
}
=
action
.
payload
;
return
{
...
state
,
logsHighlighterExpressions
:
expressions
};
return
{
...
state
,
logsHighlighterExpressions
:
expressions
};
...
...
public/sass/components/_navbar.scss
View file @
40e87536
...
@@ -155,6 +155,7 @@ i.navbar-page-btn__search {
...
@@ -155,6 +155,7 @@ i.navbar-page-btn__search {
.gicon
{
.gicon
{
filter
:
$navbar-btn-gicon-brightness
;
filter
:
$navbar-btn-gicon-brightness
;
}
}
&
:hover
{
&
:hover
{
.gicon
{
.gicon
{
filter
:
brightness
(
0
.8
);
filter
:
brightness
(
0
.8
);
...
@@ -180,6 +181,10 @@ i.navbar-page-btn__search {
...
@@ -180,6 +181,10 @@ i.navbar-page-btn__search {
}
}
}
}
&
--danger
{
@include
buttonBackground
(
$red-base
,
$red-shade
);
}
@include
media-breakpoint-down
(
lg
)
{
@include
media-breakpoint-down
(
lg
)
{
.btn-title
{
.btn-title
{
margin-left
:
$space-xs
;
margin-left
:
$space-xs
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment