diff --git a/config/testSetup.js b/config/testSetup.js index 979703723..f7aba1373 100644 --- a/config/testSetup.js +++ b/config/testSetup.js @@ -1,5 +1,8 @@ import { configure } from '@testing-library/dom' import '@testing-library/jest-dom' +import ResizeObserver from 'resize-observer-polyfill' + +global.ResizeObserver = ResizeObserver configure({ testIdAttribute: 'data-test', diff --git a/package.json b/package.json index 776154f55..b62d147e0 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "patch-package": "^7", "postinstall-postinstall": "^2.1.0", "redux-mock-store": "^1.5.4", + "resize-observer-polyfill": "^1.5.1", "semantic-release": "^20", "start-server-and-test": "^1.14.0" }, diff --git a/src/components/DashboardContainer.js b/src/components/DashboardContainer.js index f15bb1c49..1784e27ac 100644 --- a/src/components/DashboardContainer.js +++ b/src/components/DashboardContainer.js @@ -1,26 +1,48 @@ import cx from 'classnames' import PropTypes from 'prop-types' -import React from 'react' +import React, { + useRef, + useState, + useEffect, + createContext, + useContext, +} from 'react' import classes from './styles/DashboardContainer.module.css' -const DashboardContainer = ({ children, covered }) => { +const ContainerWidthContext = createContext(0) + +const DashboardContainer = ({ children }) => { + const [containerWidth, setContainerWidth] = useState(0) + const ref = useRef(null) + + useEffect(() => { + const resizeObserver = new ResizeObserver((entries) => { + setContainerWidth(entries[0].contentRect.width) + }) + resizeObserver.observe(ref.current) + + return () => { + resizeObserver.disconnect() + } + }, []) + return (
- {children} +
+ + {children} + +
) } DashboardContainer.propTypes = { children: PropTypes.node, - covered: PropTypes.bool, } +export const useContainerWidth = () => useContext(ContainerWidthContext) export default DashboardContainer diff --git a/src/components/styles/DashboardContainer.module.css b/src/components/styles/DashboardContainer.module.css index d57fd17fb..2225aec05 100644 --- a/src/components/styles/DashboardContainer.module.css +++ b/src/components/styles/DashboardContainer.module.css @@ -1,19 +1,18 @@ .container { background-color: var(--colors-grey200); - padding-inline-start: var(--spacers-dp16); - padding-inline-end: var(--spacers-dp16); - padding-block-end: var(--spacers-dp24); + padding-inline-start: var(--spacers-dp8); + padding-inline-end: var(--spacers-dp8); + padding-block-end: var(--spacers-dp12); overflow: auto; } - +.contentWrap { + overflow: visible; + margin: 0; + padding: 0; + inline-size: 100%; +} @media only screen and (max-height: 480px) { .container { overflow: visible; } } - -@media only screen and (max-height: 480px), only screen and (max-width: 480px) { - .covered { - overflow: hidden; - } -} diff --git a/src/modules/__tests__/gridUtil.spec.js b/src/modules/__tests__/gridUtil.spec.js index 00422220b..b19daee8a 100644 --- a/src/modules/__tests__/gridUtil.spec.js +++ b/src/modules/__tests__/gridUtil.spec.js @@ -10,7 +10,7 @@ import { describe('withShape', () => { it('returns objects with new properties (x, y, w, h)', () => { const items = withShape([{}]) - expect(items).toMatchObject([{ x: 0, y: 0, w: 29, h: 20 }]) + expect(items).toMatchObject([{ x: 0, y: 0, w: 29, h: 32 }]) }) it('returns same objects', () => { @@ -47,17 +47,17 @@ describe('hasShape', () => { describe('getProportionalHeight', () => { it('returns the proportional height in grid units for 480px', () => { const item = { w: 20, h: 20, type: 'CHART' } - expect(getProportionalHeight(item, 480)).toEqual(18) + expect(getProportionalHeight(item, 480)).toEqual(24) }) it('returns the proportional height in grid units for 360px', () => { const item = { w: 20, h: 20, type: 'CHART' } - expect(getProportionalHeight(item, 360)).toEqual(13) + expect(getProportionalHeight(item, 360)).toEqual(18) }) it('returns the initial height for non vis type', () => { const item = { w: 20, h: 10, type: 'TEXT' } - expect(getProportionalHeight(item, 360)).toEqual(8) + expect(getProportionalHeight(item, 360)).toEqual(10) }) }) @@ -85,7 +85,7 @@ describe('getSmallLayout', () => { x: 0, y: 1, w: SM_SCREEN_GRID_COLUMNS, - h: 13, + h: 14, type: 'CHART', i: 'C', }, @@ -93,7 +93,7 @@ describe('getSmallLayout', () => { x: 0, y: 2, w: SM_SCREEN_GRID_COLUMNS, - h: 38, + h: 52, type: 'CHART', i: 'B', }, @@ -101,7 +101,7 @@ describe('getSmallLayout', () => { x: 0, y: 3, w: SM_SCREEN_GRID_COLUMNS, - h: 36, + h: 49, type: 'CHART', i: 'E', }, @@ -109,7 +109,7 @@ describe('getSmallLayout', () => { x: 0, y: 4, w: SM_SCREEN_GRID_COLUMNS, - h: 32, + h: 43, type: 'CHART', i: 'D', }, @@ -117,7 +117,7 @@ describe('getSmallLayout', () => { x: 0, y: 5, w: SM_SCREEN_GRID_COLUMNS, - h: 8, + h: 10, type: 'TEXT', i: 'F', }, diff --git a/src/modules/gridUtil.js b/src/modules/gridUtil.js index 4958bda73..8a5ffe46c 100644 --- a/src/modules/gridUtil.js +++ b/src/modules/gridUtil.js @@ -14,18 +14,16 @@ import { import { isSmallScreen } from './smallScreen.js' export const GRID_COMPACT_TYPE = 'vertical' // vertical | horizonal | null -export const GRID_ROW_HEIGHT_PX = 10 -export const MARGIN_PX = [10, 10] +export const GRID_ROW_HEIGHT_PX = 16 +export const MARGIN_PX = [4, 4] const SM_SCREEN_MIN_ITEM_GRID_HEIGHT = 13 // minimum of ~320px export const SM_SCREEN_GRID_COLUMNS = 1 -export const MARGIN_SM_PX = [0, 16] +export const MARGIN_SM_PX = [4, 4] export const GRID_PADDING_PX = [0, 0] -// sum of left+right padding of dashboard-wrapper (App.css) -export const DASHBOARD_WRAPPER_LR_MARGIN_PX = 32 // make an assumption about the original item w/h ratio // assumes grid width of ~1200px at time dashboard was created -const GRID_COL_WIDTH_PX = 10 +const GRID_COL_WIDTH_PX = 16 export const GRID_COLUMNS = 60 // Dimensions for getShape @@ -87,15 +85,12 @@ export const withShape = (items = []) => { ) } -export const getGridWidth = (windowWidthPx) => - windowWidthPx - DASHBOARD_WRAPPER_LR_MARGIN_PX - const getGridUnitsForSmFromPx = (hPx) => { const gridUnitHeightPx = GRID_ROW_HEIGHT_PX + MARGIN_SM_PX[1] return Math.round((hPx + MARGIN_SM_PX[1]) / gridUnitHeightPx) } -export const getProportionalHeight = (item, windowWidthPx) => { +export const getProportionalHeight = (item, gridWidthPx) => { // get w/h ratio of the original item const wPx = getItemWHPx(item.w, GRID_COL_WIDTH_PX, MARGIN_PX[0]) const hPx = getItemWHPx(item.h, GRID_ROW_HEIGHT_PX, MARGIN_PX[1]) @@ -105,8 +100,6 @@ export const getProportionalHeight = (item, windowWidthPx) => { return getGridUnitsForSmFromPx(hPx) } - const gridWidthPx = getGridWidth(windowWidthPx) - // get new height in px based on the ratio const newColWidthPx = (gridWidthPx - diff --git a/src/modules/smallScreen.js b/src/modules/smallScreen.js index 6c79c8e84..1c6f9e522 100644 --- a/src/modules/smallScreen.js +++ b/src/modules/smallScreen.js @@ -1,8 +1,6 @@ -import { DASHBOARD_WRAPPER_LR_MARGIN_PX } from './gridUtil.js' - const SMALL_SCREEN_BREAKPOINT = 480 export const isSmallScreen = (width) => width <= SMALL_SCREEN_BREAKPOINT -export const getBreakpoint = () => - SMALL_SCREEN_BREAKPOINT - DASHBOARD_WRAPPER_LR_MARGIN_PX +export const getBreakpoint = (containerWidth) => + SMALL_SCREEN_BREAKPOINT - (window.innerWidth - containerWidth) diff --git a/src/pages/edit/ItemGrid.js b/src/pages/edit/ItemGrid.js index fa2464fe7..79fd60fd1 100644 --- a/src/pages/edit/ItemGrid.js +++ b/src/pages/edit/ItemGrid.js @@ -5,10 +5,10 @@ import React, { useState } from 'react' import { Responsive as ResponsiveReactGridLayout } from 'react-grid-layout' import { connect } from 'react-redux' import { acUpdateDashboardItemShapes } from '../../actions/editDashboard.js' +import { useContainerWidth } from '../../components/DashboardContainer.js' import { Item } from '../../components/Item/Item.js' import NoContentMessage from '../../components/NoContentMessage.js' import ProgressiveLoadingContainer from '../../components/ProgressiveLoadingContainer.js' -import { useWindowDimensions } from '../../components/WindowDimensionsProvider.js' import { EDIT } from '../../modules/dashboardModes.js' import { getFirstOfTypes } from '../../modules/getFirstOfType.js' import { getGridItemDomElementClassName } from '../../modules/getGridItemDomElementClassName.js' @@ -19,7 +19,6 @@ import { GRID_PADDING_PX, GRID_COLUMNS, hasShape, - getGridWidth, hasLayout, } from '../../modules/gridUtil.js' import { getBreakpoint } from '../../modules/smallScreen.js' @@ -37,8 +36,8 @@ const EditItemGrid = ({ hasLayout, hideGrid, }) => { + const containerWidth = useContainerWidth() const [gridWidth, setGridWidth] = useState({ width: 0 }) - const { width } = useWindowDimensions() const firstOfTypes = getFirstOfTypes(dashboardItems) const onLayoutChange = (newLayout) => { @@ -90,10 +89,10 @@ const EditItemGrid = ({ -
- TitleBar -
-
- ItemGrid +
+
+ TitleBar +
+
+ ItemGrid +
diff --git a/src/pages/edit/__tests__/__snapshots__/NewDashboard.spec.js.snap b/src/pages/edit/__tests__/__snapshots__/NewDashboard.spec.js.snap index 2e27c8ef3..b77e35642 100644 --- a/src/pages/edit/__tests__/__snapshots__/NewDashboard.spec.js.snap +++ b/src/pages/edit/__tests__/__snapshots__/NewDashboard.spec.js.snap @@ -15,11 +15,15 @@ exports[`NewDashboard renders dashboard 1`] = ` class="container dashboard-scroll-container" data-test="inner-scroll-container" > -
- TitleBar -
-
- ItemGrid +
+
+ TitleBar +
+
+ ItemGrid +
diff --git a/src/pages/print/styles/PrintDashboard.module.css b/src/pages/print/styles/PrintDashboard.module.css index b6baf7955..5d8d2fafc 100644 --- a/src/pages/print/styles/PrintDashboard.module.css +++ b/src/pages/print/styles/PrintDashboard.module.css @@ -5,7 +5,7 @@ } .wrapper { - background-color: #f4f6f8; + background-color: var(--colors-grey200); padding-inline-start: 44px; overflow-y: auto; } diff --git a/src/pages/print/styles/PrintLayoutDashboard.module.css b/src/pages/print/styles/PrintLayoutDashboard.module.css index a6653b866..25ea28339 100644 --- a/src/pages/print/styles/PrintLayoutDashboard.module.css +++ b/src/pages/print/styles/PrintLayoutDashboard.module.css @@ -5,7 +5,7 @@ } .wrapper { - background-color: #f4f6f8; + background-color: var(--colors-grey200); padding-inline-start: 44px; overflow-y: auto; } diff --git a/src/pages/print/styles/print.css b/src/pages/print/styles/print.css index ef3094d8e..c9c585179 100644 --- a/src/pages/print/styles/print.css +++ b/src/pages/print/styles/print.css @@ -15,7 +15,7 @@ header.hidden { inline-size: calc(var(--a4-landscape-width-px) + 18px) !important; border: none !important; box-shadow: none !important; - background-color: #f4f6f8; + background-color: var(--colors-grey200); } .react-grid-item.PAGEBREAK::before { diff --git a/src/pages/view/ItemGrid.js b/src/pages/view/ItemGrid.js index 50252c9be..5e7ccaef9 100644 --- a/src/pages/view/ItemGrid.js +++ b/src/pages/view/ItemGrid.js @@ -6,6 +6,7 @@ import PropTypes from 'prop-types' import React, { useState, useEffect, useRef } from 'react' import { Responsive as ResponsiveReactGridLayout } from 'react-grid-layout' import { useSelector } from 'react-redux' +import { useContainerWidth } from '../../components/DashboardContainer.js' import { Item } from '../../components/Item/Item.js' import NoContentMessage from '../../components/NoContentMessage.js' import ProgressiveLoadingContainer from '../../components/ProgressiveLoadingContainer.js' @@ -22,7 +23,6 @@ import { MARGIN_SM_PX, GRID_COLUMNS, getSmallLayout, - getGridWidth, getProportionalHeight, } from '../../modules/gridUtil.js' import { getBreakpoint, isSmallScreen } from '../../modules/smallScreen.js' @@ -42,6 +42,7 @@ const ResponsiveItemGrid = ({ dashboardIsCached }) => { const dashboardId = useSelector(sGetSelectedId) const dashboardItems = useSelector(sGetSelectedDashboardItems) const { width } = useWindowDimensions() + const containerWidth = useContainerWidth() const { apps } = useCachedDataQuery() const [expandedItems, setExpandedItems] = useState({}) const [displayItems, setDisplayItems] = useState(dashboardItems) @@ -193,10 +194,10 @@ const ResponsiveItemGrid = ({ dashboardIsCached }) => { [classes.slideshowGrid]: isSlideshowView, })} rowHeight={GRID_ROW_HEIGHT_PX} - width={getGridWidth(width)} + width={containerWidth} cols={{ lg: GRID_COLUMNS, sm: SM_SCREEN_GRID_COLUMNS }} breakpoints={{ - lg: getBreakpoint(), + lg: getBreakpoint(containerWidth), sm: 0, }} layouts={{ lg: displayItems, sm: layoutSm }} diff --git a/src/pages/view/__tests__/__snapshots__/ViewDashboard.spec.js.snap b/src/pages/view/__tests__/__snapshots__/ViewDashboard.spec.js.snap index f9540fb80..d7de62831 100644 --- a/src/pages/view/__tests__/__snapshots__/ViewDashboard.spec.js.snap +++ b/src/pages/view/__tests__/__snapshots__/ViewDashboard.spec.js.snap @@ -14,11 +14,15 @@ exports[`ViewDashboard renders dashboard 1`] = ` class="container dashboard-scroll-container" data-test="inner-scroll-container" > -
- MockFilterBar -
-
- MockItemGrid +
+
+ MockFilterBar +
+
+ MockItemGrid +
diff --git a/src/pages/view/styles/ItemGrid.module.css b/src/pages/view/styles/ItemGrid.module.css index 5b3c452f9..d2309f0cf 100644 --- a/src/pages/view/styles/ItemGrid.module.css +++ b/src/pages/view/styles/ItemGrid.module.css @@ -1,10 +1,10 @@ .slideshowContainer { - background-color: #f4f6f8; + background-color: var(--colors-grey200); block-size: 100vh; } .grid { margin-block-start: var(--spacers-dp8); - background-color: #f4f6f8; + background-color: var(--colors-grey200); } /* react-grid-layout uses width and height instead