import React from 'react'; import PropTypes from 'prop-types'; import { Responsive, WidthProvider } from 'react-grid-layout'; import GridCell from './GridCell'; import { getExploreUrl } from '../../explore/exploreUtils'; require('react-grid-layout/css/styles.css'); require('react-resizable/css/styles.css'); const ResponsiveReactGridLayout = WidthProvider(Responsive); const propTypes = { dashboard: PropTypes.object.isRequired, datasources: PropTypes.object, charts: PropTypes.object.isRequired, filters: PropTypes.object, timeout: PropTypes.number, onChange: PropTypes.func, getFormDataExtra: PropTypes.func, fetchSlice: PropTypes.func, saveSlice: PropTypes.func, removeSlice: PropTypes.func, removeChart: PropTypes.func, updateDashboardLayout: PropTypes.func, toggleExpandSlice: PropTypes.func, addFilter: PropTypes.func, getFilters: PropTypes.func, clearFilter: PropTypes.func, removeFilter: PropTypes.func, }; const defaultProps = { onChange: () => ({}), getFormDataExtra: () => ({}), fetchSlice: () => ({}), saveSlice: () => ({}), removeSlice: () => ({}), removeChart: () => ({}), updateDashboardLayout: () => ({}), toggleExpandSlice: () => ({}), addFilter: () => ({}), getFilters: () => ({}), clearFilter: () => ({}), removeFilter: () => ({}), }; class GridLayout extends React.Component { constructor(props) { super(props); this.onResizeStop = this.onResizeStop.bind(this); this.onDragStop = this.onDragStop.bind(this); this.forceRefresh = this.forceRefresh.bind(this); this.removeSlice = this.removeSlice.bind(this); this.updateSliceName = this.props.dashboard.dash_edit_perm ? this.updateSliceName.bind(this) : null; } onResizeStop(layout) { this.props.updateDashboardLayout(layout); this.props.onChange(); } onDragStop(layout) { this.props.updateDashboardLayout(layout); this.props.onChange(); } getWidgetId(slice) { return 'widget_' + slice.slice_id; } getWidgetHeight(slice) { const widgetId = this.getWidgetId(slice); if (!widgetId || !this.refs[widgetId]) { return 400; } return this.refs[widgetId].offsetHeight; } getWidgetWidth(slice) { const widgetId = this.getWidgetId(slice); if (!widgetId || !this.refs[widgetId]) { return 400; } return this.refs[widgetId].offsetWidth; } findSliceIndexById(sliceId) { return this.props.dashboard.slices .map(slice => (slice.slice_id)).indexOf(sliceId); } forceRefresh(sliceId) { return this.props.fetchSlice(this.props.charts['slice_' + sliceId], true); } removeSlice(slice) { if (!slice) { return; } // remove slice dashbaord and charts this.props.removeSlice(slice); this.props.removeChart(this.props.charts['slice_' + slice.slice_id].chartKey); this.props.onChange(); } updateSliceName(sliceId, sliceName) { const index = this.findSliceIndexById(sliceId); if (index === -1) { return; } const currentSlice = this.props.dashboard.slices[index]; if (currentSlice.slice_name === sliceName) { return; } this.props.saveSlice(currentSlice, sliceName); } isExpanded(slice) { return this.props.dashboard.metadata.expanded_slices && this.props.dashboard.metadata.expanded_slices[slice.slice_id]; } render() { return ( {this.props.dashboard.slices.map(slice => (
))}
); } } GridLayout.propTypes = propTypes; GridLayout.defaultProps = defaultProps; export default GridLayout;