diff --git a/web/client/components/dashboard/Dashboard.jsx b/web/client/components/dashboard/Dashboard.jsx index ed0dec968c..5494d4fca9 100644 --- a/web/client/components/dashboard/Dashboard.jsx +++ b/web/client/components/dashboard/Dashboard.jsx @@ -10,10 +10,16 @@ const {pure, compose, defaultProps} = require('recompose'); const Message = require('../I18N/Message'); const emptyState = require('../misc/enhancers/emptyState'); const withSelection = require('../widgets/view/enhancers/withSelection'); +const {widthProvider} = require('../layout/enhancers/gridLayout'); module.exports = compose( pure, + defaultProps({ + breakpoints: { md: 480, xxs: 0 }, + cols: { md: 6, xxs: 1 } + }), + widthProvider({ overrideWidthProvider: true}), emptyState( ({widgets = []} = {}) => widgets.length === 0, () => ({ @@ -22,7 +28,7 @@ module.exports = }) ), defaultProps({ - isWidgetSelectable: ({}) => true + isWidgetSelectable: () => true }), withSelection )(require('../widgets/view/WidgetsView')); diff --git a/web/client/components/layout/enhancers/__tests__/gridLayout-test.js b/web/client/components/layout/enhancers/__tests__/gridLayout-test.js new file mode 100644 index 0000000000..cf9345bf74 --- /dev/null +++ b/web/client/components/layout/enhancers/__tests__/gridLayout-test.js @@ -0,0 +1,47 @@ +/* + * Copyright 2018, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ +const React = require('react'); +const ReactDOM = require('react-dom'); +const {createSink} = require('recompose'); +const expect = require('expect'); +const {widthProvider, heightProvider} = require('../gridLayout'); + +describe('gridLayout enhancers', () => { + beforeEach((done) => { + document.body.innerHTML = '
'; + setTimeout(done); + }); + afterEach((done) => { + ReactDOM.unmountComponentAtNode(document.getElementById("container")); + document.body.innerHTML = ''; + setTimeout(done); + }); + it('widthProvider rendering with defaults', (done) => { + const Sink = widthProvider()(createSink( props => { + expect(props).toExist(); + expect(props.useDefaultWidthProvider).toBe(true); + done(); + })); + ReactDOM.render(, document.getElementById("container")); + }); + it('widthProvider rendering override defaults', (done) => { + const Sink = widthProvider({overrideWidthProvider: true})(createSink(props => { + expect(props).toExist(); + expect(props.useDefaultWidthProvider).toBe(false); + done(); + })); + ReactDOM.render(, document.getElementById("container")); + }); + it('heightProvider rendering with defaults', (done) => { + const Sink = heightProvider()(createSink(props => { + expect(props).toExist(); + done(); + })); + ReactDOM.render(, document.getElementById("container")); + }); +}); diff --git a/web/client/components/layout/enhancers/gridLayout.jsx b/web/client/components/layout/enhancers/gridLayout.jsx new file mode 100644 index 0000000000..e7c409b01b --- /dev/null +++ b/web/client/components/layout/enhancers/gridLayout.jsx @@ -0,0 +1,39 @@ +/* + * Copyright 2018, GeoSolutions Sas. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ +const React = require('react'); +const withResizeSpy = require('../../misc/enhancers/withResizeSpy'); +const { compose, defaultProps, withStateHandlers} = require('recompose'); +const ContainerDimensions = require('react-container-dimensions').default; + +/** + * Width and height providers for react-grid-layout. Replace default. + */ +module.exports = { + /** + * widthProvider that checks the container size + * Useful in widgets container for dashboard and map context. + * Can optionally override default widthProvider in WidgetView, for instance + */ + widthProvider: ({overrideWidthProvider} = {}) => compose( + defaultProps({ + useDefaultWidthProvider: !overrideWidthProvider + }), + C => props => {({ width } = {}) => } + + ), + /** + * heightProvider that checks the fill div by default. + * Useful in widgets container for map context + */ + heightProvider: (opts) => compose( + withStateHandlers(() => ({}), { + onResize: () => ({ height }) => ({ height }) + }), + withResizeSpy(opts) + ) +}; diff --git a/web/client/components/widgets/view/WidgetsView.jsx b/web/client/components/widgets/view/WidgetsView.jsx index 55801fdb77..db96f8d009 100644 --- a/web/client/components/widgets/view/WidgetsView.jsx +++ b/web/client/components/widgets/view/WidgetsView.jsx @@ -7,14 +7,18 @@ */ const React = require('react'); -const { pure } = require('recompose'); +const { pure, branch } = require('recompose'); const { find } = require('lodash'); /* react-grid-layout-resize-prevent-collision is a fork of react-grid-layout deployed on npmjs.org to fix https://github.com/STRML/react-grid-layout/issues/655 You can install and use react-grid-layout again when the issue is fixed */ const { Responsive, WidthProvider: widthProvider } = require('react-grid-layout-resize-prevent-collision'); -const ResponsiveReactGridLayout = widthProvider(Responsive); +const ResponsiveReactGridLayout = + branch( + ({ useDefaultWidthProvider = true }) => useDefaultWidthProvider, + widthProvider + )(Responsive); const withGroupColor = require('../enhancers/withGroupColor'); const DefaultWidget = withGroupColor(require('../widget/DefaultWidget')); const getWidgetGroups = (groups = [], w) => groups.filter(g => find(g.widgets, id => id === w.id)); @@ -30,6 +34,10 @@ module.exports = pure(({ widgets = [], layouts, dependencies, + verticalCompact = false, + useDefaultWidthProvider = true, + measureBeforeMount, + width, showGroupColor, groups = [], getWidgetClass = () => { }, @@ -42,6 +50,9 @@ module.exports = pure(({ } = {}) => ( { diff --git a/web/client/plugins/Widgets.jsx b/web/client/plugins/Widgets.jsx index 7bb5a0981a..7afba44942 100644 --- a/web/client/plugins/Widgets.jsx +++ b/web/client/plugins/Widgets.jsx @@ -9,12 +9,13 @@ const React = require('react'); const {connect} = require('react-redux'); const {createSelector} = require('reselect'); -const {compose, withProps} = require('recompose'); +const { compose, withProps} = require('recompose'); const {mapIdSelector} = require('../selectors/map'); const {getFloatingWidgets, dependenciesSelector, getFloatingWidgetsLayout} = require('../selectors/widgets'); const { editWidget, updateWidgetProperty, deleteWidget, changeLayout, exportCSV, exportImage} = require('../actions/widgets'); -const ContainerDimensions = require('react-container-dimensions').default; const {rightPanelOpenSelector, bottomPanelOpenSelector} = require('../selectors/maplayout'); +const {heightProvider} = require('../components/layout/enhancers/gridLayout'); +const ContainerDimensions = require('react-container-dimensions').default; const PropTypes = require('prop-types'); const WidgetsView = @@ -40,20 +41,29 @@ compose( onLayoutChange: changeLayout } ), - withProps(({width, height, rowHeight = 208} = {}) => ({ + heightProvider({ debounceTime: 20, closest: true, querySelector: '.fill' }), + C => props => {({ width } = {}) => }, + withProps(({width, height} = {}) => { + const divHeight = height - 120; + const nRows = 4; + const rowHeight = Math.floor(divHeight / nRows - 20); + return ({ rowHeight, className: "on-map", - breakpoints: {lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0}, - cols: {lg: 6, md: 6, sm: 4, xs: 2, xxs: 1}, + breakpoints: { md: 480, xxs: 0 }, + cols: { md: 6, xxs: 1 }, style: { left: (width && width > 800) ? "500px" : "0", - bottom: 50, + marginTop: 52, + bottom: 67, height: Math.floor((height - 100) / (rowHeight + 10)) * (rowHeight + 10), width: `${width && width > 800 ? 'calc(100% - 550px)' : 'calc(100% - 50px)'}`, position: 'absolute', zIndex: 50 } - })) + }); + }) + )(require('../components/widgets/view/WidgetsView')); @@ -65,7 +75,7 @@ class Widgets extends React.Component { enabled: true }; render() { - return this.props.enabled ? ({({width, height}) => } ) : null; + return this.props.enabled ? : null; } }