mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
react panel minor progress
This commit is contained in:
parent
35403c1875
commit
aa5c9f199a
@ -175,11 +175,10 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
|
||||
const panelElements = [];
|
||||
|
||||
for (let panel of this.dashboard.panels) {
|
||||
console.log('panel.fullscreen', panel.fullscreen);
|
||||
const panelClasses = classNames({ panel: true, 'panel--fullscreen': panel.fullscreen });
|
||||
panelElements.push(
|
||||
<div key={panel.id.toString()} className={panelClasses}>
|
||||
<DashboardPanel panel={panel} dashboard={this.dashboard} />
|
||||
<DashboardPanel panel={panel} dashboard={this.dashboard} panelContainer={this.panelContainer} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,22 +1,18 @@
|
||||
import React from 'react';
|
||||
import $ from 'jquery';
|
||||
import config from 'app/core/config';
|
||||
import classNames from 'classnames';
|
||||
import { PanelModel } from '../panel_model';
|
||||
import { DashboardModel } from '../dashboard_model';
|
||||
import { AttachedPanel } from './PanelLoader';
|
||||
import { DashboardRow } from './DashboardRow';
|
||||
import { PanelContainer } from './PanelContainer';
|
||||
import { AddPanelPanel } from './AddPanelPanel';
|
||||
import { importPluginModule } from 'app/features/plugins/plugin_loader';
|
||||
import { store } from 'app/stores/store';
|
||||
import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants';
|
||||
|
||||
const TITLE_HEIGHT = 27;
|
||||
const PANEL_BORDER = 2;
|
||||
import { PanelChrome } from './PanelChrome';
|
||||
|
||||
export interface DashboardPanelProps {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
panelContainer: PanelContainer;
|
||||
}
|
||||
|
||||
export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
|
||||
@ -56,140 +52,44 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
|
||||
return <AddPanelPanel panel={this.props.panel} dashboard={this.props.dashboard} />;
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
// skip loading angular component if we have no element
|
||||
// or we have already loaded it
|
||||
if (!this.element || this.attachedPanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const loader = this.props.panelContainer.getPanelLoader();
|
||||
this.attachedPanel = loader.load(this.element, this.props.panel, this.props.dashboard);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.attachedPanel) {
|
||||
this.attachedPanel.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.isSpecial()) {
|
||||
return this.specialPanels[this.props.panel.type]();
|
||||
}
|
||||
|
||||
let PanelComponent = null;
|
||||
|
||||
if (this.pluginExports && this.pluginExports.PanelComponent) {
|
||||
PanelComponent = this.pluginExports.PanelComponent;
|
||||
if (!this.pluginExports) {
|
||||
console.log('render null');
|
||||
return null;
|
||||
}
|
||||
|
||||
let panelContentStyle = {
|
||||
height: this.getPanelHeight(),
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="panel-container">
|
||||
<PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
|
||||
<div className="panel-content" style={panelContentStyle}>
|
||||
{PanelComponent && <PanelComponent />}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{this.props.panel.isEditing && <PanelEditor panel={this.props.panel} dashboard={this.props.dashboard} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getPanelHeight() {
|
||||
const panel = this.props.panel;
|
||||
let height = 0;
|
||||
|
||||
if (panel.fullscreen) {
|
||||
var docHeight = $(window).height();
|
||||
var editHeight = Math.floor(docHeight * 0.4);
|
||||
var fullscreenHeight = Math.floor(docHeight * 0.8);
|
||||
height = panel.isEditing ? editHeight : fullscreenHeight;
|
||||
} else {
|
||||
height = panel.gridPos.h * GRID_CELL_HEIGHT + (panel.gridPos.h - 1) * GRID_CELL_VMARGIN;
|
||||
if (this.pluginExports.PanelComponent) {
|
||||
return (
|
||||
<PanelChrome
|
||||
component={this.pluginExports.PanelComponent}
|
||||
panel={this.props.panel}
|
||||
dashboard={this.props.dashboard}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return height - PANEL_BORDER + TITLE_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
interface PanelHeaderProps {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
}
|
||||
|
||||
export class PanelHeader extends React.Component<PanelHeaderProps, any> {
|
||||
onEditPanel = () => {
|
||||
store.view.updateQuery({
|
||||
panelId: this.props.panel.id,
|
||||
edit: true,
|
||||
fullscreen: true,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
let isFullscreen = false;
|
||||
let isLoading = false;
|
||||
let panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
|
||||
|
||||
return (
|
||||
<div className={panelHeaderClass}>
|
||||
<span className="panel-info-corner">
|
||||
<i className="fa" />
|
||||
<span className="panel-info-corner-inner" />
|
||||
</span>
|
||||
|
||||
{isLoading && (
|
||||
<span className="panel-loading">
|
||||
<i className="fa fa-spinner fa-spin" />
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className="panel-title-container">
|
||||
<span className="panel-title">
|
||||
<span className="icon-gf panel-alert-icon" />
|
||||
<span className="panel-title-text">{this.props.panel.title}</span>
|
||||
<span className="panel-menu-container dropdown">
|
||||
<span className="fa fa-caret-down panel-menu-toggle" data-toggle="dropdown" />
|
||||
<ul className="dropdown-menu dropdown-menu--menu panel-menu" role="menu">
|
||||
<li>
|
||||
<a onClick={this.onEditPanel}>
|
||||
<i className="fa fa-fw fa-edit" /> Edit
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="asd">asd</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
<span className="panel-time-info">
|
||||
<i className="fa fa-clock-o" /> 4m
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface PanelEditorProps {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
}
|
||||
|
||||
export class PanelEditor extends React.Component<PanelEditorProps, any> {
|
||||
render() {
|
||||
return (
|
||||
<div className="tabbed-view tabbed-view--panel-edit">
|
||||
<div className="tabbed-view-header">
|
||||
<h3 className="tabbed-view-panel-title">{this.props.panel.type}</h3>
|
||||
|
||||
<ul className="gf-tabs">
|
||||
<li className="gf-tabs-item">
|
||||
<a className="gf-tabs-link active">Queries</a>
|
||||
</li>
|
||||
<li className="gf-tabs-item">
|
||||
<a className="gf-tabs-link">Visualization</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button className="tabbed-view-close-btn" ng-click="ctrl.exitFullscreen();">
|
||||
<i className="fa fa-remove" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="tabbed-view-body">testing</div>
|
||||
</div>
|
||||
);
|
||||
// legacy angular rendering
|
||||
return <div ref={element => (this.element = element)} className="panel-height-helper" />;
|
||||
}
|
||||
}
|
||||
|
66
public/app/features/dashboard/dashgrid/PanelChrome.tsx
Normal file
66
public/app/features/dashboard/dashgrid/PanelChrome.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import React from 'react';
|
||||
import $ from 'jquery';
|
||||
import { PanelModel } from '../panel_model';
|
||||
import { DashboardModel } from '../dashboard_model';
|
||||
import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants';
|
||||
import { PanelHeader } from './PanelHeader';
|
||||
import { PanelEditor } from './PanelEditor';
|
||||
|
||||
const TITLE_HEIGHT = 27;
|
||||
const PANEL_BORDER = 2;
|
||||
|
||||
export interface PanelChromeProps {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
component: any;
|
||||
}
|
||||
|
||||
export class PanelChrome extends React.Component<PanelChromeProps, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.props.panel.events.on('panel-size-changed', this.triggerForceUpdate.bind(this));
|
||||
}
|
||||
|
||||
triggerForceUpdate() {
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
render() {
|
||||
let panelContentStyle = {
|
||||
height: this.getPanelHeight(),
|
||||
};
|
||||
|
||||
let PanelComponent = this.props.component;
|
||||
|
||||
return (
|
||||
<div className="panel-height-helper">
|
||||
<div className="panel-container">
|
||||
<PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
|
||||
<div className="panel-content" style={panelContentStyle}>
|
||||
{<PanelComponent />}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{this.props.panel.isEditing && <PanelEditor panel={this.props.panel} dashboard={this.props.dashboard} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getPanelHeight() {
|
||||
const panel = this.props.panel;
|
||||
let height = 0;
|
||||
|
||||
if (panel.fullscreen) {
|
||||
var docHeight = $(window).height();
|
||||
var editHeight = Math.floor(docHeight * 0.4);
|
||||
var fullscreenHeight = Math.floor(docHeight * 0.8);
|
||||
height = panel.isEditing ? editHeight : fullscreenHeight;
|
||||
} else {
|
||||
height = panel.gridPos.h * GRID_CELL_HEIGHT + (panel.gridPos.h - 1) * GRID_CELL_VMARGIN;
|
||||
}
|
||||
|
||||
return height - PANEL_BORDER + TITLE_HEIGHT;
|
||||
}
|
||||
}
|
35
public/app/features/dashboard/dashgrid/PanelEditor.tsx
Normal file
35
public/app/features/dashboard/dashgrid/PanelEditor.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import { PanelModel } from '../panel_model';
|
||||
import { DashboardModel } from '../dashboard_model';
|
||||
|
||||
interface PanelEditorProps {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
}
|
||||
|
||||
export class PanelEditor extends React.Component<PanelEditorProps, any> {
|
||||
render() {
|
||||
return (
|
||||
<div className="tabbed-view tabbed-view--panel-edit">
|
||||
<div className="tabbed-view-header">
|
||||
<h3 className="tabbed-view-panel-title">{this.props.panel.type}</h3>
|
||||
|
||||
<ul className="gf-tabs">
|
||||
<li className="gf-tabs-item">
|
||||
<a className="gf-tabs-link active">Queries</a>
|
||||
</li>
|
||||
<li className="gf-tabs-item">
|
||||
<a className="gf-tabs-link">Visualization</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button className="tabbed-view-close-btn" ng-click="ctrl.exitFullscreen();">
|
||||
<i className="fa fa-remove" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="tabbed-view-body">testing</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
64
public/app/features/dashboard/dashgrid/PanelHeader.tsx
Normal file
64
public/app/features/dashboard/dashgrid/PanelHeader.tsx
Normal file
@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { PanelModel } from '../panel_model';
|
||||
import { DashboardModel } from '../dashboard_model';
|
||||
import { store } from 'app/stores/store';
|
||||
|
||||
interface PanelHeaderProps {
|
||||
panel: PanelModel;
|
||||
dashboard: DashboardModel;
|
||||
}
|
||||
|
||||
export class PanelHeader extends React.Component<PanelHeaderProps, any> {
|
||||
onEditPanel = () => {
|
||||
store.view.updateQuery({
|
||||
panelId: this.props.panel.id,
|
||||
edit: true,
|
||||
fullscreen: true,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
let isFullscreen = false;
|
||||
let isLoading = false;
|
||||
let panelHeaderClass = classNames({ 'panel-header': true, 'grid-drag-handle': !isFullscreen });
|
||||
|
||||
return (
|
||||
<div className={panelHeaderClass}>
|
||||
<span className="panel-info-corner">
|
||||
<i className="fa" />
|
||||
<span className="panel-info-corner-inner" />
|
||||
</span>
|
||||
|
||||
{isLoading && (
|
||||
<span className="panel-loading">
|
||||
<i className="fa fa-spinner fa-spin" />
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className="panel-title-container">
|
||||
<span className="panel-title">
|
||||
<span className="icon-gf panel-alert-icon" />
|
||||
<span className="panel-title-text">{this.props.panel.title}</span>
|
||||
<span className="panel-menu-container dropdown">
|
||||
<span className="fa fa-caret-down panel-menu-toggle" data-toggle="dropdown" />
|
||||
<ul className="dropdown-menu dropdown-menu--menu panel-menu" role="menu">
|
||||
<li>
|
||||
<a onClick={this.onEditPanel}>
|
||||
<i className="fa fa-fw fa-edit" /> Edit
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="asd">asd</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
<span className="panel-time-info">
|
||||
<i className="fa fa-clock-o" /> 4m
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ jest.mock('app/core/store', () => ({
|
||||
}));
|
||||
|
||||
describe('AddPanelPanel', () => {
|
||||
let wrapper, dashboardMock, getPanelContainer, panel;
|
||||
let wrapper, dashboardMock, panel;
|
||||
|
||||
beforeEach(() => {
|
||||
config.panels = [
|
||||
|
Loading…
Reference in New Issue
Block a user