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
3452ee5a
Commit
3452ee5a
authored
Dec 12, 2018
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wip: making things work again
parent
fa4fddf7
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
212 additions
and
180 deletions
+212
-180
public/app/core/components/Picker/PickerOption.test.tsx
+2
-2
public/app/core/components/Picker/PickerOption.tsx
+2
-1
public/app/features/dashboard/dashgrid/EditorTabBody.tsx
+79
-40
public/app/features/dashboard/dashgrid/QueriesTab.tsx
+129
-137
No files found.
public/app/core/components/Picker/PickerOption.test.tsx
View file @
3452ee5a
import
React
from
'react'
;
import
React
from
'react'
;
import
renderer
from
'react-test-renderer'
;
import
PickerOption
from
'./PickerOption'
;
...
...
@@ -24,7 +24,7 @@ const model = {
children
:
'Model title'
,
data
:
{
title
:
'Model title'
,
avatar
Url
:
'url/to/avatar'
,
img
Url
:
'url/to/avatar'
,
label
:
'User picker label'
,
},
className
:
'class-for-user-picker'
,
...
...
public/app/core/components/Picker/PickerOption.tsx
View file @
3452ee5a
...
...
@@ -27,7 +27,8 @@ export const Option = (props: ExtendedOptionProps) => {
);
};
export
const
SingleValue
=
(
props
:
ExtendedOptionProps
)
=>
{
// was not able to type this without typescript error
export
const
SingleValue
=
props
=>
{
const
{
children
,
data
}
=
props
;
return
(
...
...
public/app/features/dashboard/dashgrid/EditorTabBody.tsx
View file @
3452ee5a
...
...
@@ -5,19 +5,37 @@ import { FadeIn } from 'app/core/components/Animations/FadeIn';
interface
Props
{
children
:
JSX
.
Element
;
heading
:
string
;
renderToolbar
:
()
=>
JSX
.
Element
;
renderToolbar
?:
()
=>
JSX
.
Element
;
toolbarItems
?:
EditorToolBarView
[];
}
export
interface
EditorToolBarView
{
title
:
string
;
imgSrc
?:
string
;
icon
?:
string
;
disabled
?:
boolean
;
onClick
?:
()
=>
void
;
render
:
(
closeFunction
:
any
)
=>
JSX
.
Element
|
JSX
.
Element
[];
}
interface
State
{
openView
?:
EditorToolBarView
;
isOpen
:
boolean
;
fadeIn
:
boolean
;
}
export
class
EditorTabBody
extends
PureComponent
<
Props
,
State
>
{
static
defaultProps
=
{
toolbarItems
:
[],
};
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
openView
:
null
,
fadeIn
:
false
,
isOpen
:
false
,
};
}
...
...
@@ -25,56 +43,77 @@ export class EditorTabBody extends PureComponent<Props, State> {
this
.
setState
({
fadeIn
:
true
});
}
// renderMainSelection(view: EditorToolBarView) {
// return (
// <div className="toolbar__main" onClick={() => this.onToggleToolBarView(view)} key={view.title + view.icon}>
// <img className="toolbar__main-image" src={view.imgSrc} />
// <div className="toolbar__main-name">{view.title}</div>
// <i className="fa fa-caret-down" />
// </div>
// );
// }
//
// renderButton(view: EditorToolBarView) {
// const onClick = () => {
// if (view.onClick) {
// view.onClick();
// }
// this.onToggleToolBarView(view);
// };
//
// return (
// <div className="nav-buttons" key={view.title + view.icon}>
// <button className="btn navbar-button" onClick={onClick} disabled={view.disabled}>
// {view.icon && <i className={view.icon} />} {view.title}
// </button>
// </div>
// );
// }
//
// renderOpenView(view: EditorToolBarView) {
// return (
// <div className="toolbar-subview">
// <button className="toolbar-subview__close" onClick={this.onCloseOpenView}>
// <i className="fa fa-chevron-up" />
// </button>
// {view.render(this.onCloseOpenView)}
// </div>
// );
// }
onToggleToolBarView
=
(
item
:
EditorToolBarView
)
=>
{
this
.
setState
({
openView
:
item
,
isOpen
:
!
this
.
state
.
isOpen
,
});
};
onCloseOpenView
=
()
=>
{
this
.
setState
({
isOpen
:
false
});
};
static
getDerivedStateFromProps
(
props
,
state
)
{
if
(
state
.
openView
)
{
const
activeToolbarItem
=
props
.
toolbarItems
.
find
(
item
=>
item
.
title
===
state
.
openView
.
title
&&
item
.
icon
===
state
.
openView
.
icon
);
if
(
activeToolbarItem
)
{
return
{
...
state
,
openView
:
activeToolbarItem
,
};
}
}
return
state
;
}
renderButton
(
view
:
EditorToolBarView
)
{
const
onClick
=
()
=>
{
if
(
view
.
onClick
)
{
view
.
onClick
();
}
this
.
onToggleToolBarView
(
view
);
};
return
(
<
div
className=
"nav-buttons"
key=
{
view
.
title
+
view
.
icon
}
>
<
button
className=
"btn navbar-button"
onClick=
{
onClick
}
disabled=
{
view
.
disabled
}
>
{
view
.
icon
&&
<
i
className=
{
view
.
icon
}
/>
}
{
view
.
title
}
</
button
>
</
div
>
);
}
renderOpenView
(
view
:
EditorToolBarView
)
{
return
(
<
div
className=
"toolbar-subview"
>
<
button
className=
"toolbar-subview__close"
onClick=
{
this
.
onCloseOpenView
}
>
<
i
className=
"fa fa-chevron-up"
/>
</
button
>
{
view
.
render
(
this
.
onCloseOpenView
)
}
</
div
>
);
}
render
()
{
const
{
children
,
renderToolbar
,
heading
}
=
this
.
props
;
const
{
fadeI
n
}
=
this
.
state
;
const
{
children
,
renderToolbar
,
heading
,
toolbarItems
}
=
this
.
props
;
const
{
openView
,
fadeIn
,
isOpe
n
}
=
this
.
state
;
return
(
<>
<
div
className=
"toolbar"
>
<
div
className=
"toolbar__heading"
>
{
heading
}
</
div
>
{
renderToolbar
&&
renderToolbar
()
}
<
div
className=
"gf-form--grow"
/>
{
toolbarItems
.
map
(
item
=>
this
.
renderButton
(
item
))
}
</
div
>
<
div
className=
"panel-editor__scroll"
>
<
CustomScrollbar
autoHide=
{
false
}
>
<
FadeIn
in=
{
isOpen
}
duration=
{
200
}
unmountOnExit=
{
true
}
>
<
div
className=
"panel-editor__toolbar-view"
>
{
openView
&&
this
.
renderOpenView
(
openView
)
}
</
div
>
</
FadeIn
>
<
div
className=
"panel-editor__content"
>
<
FadeIn
in=
{
fadeIn
}
duration=
{
50
}
>
{
children
}
...
...
public/app/features/dashboard/dashgrid/QueriesTab.tsx
View file @
3452ee5a
...
...
@@ -30,8 +30,8 @@ interface Props {
interface
State
{
currentDS
:
DataSourceSelectItem
;
helpContent
:
JSX
.
Element
;
isLoadingHelp
:
string
;
helpContent
:
JSX
.
Element
|
string
;
isLoadingHelp
:
boolean
;
isPickerOpen
:
boolean
;
}
...
...
@@ -126,113 +126,113 @@ export class QueriesTab extends PureComponent<Props, State> {
});
};
//
loadHelp = () => {
// const { currentDatasource
} = this.state;
// const hasHelp = currentDatasource
.meta.hasQueryHelp;
//
//
if (hasHelp) {
//
this.setState({
//
helpContent: <h2>Loading help...</h2>,
// isLoadingHelp: true
//
});
//
//
this.backendSrv
// .get(`/api/plugins/${currentDatasource
.meta.id}/markdown/query_help`)
//
.then(res => {
//
const md = new Remarkable();
// const helpHtml = md.render(res); // TODO: Clean out dangerous code? Previous: this.helpHtml = this.$sce.trustAsHtml(md.render(res)
);
//
this.setState({
//
helpContent: <div className="markdown-html" dangerouslySetInnerHTML={{ __html: helpHtml }} />,
// isLoadingHelp: false
//
});
//
})
//
.catch(() => {
//
this.setState({
//
helpContent: 'Error occured when loading help',
//
isLoadingHelp: false,
//
});
//
});
//
}
//
};
//
renderOptions = close => {
// const { currentDatasource
} = this.state;
// const { queryOptions } = currentDatasource
.meta;
//
const { panel } = this.props;
//
//
const onChangeFn = (panelKey: string) => {
//
return (value: string | number) => {
//
panel[panelKey] = value;
//
panel.refresh();
//
};
//
};
//
//
const allOptions = {
//
cacheTimeout: {
//
label: 'Cache timeout',
//
placeholder: '60',
//
name: 'cacheTimeout',
//
value: panel.cacheTimeout,
//
tooltipInfo: (
//
<>
//
If your time series store has a query cache this option can override the default cache timeout. Specify a
//
numeric value in seconds.
//
</>
//
),
//
},
//
maxDataPoints: {
//
label: 'Max data points',
//
placeholder: 'auto',
//
name: 'maxDataPoints',
//
value: panel.maxDataPoints,
//
tooltipInfo: (
//
<>
//
The maximum data points the query should return. For graphs this is automatically set to one data point per
//
pixel.
//
</>
//
),
//
},
//
minInterval: {
//
label: 'Min time interval',
//
placeholder: '0',
//
name: 'minInterval',
//
value: panel.interval,
//
panelKey: 'interval',
//
tooltipInfo: (
//
<>
//
A lower limit for the auto group by time interval. Recommended to be set to write frequency, for example{' '}
//
<code>1m</code> if your data is written every minute. Access auto interval via variable{' '}
//
<code>$__interval</code> for time range string and <code>$__interval_ms</code> for numeric variable that can
//
be used in math expressions.
//
</>
//
),
//
},
//
};
//
//
const dsOptions = queryOptions
//
? Object.keys(queryOptions).map(key => {
//
const options = allOptions[key];
//
return <DataSourceOption key={key} {...options} onChange={onChangeFn(allOptions[key].panelKey || key)} />;
//
})
//
: null;
//
//
return (
//
<>
//
<TimeRangeOptions panel={this.props.panel} />
//
{dsOptions}
//
</>
//
);
//
};
loadHelp
=
()
=>
{
const
{
currentDS
}
=
this
.
state
;
const
hasHelp
=
currentDS
.
meta
.
hasQueryHelp
;
if
(
hasHelp
)
{
this
.
setState
({
helpContent
:
<
h2
>
Loading help...
</
h2
>,
isLoadingHelp
:
true
,
});
this
.
backendSrv
.
get
(
`/api/plugins/
${
currentDS
.
meta
.
id
}
/markdown/query_help`
)
.
then
(
res
=>
{
const
md
=
new
Remarkable
();
const
helpHtml
=
md
.
render
(
res
);
this
.
setState
({
helpContent
:
<
div
className=
"markdown-html"
dangerouslySetInnerHTML=
{
{
__html
:
helpHtml
}
}
/>,
isLoadingHelp
:
false
,
});
})
.
catch
(()
=>
{
this
.
setState
({
helpContent
:
'Error occured when loading help'
,
isLoadingHelp
:
false
,
});
});
}
};
renderOptions
=
close
=>
{
const
{
currentDS
}
=
this
.
state
;
const
{
queryOptions
}
=
currentDS
.
meta
;
const
{
panel
}
=
this
.
props
;
const
onChangeFn
=
(
panelKey
:
string
)
=>
{
return
(
value
:
string
|
number
)
=>
{
panel
[
panelKey
]
=
value
;
panel
.
refresh
();
};
};
const
allOptions
=
{
cacheTimeout
:
{
label
:
'Cache timeout'
,
placeholder
:
'60'
,
name
:
'cacheTimeout'
,
value
:
panel
.
cacheTimeout
,
tooltipInfo
:
(
<>
If your time series store has a query cache this option can override the default cache timeout. Specify a
numeric value in seconds.
</>
),
},
maxDataPoints
:
{
label
:
'Max data points'
,
placeholder
:
'auto'
,
name
:
'maxDataPoints'
,
value
:
panel
.
maxDataPoints
,
tooltipInfo
:
(
<>
The maximum data points the query should return. For graphs this is automatically set to one data point per
pixel.
</>
),
},
minInterval
:
{
label
:
'Min time interval'
,
placeholder
:
'0'
,
name
:
'minInterval'
,
value
:
panel
.
interval
,
panelKey
:
'interval'
,
tooltipInfo
:
(
<>
A lower limit for the auto group by time interval. Recommended to be set to write frequency, for example
{
' '
}
<
code
>
1m
</
code
>
if your data is written every minute. Access auto interval via variable
{
' '
}
<
code
>
$__interval
</
code
>
for time range string and
<
code
>
$__interval_ms
</
code
>
for numeric variable that can
be used in math expressions.
</>
),
},
};
const
dsOptions
=
queryOptions
?
Object
.
keys
(
queryOptions
).
map
(
key
=>
{
const
options
=
allOptions
[
key
];
return
<
DataSourceOption
key=
{
key
}
{
...
options
}
onChange=
{
onChangeFn
(
allOptions
[
key
].
panelKey
||
key
)
}
/>;
})
:
null
;
return
(
<>
<
TimeRangeOptions
panel=
{
this
.
props
.
panel
}
/>
{
dsOptions
}
</>
);
};
renderQueryInspector
=
()
=>
{
const
{
panel
}
=
this
.
props
;
return
<
QueryInspector
panel=
{
panel
}
LoadingPlaceholder=
{
LoadingPlaceholder
}
/>;
};
//
renderHelp = () => {
// const { helpHtml, isLoading } = this.state.help
;
// return isLoading ? <LoadingPlaceholder text="Loading help..." /> : helpHtml
;
//
};
renderHelp
=
()
=>
{
const
{
helpContent
,
isLoadingHelp
}
=
this
.
state
;
return
isLoadingHelp
?
<
LoadingPlaceholder
text=
"Loading help..."
/>
:
helpContent
;
};
onAddQuery
=
(
query
?:
DataQuery
)
=>
{
this
.
props
.
panel
.
addQuery
(
query
);
...
...
@@ -278,43 +278,35 @@ export class QueriesTab extends PureComponent<Props, State> {
render
()
{
const
{
panel
}
=
this
.
props
;
const
{
currentDS
}
=
this
.
state
;
const
{
hasQueryHelp
}
=
currentDS
.
meta
;
const
queryInspector
=
{
title
:
'Query Inspector'
,
render
:
this
.
renderQueryInspector
,
};
// const dsInformation = {
// title: currentDatasource.name,
// imgSrc: currentDatasource.meta.info.logos.small,
// render: closeOpenView => (
// <DataSourcePicker
// datasources={this.datasources}
// onChangeDataSource={ds => {
// closeOpenView();
// this.onChangeDataSource(ds);
// }}
// />
// ),
// };
//
// const queryInspector = {
// title: 'Query Inspector',
// render: this.renderQueryInspector,
// };
//
// const dsHelp = {
// title: '',
// icon: 'fa fa-question',
// disabled: !hasQueryHelp,
// onClick: this.loadHelp,
// render: this.renderHelp,
// };
//
// const options = {
// title: 'Time Range',
// icon: '',
// disabled: false,
// render: this.renderOptions,
// };
const
dsHelp
=
{
title
:
''
,
icon
:
'fa fa-question'
,
disabled
:
!
hasQueryHelp
,
onClick
:
this
.
loadHelp
,
render
:
this
.
renderHelp
,
};
const
options
=
{
title
:
'Time Range'
,
icon
:
''
,
disabled
:
false
,
render
:
this
.
renderOptions
,
};
return
(
<
EditorTabBody
heading=
"Queries"
renderToolbar=
{
this
.
renderToolbar
}
>
<
EditorTabBody
heading=
"Queries"
renderToolbar=
{
this
.
renderToolbar
}
toolbarItems=
{
[
options
,
queryInspector
,
dsHelp
]
}
>
<
div
className=
"query-editor-rows gf-form-group"
>
<
div
ref=
{
element
=>
(
this
.
element
=
element
)
}
/>
...
...
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