mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
react-panels: minor progress on data flow
This commit is contained in:
@@ -5,24 +5,27 @@ import { DashboardModel } from '../dashboard_model';
|
|||||||
import { getAngularLoader, AngularComponent } from 'app/core/services/angular_loader';
|
import { getAngularLoader, AngularComponent } from 'app/core/services/angular_loader';
|
||||||
import { DashboardRow } from './DashboardRow';
|
import { DashboardRow } from './DashboardRow';
|
||||||
import { AddPanelPanel } from './AddPanelPanel';
|
import { AddPanelPanel } from './AddPanelPanel';
|
||||||
import { importPluginModule } from 'app/features/plugins/plugin_loader';
|
import { importPluginModule, PluginExports } from 'app/features/plugins/plugin_loader';
|
||||||
import { PanelChrome } from './PanelChrome';
|
import { PanelChrome } from './PanelChrome';
|
||||||
|
|
||||||
export interface DashboardPanelProps {
|
export interface Props {
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
|
export interface State {
|
||||||
|
pluginExports: PluginExports;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DashboardPanel extends React.Component<Props, State> {
|
||||||
element: any;
|
element: any;
|
||||||
angularPanel: AngularComponent;
|
angularPanel: AngularComponent;
|
||||||
pluginInfo: any;
|
pluginInfo: any;
|
||||||
pluginExports: any;
|
|
||||||
specialPanels = {};
|
specialPanels = {};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {};
|
this.state = { pluginExports: null };
|
||||||
|
|
||||||
this.specialPanels['row'] = this.renderRow.bind(this);
|
this.specialPanels['row'] = this.renderRow.bind(this);
|
||||||
this.specialPanels['add-panel'] = this.renderAddPanel.bind(this);
|
this.specialPanels['add-panel'] = this.renderAddPanel.bind(this);
|
||||||
@@ -32,8 +35,7 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
|
|||||||
|
|
||||||
// load panel plugin
|
// load panel plugin
|
||||||
importPluginModule(this.pluginInfo.module).then(pluginExports => {
|
importPluginModule(this.pluginInfo.module).then(pluginExports => {
|
||||||
this.pluginExports = pluginExports;
|
this.setState({ pluginExports: pluginExports });
|
||||||
this.forceUpdate();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,18 +72,21 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { pluginExports } = this.state;
|
||||||
|
|
||||||
if (this.isSpecial()) {
|
if (this.isSpecial()) {
|
||||||
return this.specialPanels[this.props.panel.type]();
|
return this.specialPanels[this.props.panel.type]();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.pluginExports) {
|
if (!pluginExports) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.pluginExports.PanelComponent) {
|
if (pluginExports.PanelComponent) {
|
||||||
return (
|
return (
|
||||||
<PanelChrome
|
<PanelChrome
|
||||||
component={this.pluginExports.PanelComponent}
|
key="asd"
|
||||||
|
component={pluginExports.PanelComponent}
|
||||||
panel={this.props.panel}
|
panel={this.props.panel}
|
||||||
dashboard={this.props.dashboard}
|
dashboard={this.props.dashboard}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React, { Component, ComponentClass } from 'react';
|
import React, { Component, ComponentClass } from 'react';
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
export interface OuterProps {
|
export interface OuterProps {
|
||||||
type: string;
|
type: string;
|
||||||
@@ -7,16 +6,19 @@ export interface OuterProps {
|
|||||||
isVisible: boolean;
|
isVisible: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AddedProps {
|
export interface PanelProps extends OuterProps {
|
||||||
data: any[];
|
data: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DataPanel extends ComponentClass<OuterProps> {
|
||||||
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
data: any[];
|
data: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DataPanel = (ComposedComponent: ComponentClass<AddedProps & OuterProps>) => {
|
export const DataPanelWrapper = (ComposedComponent: ComponentClass<PanelProps>) => {
|
||||||
class Wrapper extends Component<OuterProps, State> {
|
class Wrapper extends Component<OuterProps, State> {
|
||||||
public static defaultProps = {
|
public static defaultProps = {
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
@@ -32,26 +34,31 @@ const DataPanel = (ComposedComponent: ComponentClass<AddedProps & OuterProps>) =
|
|||||||
}
|
}
|
||||||
|
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
|
console.log('data panel mount');
|
||||||
this.issueQueries();
|
this.issueQueries();
|
||||||
}
|
}
|
||||||
|
|
||||||
public issueQueries = () => {
|
public issueQueries = async () => {
|
||||||
const { queries, isVisible } = this.props;
|
const { isVisible } = this.props;
|
||||||
|
|
||||||
if (!isVisible) {
|
if (!isVisible) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!queries.length) {
|
|
||||||
this.setState({ data: [{ message: 'no queries' }] });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({ isLoading: true });
|
this.setState({ isLoading: true });
|
||||||
|
|
||||||
|
await new Promise(resolve => {
|
||||||
|
setTimeout(() => {
|
||||||
|
|
||||||
|
this.setState({ isLoading: false, data: [{value: 10}] });
|
||||||
|
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const { data, isLoading } = this.state;
|
const { data, isLoading } = this.state;
|
||||||
|
console.log('data panel render');
|
||||||
|
|
||||||
if (!data.length) {
|
if (!data.length) {
|
||||||
return (
|
return (
|
||||||
@@ -76,4 +83,3 @@ const DataPanel = (ComposedComponent: ComponentClass<AddedProps & OuterProps>) =
|
|||||||
return Wrapper;
|
return Wrapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DataPanel;
|
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import React from 'react';
|
import React, { ComponentClass } from 'react';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { PanelModel } from '../panel_model';
|
import { PanelModel } from '../panel_model';
|
||||||
import { DashboardModel } from '../dashboard_model';
|
import { DashboardModel } from '../dashboard_model';
|
||||||
import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants';
|
import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants';
|
||||||
import { PanelHeader } from './PanelHeader';
|
import { PanelHeader } from './PanelHeader';
|
||||||
import { PanelEditor } from './PanelEditor';
|
import { PanelEditor } from './PanelEditor';
|
||||||
|
import { DataPanel, PanelProps, DataPanelWrapper } from './DataPanel';
|
||||||
|
|
||||||
const TITLE_HEIGHT = 27;
|
const TITLE_HEIGHT = 27;
|
||||||
const PANEL_BORDER = 2;
|
const PANEL_BORDER = 2;
|
||||||
@@ -12,33 +13,46 @@ const PANEL_BORDER = 2;
|
|||||||
export interface Props {
|
export interface Props {
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
component: any;
|
component: ComponentClass<PanelProps>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PanelChrome extends React.Component<Props, any> {
|
interface State {
|
||||||
|
height: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PanelChrome extends React.Component<Props, State> {
|
||||||
|
panelComponent: DataPanel;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.props.panel.events.on('panel-size-changed', this.triggerForceUpdate.bind(this));
|
this.state = {
|
||||||
}
|
|
||||||
|
|
||||||
triggerForceUpdate() {
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let panelContentStyle = {
|
|
||||||
height: this.getPanelHeight(),
|
height: this.getPanelHeight(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let PanelComponent = this.props.component;
|
this.panelComponent = DataPanelWrapper(this.props.component);
|
||||||
|
this.props.panel.events.on('panel-size-changed', this.onPanelSizeChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPanelSizeChanged = () => {
|
||||||
|
this.setState({
|
||||||
|
height: this.getPanelHeight(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
console.log('panel chrome mounted');
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let PanelComponent = this.panelComponent;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="panel-height-helper">
|
<div className="panel-height-helper">
|
||||||
<div className="panel-container">
|
<div className="panel-container">
|
||||||
<PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
|
<PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
|
||||||
<div className="panel-content" style={panelContentStyle}>
|
<div className="panel-content" style={{ height: this.state.height }}>
|
||||||
{<PanelComponent />}
|
{<PanelComponent type={'test'} queries={[]} isVisible={true} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{this.props.panel.isEditing && <PanelEditor panel={this.props.panel} dashboard={this.props.dashboard} />}
|
{this.props.panel.isEditing && <PanelEditor panel={this.props.panel} dashboard={this.props.dashboard} />}
|
||||||
|
|||||||
@@ -138,11 +138,22 @@ const flotDeps = [
|
|||||||
'jquery.flot.stackpercent',
|
'jquery.flot.stackpercent',
|
||||||
'jquery.flot.events',
|
'jquery.flot.events',
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let flotDep of flotDeps) {
|
for (let flotDep of flotDeps) {
|
||||||
exposeToPlugin(flotDep, { fakeDep: 1 });
|
exposeToPlugin(flotDep, { fakeDep: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function importPluginModule(path: string): Promise<any> {
|
export interface PluginExports {
|
||||||
|
PanelCtrl?;
|
||||||
|
any;
|
||||||
|
PanelComponent?: any;
|
||||||
|
Datasource?: any;
|
||||||
|
QueryCtrl?: any;
|
||||||
|
ConfigCtrl?: any;
|
||||||
|
AnnotationsQueryCtrl?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function importPluginModule(path: string): Promise<PluginExports> {
|
||||||
let builtIn = builtInPlugins[path];
|
let builtIn = builtInPlugins[path];
|
||||||
if (builtIn) {
|
if (builtIn) {
|
||||||
return Promise.resolve(builtIn);
|
return Promise.resolve(builtIn);
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
import React from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
import { PanelProps } from 'app/features/dashboard/dashgrid/DataPanel';
|
||||||
|
|
||||||
export class ReactTestPanel extends React.Component<any, any> {
|
export class ReactTestPanel extends PureComponent<PanelProps> {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <h2>I am a react panel, haha!</h2>;
|
const { data } = this.props;
|
||||||
|
let value = 0;
|
||||||
|
|
||||||
|
if (data.length) {
|
||||||
|
value = data[0].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <h2>I am a react value: {value}</h2>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user