mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Dashboard smaller panel grid dimensions (#16763)
* 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
This commit is contained in:
parent
ec1ee938a6
commit
f5aaad396f
8 changed files with 109 additions and 110 deletions
|
@ -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}`;
|
||||
|
|
|
@ -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 };
|
||||
|
@ -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}
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
import expect from 'expect.js';
|
||||
import { PanelUtils } from '../panel_utils';
|
||||
import { DEFAULT_PANEL_WIDTH, DEFAULT_PANEL_HEIGHT } from '../../dashboard_constants';
|
||||
|
||||
describe('PanelUtils', function () {
|
||||
it('convertOldPanelData 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.convertOldPanelData(oldPanel));
|
||||
expect(panelData[0].gridData.w = DEFAULT_PANEL_WIDTH);
|
||||
expect(panelData[0].gridData.h = DEFAULT_PANEL_HEIGHT);
|
||||
|
||||
expect(panelData[1].gridData.w = 3);
|
||||
expect(panelData[1].gridData.h = 2);
|
||||
});
|
||||
});
|
|
@ -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,
|
||||
|
@ -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);
|
||||
|
|
|
@ -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');
|
||||
});
|
|
@ -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', () => {
|
||||
|
@ -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, 300, 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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue