Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 46 additions & 6 deletions client/app/components/dashboards/dashboard-grid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import PropTypes from 'prop-types';
import { chain, pick } from 'lodash';
import { react2angular } from 'react2angular';
import cx from 'classnames';
import GridLayout, { WidthProvider } from 'react-grid-layout';
import { Responsive, WidthProvider } from 'react-grid-layout';
import { DashboardWidget } from '@/components/dashboards/widget';
import cfg from '@/config/dashboard-grid-options';

import 'react-grid-layout/css/styles.css';

const ResponsiveGridLayout = WidthProvider(GridLayout);
const ResponsiveGridLayout = WidthProvider(Responsive);

const WidgetType = PropTypes.shape({
id: PropTypes.number.isRequired,
Expand All @@ -27,18 +27,23 @@ const WidgetType = PropTypes.shape({
}).isRequired,
});

const SINGLE = 'single-column';
const MULTI = 'multi-column';

class DashboardGrid extends React.Component {
static propTypes = {
isEditing: PropTypes.bool.isRequired,
dashboard: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
widgets: PropTypes.arrayOf(WidgetType).isRequired,
onBreakpointChange: PropTypes.func,
onRemoveWidget: PropTypes.func,
onLayoutChange: PropTypes.func,
};

static defaultProps = {
onRemoveWidget: () => {},
onLayoutChange: () => {},
onBreakpointChange: () => {},
}

static normalizeFrom(widget) {
Expand Down Expand Up @@ -67,15 +72,47 @@ class DashboardGrid extends React.Component {
};
}

onLayoutChange(layout) {
const normalized = chain(layout)
state = {
layouts: {},
}

mode = null

componentDidMount() {
this.onBreakpointChange(document.body.offsetWidth <= cfg.mobileBreakPoint ? SINGLE : MULTI);
}

onLayoutChange = (_, layouts) => {
// workaround for when dashboard starts at single mode and then multi is empty or carries single col data
// fixes test dashboard_spec['shows widgets with full width']
// TODO: open react-grid-layout issue
if (layouts[MULTI]) {
this.setState({ layouts });
}

// workaround for https://github.com/STRML/react-grid-layout/issues/889
// remove next line when fix lands
this.mode = document.body.offsetWidth <= cfg.mobileBreakPoint ? SINGLE : MULTI;
// end workaround

// don't save single column mode layout
if (this.mode === SINGLE) {
return;
}

const normalized = chain(layouts[MULTI])
.keyBy('i')
.mapValues(DashboardGrid.normalizeTo)
.value();

this.props.onLayoutChange(normalized);
}

onBreakpointChange = (mode) => {
this.mode = mode;
this.props.onBreakpointChange(mode === SINGLE);
}

render() {
const className = cx('dashboard-wrapper', this.props.isEditing ? 'editing-mode' : 'preview-mode');
const { onRemoveWidget, dashboard, widgets } = this.props;
Expand All @@ -84,12 +121,15 @@ class DashboardGrid extends React.Component {
<div className={className}>
<ResponsiveGridLayout
className="layout"
cols={cfg.columns}
cols={{ [MULTI]: cfg.columns, [SINGLE]: 1 }}
rowHeight={cfg.rowHeight - cfg.margins}
margin={[cfg.margins, cfg.margins]}
isDraggable={this.props.isEditing}
isResizable={this.props.isEditing}
onLayoutChange={layout => this.onLayoutChange(layout)}
layouts={this.state.layouts}
onLayoutChange={this.onLayoutChange}
onBreakpointChange={this.onBreakpointChange}
breakpoints={{ [MULTI]: cfg.mobileBreakPoint, [SINGLE]: 0 }}
measureBeforeMount
>
{widgets.map(widget => (
Expand Down
1 change: 1 addition & 0 deletions client/app/pages/dashboards/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ <h3>
widgets="$ctrl.dashboard.widgets"
is-editing="$ctrl.layoutEditing && !$ctrl.isGridDisabled"
on-layout-change="$ctrl.onLayoutChange"
on-breakpoint-change="$ctrl.onBreakpointChanged"
on-remove-widget="$ctrl.removeWidget"
/>
</div>
Expand Down
5 changes: 5 additions & 0 deletions client/app/pages/dashboards/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ function DashboardCtrl(
}
};

this.onBreakpointChanged = (isSingleCol) => {
this.isGridDisabled = isSingleCol;
$scope.$applyAsync();
};

this.editLayout = (isEditing) => {
this.layoutEditing = isEditing;
};
Expand Down
8 changes: 4 additions & 4 deletions client/cypress/integration/dashboard/dashboard_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ describe('Dashboard', () => {
});
});

context.skip('viewport width is at 800px', () => {
context('viewport width is at 800px', () => {
before(function () {
cy.login();
createNewDashboardByAPI('Foo Bar')
Expand All @@ -557,12 +557,12 @@ describe('Dashboard', () => {

it('shows widgets with full width', () => {
cy.get('@textboxEl').should(($el) => {
expect($el.width()).to.eq(785);
expect($el.width()).to.eq(770);
});

cy.viewport(801, 800);
cy.get('@textboxEl').should(($el) => {
expect($el.width()).to.eq(393);
expect($el.width()).to.eq(378);
});
});

Expand Down Expand Up @@ -592,7 +592,7 @@ describe('Dashboard', () => {
});
});

context.skip('viewport width is at 767px', () => {
context('viewport width is at 767px', () => {
before(function () {
cy.login();
createNewDashboardByAPI('Foo Bar').then(({ slug }) => {
Expand Down