mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
wip: making things work again
This commit is contained in:
parent
fa4fddf7b5
commit
3452ee5a9c
@ -1,4 +1,4 @@
|
||||
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',
|
||||
avatarUrl: 'url/to/avatar',
|
||||
imgUrl: 'url/to/avatar',
|
||||
label: 'User picker label',
|
||||
},
|
||||
className: 'class-for-user-picker',
|
||||
|
@ -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 (
|
||||
|
@ -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 { fadeIn } = this.state;
|
||||
const { children, renderToolbar, heading, toolbarItems } = this.props;
|
||||
const { openView, fadeIn, isOpen } = 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}
|
||||
|
@ -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,
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// };
|
||||
loadHelp = () => {
|
||||
const { currentDS } = this.state;
|
||||
const hasHelp = currentDS.meta.hasQueryHelp;
|
||||
|
||||
// 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}
|
||||
// </>
|
||||
// );
|
||||
// };
|
||||
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 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 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,
|
||||
};
|
||||
|
||||
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)} />
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user