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
16b04160
Unverified
Commit
16b04160
authored
Oct 02, 2019
by
Andrej Ocenas
Committed by
GitHub
Oct 02, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Explore: Move data source loader into the select (#19465)
parent
9a68236d
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
249 additions
and
22 deletions
+249
-22
packages/grafana-ui/.storybook/config.ts
+1
-1
packages/grafana-ui/src/components/Select/Select.tsx
+2
-1
packages/grafana-ui/src/components/Select/SelectOption.tsx
+0
-14
packages/grafana-ui/src/components/Select/SingleValue.tsx
+61
-0
packages/grafana-ui/src/components/Spinner/Spinner.story.tsx
+15
-0
packages/grafana-ui/src/components/Spinner/Spinner.tsx
+33
-0
packages/grafana-ui/src/components/index.ts
+2
-0
packages/grafana-ui/src/components/transitions/FadeTransition.tsx
+43
-0
packages/grafana-ui/src/utils/useDelayedSwitch.story.tsx
+26
-0
packages/grafana-ui/src/utils/useDelayedSwitch.ts
+55
-0
public/app/core/components/Select/DataSourcePicker.tsx
+3
-1
public/app/features/explore/Explore.tsx
+0
-5
public/app/features/explore/ExploreToolbar.tsx
+5
-0
public/app/plugins/datasource/stackdriver/components/__snapshots__/QueryEditor.test.tsx.snap
+3
-0
No files found.
packages/grafana-ui/.storybook/config.ts
View file @
16b04160
...
...
@@ -28,7 +28,7 @@ const handleThemeChange = (theme: string) => {
}
};
// automatically import all files ending in *.stories.tsx
const
req
=
require
.
context
(
'../src
/components
'
,
true
,
/.story.tsx$/
);
const
req
=
require
.
context
(
'../src'
,
true
,
/.story.tsx$/
);
addDecorator
(
withKnobs
);
addDecorator
(
withPaddedStory
);
...
...
packages/grafana-ui/src/components/Select/Select.tsx
View file @
16b04160
...
...
@@ -11,7 +11,8 @@ import { default as ReactAsyncSelect } from '@torkelo/react-select/lib/Async';
import
{
components
}
from
'@torkelo/react-select'
;
// Components
import
{
SelectOption
,
SingleValue
}
from
'./SelectOption'
;
import
{
SelectOption
}
from
'./SelectOption'
;
import
{
SingleValue
}
from
'./SingleValue'
;
import
SelectOptionGroup
from
'./SelectOptionGroup'
;
import
IndicatorsContainer
from
'./IndicatorsContainer'
;
import
NoOptionsMessage
from
'./NoOptionsMessage'
;
...
...
packages/grafana-ui/src/components/Select/SelectOption.tsx
View file @
16b04160
...
...
@@ -30,18 +30,4 @@ export const SelectOption = (props: ExtendedOptionProps) => {
);
};
// was not able to type this without typescript error
export
const
SingleValue
=
(
props
:
any
)
=>
{
const
{
children
,
data
}
=
props
;
return
(
<
components
.
SingleValue
{
...
props
}
>
<
div
className=
"gf-form-select-box__img-value"
>
{
data
.
imgUrl
&&
<
img
className=
"gf-form-select-box__desc-option__img"
src=
{
data
.
imgUrl
}
/>
}
{
children
}
</
div
>
</
components
.
SingleValue
>
);
};
export
default
SelectOption
;
packages/grafana-ui/src/components/Select/SingleValue.tsx
0 → 100644
View file @
16b04160
import
React
from
'react'
;
import
{
css
,
cx
}
from
'emotion'
;
// Ignoring because I couldn't get @types/react-select work wih Torkel's fork
// @ts-ignore
import
{
components
}
from
'@torkelo/react-select'
;
import
{
FadeTransition
,
Spinner
}
from
'..'
;
import
{
useDelayedSwitch
}
from
'../../utils/useDelayedSwitch'
;
import
{
stylesFactory
}
from
'../../themes'
;
const
getStyles
=
stylesFactory
(()
=>
{
const
container
=
css
`
width: 16px;
height: 16px;
display: inline-block;
margin-right: 10px;
position: relative;
vertical-align: middle;
`
;
const
item
=
css
`
width: 100%;
height: 100%;
position: absolute;
`
;
return
{
container
,
item
};
});
type
Props
=
{
children
:
React
.
ReactNode
;
data
:
{
imgUrl
?:
string
;
loading
?:
boolean
;
};
};
export
const
SingleValue
=
(
props
:
Props
)
=>
{
const
{
children
,
data
}
=
props
;
const
styles
=
getStyles
();
const
loading
=
useDelayedSwitch
(
data
.
loading
||
false
,
{
delay
:
250
,
duration
:
750
});
return
(
<
components
.
SingleValue
{
...
props
}
>
<
div
className=
{
cx
(
'gf-form-select-box__img-value'
)
}
>
<
div
className=
{
styles
.
container
}
>
<
FadeTransition
duration=
{
150
}
visible=
{
loading
}
>
<
Spinner
className=
{
styles
.
item
}
inline
/>
</
FadeTransition
>
{
data
.
imgUrl
&&
(
<
FadeTransition
duration=
{
150
}
visible=
{
!
loading
}
>
<
img
className=
{
styles
.
item
}
src=
{
data
.
imgUrl
}
/>
</
FadeTransition
>
)
}
</
div
>
{
children
}
</
div
>
</
components
.
SingleValue
>
);
};
packages/grafana-ui/src/components/Spinner/Spinner.story.tsx
0 → 100644
View file @
16b04160
import
React
from
'react'
;
import
{
storiesOf
}
from
'@storybook/react'
;
import
{
withCenteredStory
}
from
'../../utils/storybook/withCenteredStory'
;
import
{
Spinner
}
from
'./Spinner'
;
const
story
=
storiesOf
(
'UI/Spinner'
,
module
);
story
.
addDecorator
(
withCenteredStory
);
story
.
add
(
'spinner'
,
()
=>
{
return
(
<
div
>
<
Spinner
/>
</
div
>
);
});
packages/grafana-ui/src/components/Spinner/Spinner.tsx
0 → 100644
View file @
16b04160
import
React
,
{
FC
}
from
'react'
;
import
{
cx
,
css
}
from
'emotion'
;
import
{
stylesFactory
}
from
'../../themes'
;
const
getStyles
=
stylesFactory
((
size
:
number
,
inline
:
boolean
)
=>
{
return
{
wrapper
:
css
`
font-size:
${
size
}
px;
${
inline
?
css
`
display: inline-block;
`
:
''
}
`
,
};
});
type
Props
=
{
className
?:
string
;
style
?:
React
.
CSSProperties
;
iconClassName
?:
string
;
inline
?:
boolean
;
size
?:
number
;
};
export
const
Spinner
:
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
{
className
,
inline
=
false
,
iconClassName
,
style
,
size
=
16
}
=
props
;
const
styles
=
getStyles
(
size
,
inline
);
return
(
<
div
style=
{
style
}
className=
{
cx
(
styles
.
wrapper
,
className
)
}
>
<
i
className=
{
cx
(
'fa fa-spinner fa-spin'
,
iconClassName
)
}
/>
</
div
>
);
};
packages/grafana-ui/src/components/index.ts
View file @
16b04160
...
...
@@ -86,3 +86,5 @@ export { JSONFormatter } from './JSONFormatter/JSONFormatter';
export
{
JsonExplorer
}
from
'./JSONFormatter/json_explorer/json_explorer'
;
export
{
ErrorBoundary
,
ErrorBoundaryAlert
}
from
'./ErrorBoundary/ErrorBoundary'
;
export
{
AlphaNotice
}
from
'./AlphaNotice/AlphaNotice'
;
export
{
Spinner
}
from
'./Spinner/Spinner'
;
export
{
FadeTransition
}
from
'./transitions/FadeTransition'
;
packages/grafana-ui/src/components/transitions/FadeTransition.tsx
0 → 100644
View file @
16b04160
import
React
from
'react'
;
import
{
css
}
from
'emotion'
;
import
{
CSSTransition
}
from
'react-transition-group'
;
import
{
stylesFactory
}
from
'../../themes'
;
const
getStyles
=
stylesFactory
((
duration
:
number
)
=>
{
return
{
enter
:
css
`
label: enter;
opacity: 0;
`
,
enterActive
:
css
`
label: enterActive;
opacity: 1;
transition: opacity
${
duration
}
ms ease-out;
`
,
exit
:
css
`
label: exit;
opacity: 1;
`
,
exitActive
:
css
`
label: exitActive;
opacity: 0;
transition: opacity
${
duration
}
ms ease-out;
`
,
};
});
type
Props
=
{
children
:
React
.
ReactNode
;
visible
:
boolean
;
duration
?:
number
;
};
export
function
FadeTransition
(
props
:
Props
)
{
const
{
visible
,
children
,
duration
=
250
}
=
props
;
const
styles
=
getStyles
(
duration
);
return
(
<
CSSTransition
in=
{
visible
}
mountOnEnter=
{
true
}
unmountOnExit=
{
true
}
timeout=
{
duration
}
classNames=
{
styles
}
>
{
children
}
</
CSSTransition
>
);
}
packages/grafana-ui/src/utils/useDelayedSwitch.story.tsx
0 → 100644
View file @
16b04160
import
React
from
'react'
;
import
{
storiesOf
}
from
'@storybook/react'
;
import
{
withCenteredStory
}
from
'./storybook/withCenteredStory'
;
import
{
useDelayedSwitch
}
from
'./useDelayedSwitch'
;
import
{
boolean
,
number
}
from
'@storybook/addon-knobs'
;
const
getKnobs
=
()
=>
{
return
{
value
:
boolean
(
'Value'
,
false
),
duration
:
number
(
'Duration to stay on'
,
2000
),
delay
:
number
(
'Delay before switching on'
,
2000
),
};
};
function
StoryWrapper
()
{
const
{
value
,
delay
=
0
,
duration
=
0
}
=
getKnobs
();
const
valueDelayed
=
useDelayedSwitch
(
value
,
{
delay
,
duration
});
return
<
div
>
{
valueDelayed
?
'ON'
:
'OFF'
}
</
div
>;
}
const
story
=
storiesOf
(
'Utils/useDelayedSwitch'
,
module
);
story
.
addDecorator
(
withCenteredStory
);
story
.
add
(
'useDelayedSwitch'
,
()
=>
{
return
<
StoryWrapper
/>;
});
packages/grafana-ui/src/utils/useDelayedSwitch.ts
0 → 100644
View file @
16b04160
import
{
useEffect
,
useRef
,
useState
}
from
'react'
;
type
DelayOptions
=
{
// Minimal amount of time the switch will be on.
duration
?:
number
;
// Delay after which switch will turn on.
delay
?:
number
;
};
/**
* Hook that delays changing of boolean switch to prevent too much time spent in "on" state. It is kind of a throttle
* but you can specify different time for on and off throttling so this only allows a boolean values and also prefers
* to stay "off" so turning "on" is always delayed while turning "off" is throttled.
*
* This is useful for showing loading elements to prevent it flashing too much in case of quick loading time or
* prevent it flash if loaded state comes right after switch to loading.
*/
export
function
useDelayedSwitch
(
value
:
boolean
,
options
:
DelayOptions
=
{}):
boolean
{
const
{
duration
=
250
,
delay
=
250
}
=
options
;
const
[
delayedValue
,
setDelayedValue
]
=
useState
(
value
);
const
onStartTime
=
useRef
<
Date
|
undefined
>
();
useEffect
(()
=>
{
let
timeout
:
number
|
undefined
;
if
(
value
)
{
// If toggling to "on" state we always setTimout no matter how long we have been "off".
timeout
=
setTimeout
(()
=>
{
onStartTime
.
current
=
new
Date
();
setDelayedValue
(
value
);
},
delay
)
as
any
;
}
else
{
// If toggling to "off" state we check how much time we were already "on".
const
timeSpent
=
onStartTime
.
current
?
Date
.
now
()
-
onStartTime
.
current
.
valueOf
()
:
0
;
const
turnOff
=
()
=>
{
onStartTime
.
current
=
undefined
;
setDelayedValue
(
value
);
};
if
(
timeSpent
>=
duration
)
{
// We already spent enough time "on" so change right away.
turnOff
();
}
else
{
timeout
=
setTimeout
(
turnOff
,
duration
-
timeSpent
)
as
any
;
}
}
return
()
=>
{
if
(
timeout
)
{
clearTimeout
(
timeout
);
timeout
=
undefined
;
}
};
},
[
value
,
duration
,
delay
]);
return
delayedValue
;
}
public/app/core/components/Select/DataSourcePicker.tsx
View file @
16b04160
...
...
@@ -15,6 +15,7 @@ export interface Props {
onBlur
?:
()
=>
void
;
autoFocus
?:
boolean
;
openMenuOnFocus
?:
boolean
;
showLoading
?:
boolean
;
}
export
class
DataSourcePicker
extends
PureComponent
<
Props
>
{
...
...
@@ -35,7 +36,7 @@ export class DataSourcePicker extends PureComponent<Props> {
};
render
()
{
const
{
datasources
,
current
,
autoFocus
,
onBlur
,
openMenuOnFocus
}
=
this
.
props
;
const
{
datasources
,
current
,
autoFocus
,
onBlur
,
openMenuOnFocus
,
showLoading
}
=
this
.
props
;
const
options
=
datasources
.
map
(
ds
=>
({
value
:
ds
.
name
,
...
...
@@ -47,6 +48,7 @@ export class DataSourcePicker extends PureComponent<Props> {
label
:
current
.
name
,
value
:
current
.
name
,
imgUrl
:
current
.
meta
.
info
.
logos
.
small
,
loading
:
showLoading
,
};
return
(
...
...
public/app/features/explore/Explore.tsx
View file @
16b04160
...
...
@@ -67,7 +67,6 @@ interface ExploreProps {
changeSize
:
typeof
changeSize
;
datasourceError
:
string
;
datasourceInstance
:
DataSourceApi
;
datasourceLoading
:
boolean
|
null
;
datasourceMissing
:
boolean
;
exploreId
:
ExploreId
;
initializeExplore
:
typeof
initializeExplore
;
...
...
@@ -251,7 +250,6 @@ export class Explore extends React.PureComponent<ExploreProps> {
StartPage
,
datasourceInstance
,
datasourceError
,
datasourceLoading
,
datasourceMissing
,
exploreId
,
showingStartPage
,
...
...
@@ -272,7 +270,6 @@ export class Explore extends React.PureComponent<ExploreProps> {
return
(
<
div
className=
{
exploreClass
}
ref=
{
this
.
getRef
}
>
<
ExploreToolbar
exploreId=
{
exploreId
}
onChangeTime=
{
this
.
onChangeTime
}
/>
{
datasourceLoading
?
<
div
className=
"explore-container"
>
Loading datasource...
</
div
>
:
null
}
{
datasourceMissing
?
this
.
renderEmptyState
()
:
null
}
<
FadeIn
duration=
{
datasourceError
?
150
:
5
}
in=
{
datasourceError
?
true
:
false
}
>
...
...
@@ -360,7 +357,6 @@ function mapStateToProps(state: StoreState, { exploreId }: ExploreProps): Partia
StartPage
,
datasourceError
,
datasourceInstance
,
datasourceLoading
,
datasourceMissing
,
initialized
,
showingStartPage
,
...
...
@@ -406,7 +402,6 @@ function mapStateToProps(state: StoreState, { exploreId }: ExploreProps): Partia
StartPage
,
datasourceError
,
datasourceInstance
,
datasourceLoading
,
datasourceMissing
,
initialized
,
showingStartPage
,
...
...
public/app/features/explore/ExploreToolbar.tsx
View file @
16b04160
...
...
@@ -68,6 +68,7 @@ interface StateProps {
isPaused
:
boolean
;
originPanelId
:
number
;
queries
:
DataQuery
[];
datasourceLoading
:
boolean
|
null
;
}
interface
DispatchProps
{
...
...
@@ -156,6 +157,7 @@ export class UnConnectedExploreToolbar extends PureComponent<Props, {}> {
isLive
,
isPaused
,
originPanelId
,
datasourceLoading
,
}
=
this
.
props
;
const
styles
=
getStyles
();
...
...
@@ -193,6 +195,7 @@ export class UnConnectedExploreToolbar extends PureComponent<Props, {}> {
onChange=
{
this
.
onChangeDatasource
}
datasources=
{
exploreDatasources
}
current=
{
selectedDatasource
}
showLoading=
{
datasourceLoading
}
/>
</
div
>
{
supportedModes
.
length
>
1
?
(
...
...
@@ -316,6 +319,7 @@ const mapStateToProps = (state: StoreState, { exploreId }: OwnProps): StateProps
isPaused
,
originPanelId
,
queries
,
datasourceLoading
,
}
=
exploreItem
;
const
selectedDatasource
=
datasourceInstance
?
exploreDatasources
.
find
(
datasource
=>
datasource
.
name
===
datasourceInstance
.
name
)
...
...
@@ -339,6 +343,7 @@ const mapStateToProps = (state: StoreState, { exploreId }: OwnProps): StateProps
isPaused
,
originPanelId
,
queries
,
datasourceLoading
,
};
};
...
...
public/app/plugins/datasource/stackdriver/components/__snapshots__/QueryEditor.test.tsx.snap
View file @
16b04160
...
...
@@ -318,6 +318,9 @@ Array [
<div
className="gf-form-select-box__img-value"
>
<div
className="css-zyq2zu"
/>
stackdriver auto
</div>
</div>
...
...
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