newgrid: row progress
This commit is contained in:
@@ -82,9 +82,11 @@ export class DashboardModel {
|
||||
this.folderId = data.folderId || null;
|
||||
this.panels = _.map(data.panels || [], panelData => new PanelModel(panelData));
|
||||
|
||||
this.addBuiltInAnnotationQuery();
|
||||
this.initMeta(meta);
|
||||
this.updateSchema(data);
|
||||
|
||||
this.addBuiltInAnnotationQuery();
|
||||
this.sortPanelsByGridPos();
|
||||
}
|
||||
|
||||
addBuiltInAnnotationQuery() {
|
||||
@@ -200,10 +202,12 @@ export class DashboardModel {
|
||||
return null;
|
||||
}
|
||||
|
||||
addPanel(panel) {
|
||||
panel.id = this.getNextPanelId();
|
||||
addPanel(panelData) {
|
||||
panelData.id = this.getNextPanelId();
|
||||
|
||||
this.panels.unshift(new PanelModel(panel));
|
||||
let panel = new PanelModel(panelData);
|
||||
|
||||
this.panels.unshift(panel);
|
||||
|
||||
this.sortPanelsByGridPos();
|
||||
|
||||
@@ -395,11 +399,53 @@ export class DashboardModel {
|
||||
|
||||
destroy() {
|
||||
this.events.removeAllListeners();
|
||||
for (let row of this.rows) {
|
||||
row.destroy();
|
||||
for (let panel of this.panels) {
|
||||
panel.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
toggleRow(row) {
|
||||
let rowPanels = [];
|
||||
let rowFound = false;
|
||||
|
||||
// if already collapsed
|
||||
if (row.collapse) {
|
||||
row.collapse = false;
|
||||
|
||||
for (let panel of row.panels) {
|
||||
this.panels.push(new PanelModel(panel));
|
||||
}
|
||||
|
||||
row.panels = [];
|
||||
|
||||
} else {
|
||||
|
||||
for (let index = 0; index < this.panels.length; index++) {
|
||||
let panel = this.panels[index];
|
||||
|
||||
if (rowFound) {
|
||||
// break when encountering another row
|
||||
if (panel.type === 'row') {
|
||||
break;
|
||||
}
|
||||
|
||||
// this panel must belong to row
|
||||
rowPanels.push(panel);
|
||||
} else if (panel === row) {
|
||||
rowFound = true;
|
||||
}
|
||||
}
|
||||
// remove panels
|
||||
_.pull(this.panels, ...rowPanels);
|
||||
// save panel models inside row panel
|
||||
row.panels = _.map(rowPanels, panel => panel.getSaveModel());
|
||||
row.collapse = true;
|
||||
}
|
||||
|
||||
// emit change event
|
||||
this.events.emit('row-collapse-changed');
|
||||
}
|
||||
|
||||
on(eventName, callback) {
|
||||
this.events.on(eventName, callback);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import _ from 'lodash';
|
||||
import config from 'app/core/config';
|
||||
import {PanelModel} from '../panel_model';
|
||||
import {PanelContainer} from './PanelContainer';
|
||||
import {GRID_COLUMN_COUNT} from 'app/core/constants';
|
||||
|
||||
export interface AddPanelPanelProps {
|
||||
panel: PanelModel;
|
||||
@@ -46,9 +45,6 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
|
||||
const dashboard = panelContainer.getDashboard();
|
||||
const {gridPos} = this.props.panel;
|
||||
|
||||
// remove add-panel panel
|
||||
dashboard.removePanel(this.props.panel);
|
||||
|
||||
var newPanel: any = {
|
||||
type: panelPluginInfo.id,
|
||||
title: 'Panel Title',
|
||||
@@ -57,10 +53,11 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
|
||||
|
||||
if (panelPluginInfo.id === 'row') {
|
||||
newPanel.title = 'Row title';
|
||||
newPanel.gridPos = {x: 0, y: 0, w: GRID_COLUMN_COUNT, h: 1, static: true};
|
||||
newPanel.gridPos = {x: 0, y: 0};
|
||||
}
|
||||
|
||||
dashboard.addPanel(newPanel);
|
||||
dashboard.removePanel(this.props.panel);
|
||||
}
|
||||
|
||||
renderPanelItem(panel) {
|
||||
|
||||
@@ -70,6 +70,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
|
||||
this.dashboard.on('panel-removed', this.triggerForceUpdate.bind(this));
|
||||
this.dashboard.on('repeats-processed', this.triggerForceUpdate.bind(this));
|
||||
this.dashboard.on('view-mode-changed', this.triggerForceUpdate.bind(this));
|
||||
this.dashboard.on('row-collapse-changed', this.triggerForceUpdate.bind(this));
|
||||
}
|
||||
|
||||
buildLayout() {
|
||||
@@ -85,14 +86,22 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
|
||||
continue;
|
||||
}
|
||||
|
||||
layout.push({
|
||||
let panelPos: any = {
|
||||
i: stringId,
|
||||
x: panel.gridPos.x,
|
||||
y: panel.gridPos.y,
|
||||
w: panel.gridPos.w,
|
||||
h: panel.gridPos.h,
|
||||
static: panel.gridPos.static,
|
||||
});
|
||||
};
|
||||
|
||||
if (panel.type === 'row') {
|
||||
panelPos.w = GRID_COLUMN_COUNT;
|
||||
panelPos.h = 1;
|
||||
panelPos.isResizable = false;
|
||||
panelPos.isDraggable = panel.collapse;
|
||||
}
|
||||
|
||||
layout.push(panelPos);
|
||||
}
|
||||
|
||||
return layout;
|
||||
@@ -109,7 +118,6 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
|
||||
}
|
||||
|
||||
onWidthChange() {
|
||||
console.log('width change');
|
||||
for (const panel of this.dashboard.panels) {
|
||||
panel.resizeDone();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
|
||||
render() {
|
||||
// special handling for rows
|
||||
if (this.props.panel.type === 'row') {
|
||||
return <DashboardRow panel={this.props.panel} />;
|
||||
return <DashboardRow panel={this.props.panel} getPanelContainer={this.props.getPanelContainer} />;
|
||||
}
|
||||
|
||||
if (this.props.panel.type === 'add-panel') {
|
||||
|
||||
@@ -1,27 +1,46 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import {PanelModel} from '../panel_model';
|
||||
import {PanelContainer} from './PanelContainer';
|
||||
|
||||
export interface DashboardRowProps {
|
||||
panel: PanelModel;
|
||||
getPanelContainer: () => PanelContainer;
|
||||
}
|
||||
|
||||
export class DashboardRow extends React.Component<DashboardRowProps, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
collapse: this.props.panel.collapse,
|
||||
};
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.openSettings = this.openSettings.bind(this);
|
||||
}
|
||||
|
||||
toggle() {}
|
||||
toggle() {
|
||||
const panelContainer = this.props.getPanelContainer();
|
||||
const dashboard = panelContainer.getDashboard();
|
||||
|
||||
dashboard.toggleRow(this.props.panel);
|
||||
|
||||
this.setState(prevState => {
|
||||
return {collapse: !prevState.collapse};
|
||||
});
|
||||
}
|
||||
|
||||
openSettings() {}
|
||||
|
||||
render() {
|
||||
const classes = classNames({'dashboard-row': true, 'dashboard-row--collapse': this.state.collapse});
|
||||
const chevronClass = classNames({'fa': true, 'fa-chevron-down': !this.state.collapse, 'fa-chevron-right': this.state.collapse});
|
||||
|
||||
return (
|
||||
<div className="dashboard-row">
|
||||
<div className={classes}>
|
||||
<a className="dashboard-row__title pointer" onClick={this.toggle}>
|
||||
<i className="fa fa-chevron-down" />
|
||||
<i className={chevronClass} />
|
||||
{this.props.panel.title}
|
||||
</a>
|
||||
<div className="dashboard-row__actions">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<a class="navbar-page-icon" ng-click="ctrl.starDashboard()">
|
||||
<i class="gicon gicon-dashboard-starred"></i>
|
||||
<a class="navbar-page-icon" ng-click="ctrl.starDashboard()" bs-tooltip="'Mark as favorite'" data-placement="bottom">
|
||||
<i class="fa" ng-class="{'fa-star-o': !ctrl.dashboard.meta.isStarred, 'fa-star': ctrl.dashboard.meta.isStarred}"></i>
|
||||
</a>
|
||||
|
||||
<a class="navbar-page-btn" ng-click="ctrl.showSearch()">
|
||||
|
||||
@@ -27,6 +27,7 @@ export class PanelModel {
|
||||
repeatPanelId?: number;
|
||||
repeatDirection?: string;
|
||||
minSpan?: number;
|
||||
collapse?: boolean;
|
||||
|
||||
// non persisted
|
||||
fullscreen: boolean;
|
||||
@@ -86,5 +87,9 @@ export class PanelModel {
|
||||
resizeDone() {
|
||||
this.events.emit('panel-size-changed');
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.events.removeAllListeners();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
|
||||
it('should move pulldowns to new schema', function() {
|
||||
expect(model.annotations.list[0].name).to.be('old');
|
||||
expect(model.annotations.list[1].name).to.be('old');
|
||||
});
|
||||
|
||||
it('table panel should only have two thresholds values', function() {
|
||||
@@ -560,4 +560,27 @@ describe('DashboardModel', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('When collapsing row', function(ctx) {
|
||||
var dashboard;
|
||||
|
||||
beforeEach(function() {
|
||||
dashboard = new DashboardModel({
|
||||
panels: [
|
||||
{id: 1, type: 'graph', gridPos: {x: 0, y: 0, w: 24, h: 2}},
|
||||
{id: 2, type: 'row', gridPos: {x: 0, y: 2, w: 24, h: 2}},
|
||||
{id: 3, type: 'graph', gridPos: {x: 0, y: 4, w: 12, h: 2}},
|
||||
{id: 4, type: 'graph', gridPos: {x: 12, y: 4, w: 12, h: 2}},
|
||||
{id: 5, type: 'row', gridPos: {x: 0, y: 6, w: 24, h: 2}},
|
||||
],
|
||||
});
|
||||
dashboard.toggleRow(dashboard.panels[1]);
|
||||
});
|
||||
|
||||
it('should remove panels and put them inside collapsed row', function() {
|
||||
expect(dashboard.panels.length).to.eql(3);
|
||||
expect(dashboard.panels[1].panels.length).to.eql(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
$dashboard-row-height: 30px;
|
||||
|
||||
.dashboard-row {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
@@ -31,7 +29,6 @@ $dashboard-row-height: 30px;
|
||||
flex-grow: 0;
|
||||
font-size: 1.15rem;
|
||||
font-weight: $font-weight-semi-bold;
|
||||
padding: 0rem 1rem 0.3rem 1rem;
|
||||
color: $text-color;
|
||||
|
||||
.fa {
|
||||
@@ -53,6 +50,8 @@ $dashboard-row-height: 30px;
|
||||
color: $link-hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.dashboard-row__panel_count {
|
||||
@@ -61,15 +60,12 @@ $dashboard-row-height: 30px;
|
||||
font-size: $font-size-sm;
|
||||
font-weight: normal;
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.dashboard-row__drag {
|
||||
cursor: move;
|
||||
width: 1rem;
|
||||
height: $dashboard-row-height;
|
||||
height: 100%;
|
||||
background: url("../img/grab_dark.svg") no-repeat 50% 50%;
|
||||
background-size: 8px;
|
||||
visibility: hidden;
|
||||
|
||||
Reference in New Issue
Block a user