Skip to content

Commit

Permalink
Dashboard smaller panel grid dimensions (#16763) (#17105)
Browse files Browse the repository at this point in the history
* change panel height from 100 to 20

* scale default height

* change number of grid columns to 48 so there is better control of panel width

* remove input controls resize test since its using EUI components and no longer needs to be functionally tested

* fix dashboard_grid_container test

* clean up rebase artifacts

* scale x and y in panel_state test

* make DASHBOARD_GRID_HEIGHT a constant
  • Loading branch information
nreese committed Mar 12, 2018
1 parent d0ea1de commit 74982f8
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ export const DashboardConstants = {
LANDING_PAGE_PATH: '/dashboards',
CREATE_NEW_DASHBOARD_URL: '/dashboard',
};
export const DEFAULT_PANEL_WIDTH = 6;
export const DEFAULT_PANEL_HEIGHT = 3;
export const DASHBOARD_GRID_COLUMN_COUNT = 12;
export const DASHBOARD_GRID_COLUMN_COUNT = 48;
export const DASHBOARD_GRID_HEIGHT = 20;
export const DEFAULT_PANEL_WIDTH = DASHBOARD_GRID_COLUMN_COUNT / 2;
export const DEFAULT_PANEL_HEIGHT = 15;

export function createDashboardEditUrl(id) {
return `/dashboard/${id}`;
Expand Down
19 changes: 15 additions & 4 deletions src/core_plugins/kibana/public/dashboard/grid/dashboard_grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import classNames from 'classnames';
import { PanelUtils } from '../panel/panel_utils';
import { DashboardViewMode } from '../dashboard_view_mode';
import { DashboardPanel } from '../panel';
import { DASHBOARD_GRID_COLUMN_COUNT } from '../dashboard_constants';
import {
DASHBOARD_GRID_COLUMN_COUNT,
DASHBOARD_GRID_HEIGHT,
} from '../dashboard_constants';
import sizeMe from 'react-sizeme';

const config = { monitorWidth: true };
Expand Down Expand Up @@ -58,7 +61,7 @@ function ResponsiveGrid({
isResizable={true}
margin={[MARGINS, MARGINS]}
cols={DASHBOARD_GRID_COLUMN_COUNT}
rowHeight={100}
rowHeight={DASHBOARD_GRID_HEIGHT}
draggableHandle={isViewMode ? '.doesnt-exist' : '.panel-title'}
layout={layout}
onLayoutChange={onLayoutChange}
Expand Down Expand Up @@ -95,9 +98,17 @@ export class DashboardGrid extends React.Component {

buildLayoutFromPanels() {
return _.map(this.props.panels, panel => {
if (!panel.version) {
PanelUtils.convertOldPanelData(panel);
// panel version numbers added in 6.1. Any panel without version number is assumed to be 6.0.0
const panelVersion = panel.version ? PanelUtils.parseVersion(panel.version) : PanelUtils.parseVersion('6.0.0');

if (panelVersion.major < 6 || (panelVersion.major === 6 && panelVersion.minor < 1)) {
PanelUtils.convertPanelDataPre_6_1(panel);
}

if (panelVersion.major < 6 || (panelVersion.major === 6 && panelVersion.minor < 3)) {
PanelUtils.convertPanelDataPre_6_3(panel);
}

return panel.gridData;
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { store } from '../../store';
import { DashboardGridContainer } from './dashboard_grid_container';
import { updatePanels } from '../actions';

jest.mock('ui/chrome', () => ({ getKibanaVersion: () => '6.0.0' }), { virtual: true });
jest.mock('ui/chrome', () => ({ getKibanaVersion: () => '6.3.0' }), { virtual: true });

function getProps(props = {}) {
const defaultTestProps = {
Expand Down Expand Up @@ -75,7 +75,7 @@ test('loads old panel data in the right order', () => {

const foo8Panel = _.find(panels, panel => panel.id === 'foo8');
expect(foo8Panel.row).toBe(undefined);
expect(foo8Panel.gridData.y).toBe(7);
expect(foo8Panel.gridData.y).toBe(35);
expect(foo8Panel.gridData.x).toBe(0);

grid.unmount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,35 @@ function createPanelWithDimensions(x, y, w, h) {
describe('Panel state', function () {
it('finds a spot on the right', function () {
// Default setup after a single panel, of default size, is on the grid
const panels = [createPanelWithDimensions(0, 0, 6, 6)];
const panels = [createPanelWithDimensions(0, 0, 24, 30)];

const panel = createPanelState('1', 'a type', '1', panels);
expect(panel.gridData.x).to.equal(6);
expect(panel.gridData.x).to.equal(24);
expect(panel.gridData.y).to.equal(0);
});

it('finds a spot on the right when the panel is taller than any other panel on the grid', function () {
// Should be a little empty spot on the right.
const panels = [
createPanelWithDimensions(0, 0, 6, 9),
createPanelWithDimensions(6, 0, 6, 6),
createPanelWithDimensions(0, 0, 24, 45),
createPanelWithDimensions(24, 0, 24, 30),
];

const panel = createPanelState('1', 'a type', '1', panels);
expect(panel.gridData.x).to.equal(6);
expect(panel.gridData.y).to.equal(6);
expect(panel.gridData.x).to.equal(24);
expect(panel.gridData.y).to.equal(30);
});

it('finds an empty spot in the middle of the grid', function () {
const panels = [
createPanelWithDimensions(0, 0, 12, 1),
createPanelWithDimensions(0, 1, 1, 6),
createPanelWithDimensions(10, 1, 1, 6),
createPanelWithDimensions(0, 11, 12, 1),
createPanelWithDimensions(0, 0, 48, 5),
createPanelWithDimensions(0, 5, 4, 30),
createPanelWithDimensions(40, 5, 4, 30),
createPanelWithDimensions(0, 55, 48, 5),
];

const panel = createPanelState('1', 'a type', '1', panels);
expect(panel.gridData.x).to.equal(1);
expect(panel.gridData.y).to.equal(1);
expect(panel.gridData.x).to.equal(4);
expect(panel.gridData.y).to.equal(5);
});
});

This file was deleted.

31 changes: 30 additions & 1 deletion src/core_plugins/kibana/public/dashboard/panel/panel_utils.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { DEFAULT_PANEL_WIDTH, DEFAULT_PANEL_HEIGHT } from '../dashboard_constants';
import chrome from 'ui/chrome';

const PANEL_HEIGHT_SCALE_FACTOR = 5;
const PANEL_WIDTH_SCALE_FACTOR = 4;

export class PanelUtils {

static convertOldPanelData(panel) {
// 6.1 switched from gridster to react grid. React grid uses different variables for tracking layout
static convertPanelDataPre_6_1(panel) { // eslint-disable-line camelcase
panel.gridData = {
x: panel.col - 1,
y: panel.row - 1,
Expand All @@ -21,6 +25,31 @@ export class PanelUtils {
return panel;
}

// 6.3 changed the panel dimensions to allow finer control over sizing
// 1) decrease column height from 100 to 20.
// 2) increase rows from 12 to 48
// Need to scale pre 6.3 panels so they maintain the same layout
static convertPanelDataPre_6_3(panel) { // eslint-disable-line camelcase
panel.gridData.w = panel.gridData.w * PANEL_WIDTH_SCALE_FACTOR;
panel.gridData.x = panel.gridData.x * PANEL_WIDTH_SCALE_FACTOR;
panel.gridData.h = panel.gridData.h * PANEL_HEIGHT_SCALE_FACTOR;
panel.gridData.y = panel.gridData.y * PANEL_HEIGHT_SCALE_FACTOR;
panel.version = chrome.getKibanaVersion();

return panel;
}

static parseVersion(version = '6.0.0') {
const versionSplit = version.split('.');
if (versionSplit.length < 3) {
throw new Error(`Invalid version, ${version}, expected <major>.<minor>.<patch>`);
}
return {
major: parseInt(versionSplit[0], 10),
minor: parseInt(versionSplit[1], 10)
};
}

static initPanelIndexes(panels) {
// find the largest panelIndex in all the panels
let maxIndex = this.getMaxPanelIndex(panels);
Expand Down
46 changes: 46 additions & 0 deletions src/core_plugins/kibana/public/dashboard/panel/panel_utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
jest.mock('ui/chrome',
() => ({
getKibanaVersion: () => '6.3.0',
}), { virtual: true });

import { PanelUtils } from './panel_utils';
import { DEFAULT_PANEL_WIDTH, DEFAULT_PANEL_HEIGHT } from '../dashboard_constants';

test('parseVersion', () => {
const { major, minor } = PanelUtils.parseVersion('6.2.0');
expect(major).toBe(6);
expect(minor).toBe(2);
});

test('convertPanelDataPre_6_1 gives supplies width and height when missing', () => {
const panelData = [
{ col: 3, id: 'foo1', row: 1, type: 'visualization', panelIndex: 1 },
{ col: 3, id: 'foo2', row: 1, size_x: 3, size_y: 2, type: 'visualization', panelIndex: 2 }
];
panelData.forEach(oldPanel => PanelUtils.convertPanelDataPre_6_1(oldPanel));
expect(panelData[0].gridData.w).toBe(DEFAULT_PANEL_WIDTH);
expect(panelData[0].gridData.h).toBe(DEFAULT_PANEL_HEIGHT);
expect(panelData[0].version).toBe('6.3.0');

expect(panelData[1].gridData.w).toBe(3);
expect(panelData[1].gridData.h).toBe(2);
expect(panelData[1].version).toBe('6.3.0');
});

test('convertPanelDataPre_6_3 scales panel dimensions', () => {
const oldPanel = {
gridData: {
h: 3,
w: 7,
x: 2,
y: 5,
},
version: '6.2.0'
};
const updatedPanel = PanelUtils.convertPanelDataPre_6_3(oldPanel);
expect(updatedPanel.gridData.w).toBe(28);
expect(updatedPanel.gridData.h).toBe(15);
expect(updatedPanel.gridData.x).toBe(8);
expect(updatedPanel.gridData.y).toBe(25);
expect(updatedPanel.version).toBe('6.3.0');
});
70 changes: 0 additions & 70 deletions test/functional/apps/dashboard/_dashboard_grid.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import expect from 'expect.js';

export default function ({ getService, getPageObjects }) {
const retry = getService('retry');
const find = getService('find');
const remote = getService('remote');
const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['dashboard', 'header', 'common']);

describe('dashboard grid', () => {
Expand Down Expand Up @@ -46,73 +44,5 @@ export default function ({ getService, getPageObjects }) {
expect(position1.y).to.be.greaterThan(position2.y);
});
});

describe('resize panel', () => {

describe('input control panel', () => {

before(async () => {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.addVisualizations(['Visualization InputControl']);
});

it('Should position controls in horizontal layout when panel is short and long', async () => {
const resizeIcons = await find.allByCssSelector('.react-resizable-handle');
expect(resizeIcons.length).to.equal(1);
remote
.moveMouseTo(resizeIcons[0])
.pressMouseButton()
.moveMouseTo(null, 400, 0)
.releaseMouseButton();

await retry.try(async () => {
const controls = await testSubjects.findAll('inputControlItem');
expect(controls.length).to.equal(3);
const control0Position = await controls[0].getPosition();
const control1Position = await controls[1].getPosition();
const control2Position = await controls[2].getPosition();
expect(control0Position.y).to.equal(control1Position.y);
expect(control1Position.y).to.equal(control2Position.y);
});
});

it('Should position controls in vertical layout when panel is tall and skinny', async () => {
const resizeIcons = await find.allByCssSelector('.react-resizable-handle');
expect(resizeIcons.length).to.equal(1);
remote
.moveMouseTo(resizeIcons[0])
.pressMouseButton()
.moveMouseTo(null, -400, 200)
.releaseMouseButton();

await retry.try(async () => {
const controls = await testSubjects.findAll('inputControlItem');
expect(controls.length).to.equal(3);
const control0Position = await controls[0].getPosition();
const control1Position = await controls[1].getPosition();
const control2Position = await controls[2].getPosition();
expect(control2Position.y).to.be.greaterThan(control1Position.y);
expect(control1Position.y).to.be.greaterThan(control0Position.y);
});

});

it('Should position controls inside panel', async () => {
const controls = await testSubjects.findAll('inputControlItem');
expect(controls.length).to.equal(3);
const control0Size = await controls[0].getSize();
const control1Size = await controls[1].getSize();
const control2Size = await controls[2].getSize();

const panels = await find.allByCssSelector('.dashboard-panel');
expect(panels.length).to.equal(1);
const panelSize = await panels[0].getSize();
expect(control0Size.width).to.be.lessThan(panelSize.width);
expect(control1Size.width).to.be.lessThan(panelSize.width);
expect(control2Size.width).to.be.lessThan(panelSize.width);
});
});
});
});
}

0 comments on commit 74982f8

Please sign in to comment.