poc: began react panel experiments, step2

This commit is contained in:
Torkel Ödegaard 2018-01-03 13:33:54 +01:00
parent 3eb5f23209
commit 456b4d2a66
7 changed files with 60 additions and 101 deletions

View File

@ -1,40 +0,0 @@
define([
'lodash',
'jquery',
'../core_module',
],
function (_, $, coreModule) {
'use strict';
coreModule.default.directive('dashClass', function() {
return {
link: function($scope, elem) {
$scope.onAppEvent('panel-fullscreen-enter', function() {
elem.toggleClass('panel-in-fullscreen', true);
});
$scope.onAppEvent('panel-fullscreen-exit', function() {
elem.toggleClass('panel-in-fullscreen', false);
});
$scope.$watch('ctrl.playlistSrv.isPlaying', function(newValue) {
elem.toggleClass('playlist-active', newValue === true);
});
$scope.$watch('ctrl.dashboardViewState.state.editview', function(newValue) {
if (newValue) {
elem.toggleClass('dashboard-page--settings-opening', _.isString(newValue));
setTimeout(function() {
elem.toggleClass('dashboard-page--settings-open', _.isString(newValue));
}, 10);
} else {
elem.removeClass('dashboard-page--settings-opening');
elem.removeClass('dashboard-page--settings-open');
}
});
}
};
});
});

View File

@ -0,0 +1,34 @@
import _ from 'lodash';
import coreModule from '../core_module';
coreModule.directive('dashClass', function($timeout) {
return {
link: function($scope, elem) {
$scope.ctrl.dashboard.events.on('view-mode-changed', function(panel) {
$timeout(() => {
elem.toggleClass('panel-in-fullscreen', panel.fullscreen === true);
});
});
$scope.onAppEvent('panel-fullscreen-exit', function() {
elem.toggleClass('panel-in-fullscreen', false);
});
$scope.$watch('ctrl.playlistSrv.isPlaying', function(newValue) {
elem.toggleClass('playlist-active', newValue === true);
});
$scope.$watch('ctrl.dashboardViewState.state.editview', function(newValue) {
if (newValue) {
elem.toggleClass('dashboard-page--settings-opening', _.isString(newValue));
setTimeout(function() {
elem.toggleClass('dashboard-page--settings-open', _.isString(newValue));
}, 10);
} else {
elem.removeClass('dashboard-page--settings-opening');
elem.removeClass('dashboard-page--settings-open');
}
});
},
};
});

View File

@ -3,14 +3,14 @@ import _ from 'lodash';
import config from 'app/core/config'; import config from 'app/core/config';
import { PanelModel } from '../panel_model'; import { PanelModel } from '../panel_model';
import { PanelContainer } from './PanelContainer'; import { DashboardModel } from '../dashboard_model';
import ScrollBar from 'app/core/components/ScrollBar/ScrollBar'; import ScrollBar from 'app/core/components/ScrollBar/ScrollBar';
import store from 'app/core/store'; import store from 'app/core/store';
import { LS_PANEL_COPY_KEY } from 'app/core/constants'; import { LS_PANEL_COPY_KEY } from 'app/core/constants';
export interface AddPanelPanelProps { export interface AddPanelPanelProps {
panel: PanelModel; panel: PanelModel;
getPanelContainer: () => PanelContainer; dashboard: DashboardModel;
} }
export interface AddPanelPanelState { export interface AddPanelPanelState {
@ -55,8 +55,7 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
} }
onAddPanel = panelPluginInfo => { onAddPanel = panelPluginInfo => {
const panelContainer = this.props.getPanelContainer(); const dashboard = this.props.dashboard;
const dashboard = panelContainer.getDashboard();
const { gridPos } = this.props.panel; const { gridPos } = this.props.panel;
var newPanel: any = { var newPanel: any = {

View File

@ -50,7 +50,8 @@ function GridWrapper({
onResize={onResize} onResize={onResize}
onResizeStop={onResizeStop} onResizeStop={onResizeStop}
onDragStop={onDragStop} onDragStop={onDragStop}
onLayoutChange={onLayoutChange}> onLayoutChange={onLayoutChange}
>
{children} {children}
</ReactGridLayout> </ReactGridLayout>
); );
@ -177,8 +178,8 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
const panelClasses = classNames({ panel: true, 'panel--fullscreen': panel.fullscreen }); const panelClasses = classNames({ panel: true, 'panel--fullscreen': panel.fullscreen });
panelElements.push( panelElements.push(
<div key={panel.id.toString()} className={panelClasses}> <div key={panel.id.toString()} className={panelClasses}>
<DashboardPanel panel={panel} getPanelContainer={this.props.getPanelContainer} /> <DashboardPanel panel={panel} dashboard={this.dashboard} />
</div>, </div>
); );
} }
@ -196,7 +197,8 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
onWidthChange={this.onWidthChange} onWidthChange={this.onWidthChange}
onDragStop={this.onDragStop} onDragStop={this.onDragStop}
onResize={this.onResize} onResize={this.onResize}
onResizeStop={this.onResizeStop}> onResizeStop={this.onResizeStop}
>
{this.renderPanels()} {this.renderPanels()}
</SizedReactLayoutGrid> </SizedReactLayoutGrid>
); );

View File

@ -3,7 +3,7 @@ import config from 'app/core/config';
import classNames from 'classnames'; import classNames from 'classnames';
import appEvents from 'app/core/app_events'; import appEvents from 'app/core/app_events';
import { PanelModel } from '../panel_model'; import { PanelModel } from '../panel_model';
import { PanelContainer } from './PanelContainer'; import { DashboardModel } from '../dashboard_model';
import { AttachedPanel } from './PanelLoader'; import { AttachedPanel } from './PanelLoader';
import { DashboardRow } from './DashboardRow'; import { DashboardRow } from './DashboardRow';
import { AddPanelPanel } from './AddPanelPanel'; import { AddPanelPanel } from './AddPanelPanel';
@ -11,7 +11,7 @@ import { importPluginModule } from 'app/features/plugins/plugin_loader';
export interface DashboardPanelProps { export interface DashboardPanelProps {
panel: PanelModel; panel: PanelModel;
getPanelContainer: () => PanelContainer; dashboard: DashboardModel;
} }
export class DashboardPanel extends React.Component<DashboardPanelProps, any> { export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
@ -39,33 +39,16 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
} }
} }
componentDidMount() {
if (!this.element) {
return;
}
const panelContainer = this.props.getPanelContainer();
const dashboard = panelContainer.getDashboard();
const loader = panelContainer.getPanelLoader();
this.attachedPanel = loader.load(this.element, this.props.panel, dashboard);
}
componentWillUnmount() {
if (this.attachedPanel) {
this.attachedPanel.destroy();
}
}
isSpecial() { isSpecial() {
return this.specialPanels[this.props.panel.type]; return this.specialPanels[this.props.panel.type];
} }
renderRow() { renderRow() {
return <DashboardRow panel={this.props.panel} getPanelContainer={this.props.getPanelContainer} />; return <DashboardRow panel={this.props.panel} dashboard={this.props.dashboard} />;
} }
renderAddPanel() { renderAddPanel() {
return <AddPanelPanel panel={this.props.panel} getPanelContainer={this.props.getPanelContainer} />; return <AddPanelPanel panel={this.props.panel} dashboard={this.props.dashboard} />;
} }
render() { render() {
@ -81,7 +64,7 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
return ( return (
<div className="panel-container"> <div className="panel-container">
<PanelHeader panel={this.props.panel} /> <PanelHeader panel={this.props.panel} dashboard={this.props.dashboard} />
<div className="panel-content">{PanelComponent && <PanelComponent />}</div> <div className="panel-content">{PanelComponent && <PanelComponent />}</div>
</div> </div>
); );
@ -93,16 +76,13 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
} }
interface PanelHeaderProps { interface PanelHeaderProps {
panel: any; panel: PanelModel;
dashboard: DashboardModel;
} }
export class PanelHeader extends React.Component<PanelHeaderProps, any> { export class PanelHeader extends React.Component<PanelHeaderProps, any> {
onEditPanel = () => { onEditPanel = () => {
appEvents.emit('panel-change-view', { this.props.dashboard.setViewMode(this.props.panel, true, true);
fullscreen: true,
edit: true,
panelId: this.props.panel.id,
});
}; };
render() { render() {

View File

@ -1,19 +1,16 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { PanelModel } from '../panel_model'; import { PanelModel } from '../panel_model';
import { PanelContainer } from './PanelContainer'; import { DashboardModel } from '../dashboard_model';
import templateSrv from 'app/features/templating/template_srv'; import templateSrv from 'app/features/templating/template_srv';
import appEvents from 'app/core/app_events'; import appEvents from 'app/core/app_events';
export interface DashboardRowProps { export interface DashboardRowProps {
panel: PanelModel; panel: PanelModel;
getPanelContainer: () => PanelContainer; dashboard: DashboardModel;
} }
export class DashboardRow extends React.Component<DashboardRowProps, any> { export class DashboardRow extends React.Component<DashboardRowProps, any> {
dashboard: any;
panelContainer: any;
constructor(props) { constructor(props) {
super(props); super(props);
@ -21,16 +18,13 @@ export class DashboardRow extends React.Component<DashboardRowProps, any> {
collapsed: this.props.panel.collapsed, collapsed: this.props.panel.collapsed,
}; };
this.panelContainer = this.props.getPanelContainer();
this.dashboard = this.panelContainer.getDashboard();
this.toggle = this.toggle.bind(this); this.toggle = this.toggle.bind(this);
this.openSettings = this.openSettings.bind(this); this.openSettings = this.openSettings.bind(this);
this.delete = this.delete.bind(this); this.delete = this.delete.bind(this);
} }
toggle() { toggle() {
this.dashboard.toggleRow(this.props.panel); this.props.dashboard.toggleRow(this.props.panel);
this.setState(prevState => { this.setState(prevState => {
return { collapsed: !prevState.collapsed }; return { collapsed: !prevState.collapsed };
@ -55,14 +49,10 @@ export class DashboardRow extends React.Component<DashboardRowProps, any> {
altActionText: 'Delete row only', altActionText: 'Delete row only',
icon: 'fa-trash', icon: 'fa-trash',
onConfirm: () => { onConfirm: () => {
const panelContainer = this.props.getPanelContainer(); this.props.dashboard.removeRow(this.props.panel, true);
const dashboard = panelContainer.getDashboard();
dashboard.removeRow(this.props.panel, true);
}, },
onAltAction: () => { onAltAction: () => {
const panelContainer = this.props.getPanelContainer(); this.props.dashboard.removeRow(this.props.panel, false);
const dashboard = panelContainer.getDashboard();
dashboard.removeRow(this.props.panel, false);
}, },
}); });
} }

View File

@ -4,18 +4,13 @@ import { DashboardRow } from '../dashgrid/DashboardRow';
import { PanelModel } from '../panel_model'; import { PanelModel } from '../panel_model';
describe('DashboardRow', () => { describe('DashboardRow', () => {
let wrapper, panel, getPanelContainer, dashboardMock; let wrapper, panel, dashboardMock;
beforeEach(() => { beforeEach(() => {
dashboardMock = { toggleRow: jest.fn() }; dashboardMock = { toggleRow: jest.fn() };
getPanelContainer = jest.fn().mockReturnValue({
getDashboard: jest.fn().mockReturnValue(dashboardMock),
getPanelLoader: jest.fn()
});
panel = new PanelModel({ collapsed: false }); panel = new PanelModel({ collapsed: false });
wrapper = shallow(<DashboardRow panel={panel} getPanelContainer={getPanelContainer} />); wrapper = shallow(<DashboardRow panel={panel} dashboard={dashboardMock} />);
}); });
it('Should not have collapsed class when collaped is false', () => { it('Should not have collapsed class when collaped is false', () => {
@ -29,5 +24,4 @@ describe('DashboardRow', () => {
expect(wrapper.find('.dashboard-row--collapsed')).toHaveLength(1); expect(wrapper.find('.dashboard-row--collapsed')).toHaveLength(1);
expect(dashboardMock.toggleRow.mock.calls).toHaveLength(1); expect(dashboardMock.toggleRow.mock.calls).toHaveLength(1);
}); });
}); });