Skip to content

Commit

Permalink
feat: responsive - disallow editing in small screen (#1419)
Browse files Browse the repository at this point in the history
When screen width is 480px or less, then editing dashboards is disabled. Instead a message is displayed. The user's changes are preserved, so that if the screen becomes wider than 480px, their changes are again shown.

* cypress and unit tests added/updated
* NewDashboard and EditDashboard changed from class to fn components
  • Loading branch information
jenniferarnesen authored Jan 12, 2021
1 parent 4d83168 commit 9932951
Show file tree
Hide file tree
Showing 14 changed files with 707 additions and 146 deletions.
17 changes: 16 additions & 1 deletion cypress/integration/common/common.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Given, Then } from 'cypress-cucumber-preprocessor/steps'
import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps'
import { dashboards } from '../../assets/backends'
import { EXTENDED_TIMEOUT } from '../../support/utils'
import { chartSel } from '../../selectors/dashboardItem'
Expand All @@ -21,3 +21,18 @@ Then('the {string} dashboard displays in view mode', title => {
cy.get(dashboardTitleSel).should('be.visible').and('contain', title)
cy.get(chartSel, EXTENDED_TIMEOUT).should('exist')
})

Given('I choose to create new dashboard', () => {
cy.get('[data-test="link-new-dashboard"]', {
timeout: 15000,
}).click()
})

When('I choose to edit dashboard', () => {
cy.get('[data-test="link-edit-dashboard"]').click()
})

When('dashboard items are added', () => {
cy.get('[data-test="item-search"]').click()
cy.get('[data-test="menu-item-ANC: 1 and 3 coverage Yearly"]').click()
})
19 changes: 4 additions & 15 deletions cypress/integration/ui/edit_dashboard/edit_dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,11 @@ const toggleShowMoreButton = () => {
/*
Scenario: I create a new dashboard
*/
Given('I choose to create new dashboard', () => {
cy.get('[data-test="link-new-dashboard"]', {
timeout: 15000,
}).click()
})

When('dashboard title is added', () => {
cy.get('[data-test="dashboard-title-input"]').type(TEST_DASHBOARD_TITLE)
})

When('dashboard items are added', () => {
cy.get('[data-test="item-search"]').click()
cy.get('[data-test="menu-item-ANC: 1 and 3 coverage Yearly"]').click()
})

When('escape key is pressed', () => {
cy.get('body').trigger('keydown', { key: 'Escape' })
cy.get('[data-test="item-menu]').should('not.exist')
Expand All @@ -66,7 +56,10 @@ When('dashboard is saved', () => {
})

Then('the saved dashboard should be displayed', () => {
cy.get('[data-test="view-dashboard-title"]').contains(TEST_DASHBOARD_TITLE)
cy.get('[data-test="view-dashboard-title"]').should(
'have.text',
TEST_DASHBOARD_TITLE
)
})

Then('dashboard displays in view mode', () => {
Expand All @@ -83,10 +76,6 @@ Given('I open existing dashboard', () => {
cy.get(dashboardChipSel).contains(TEST_DASHBOARD_TITLE).click()
})

When('I choose to edit dashboard', () => {
cy.get('[data-test="link-edit-dashboard"]').click()
})

When('I choose to delete dashboard', () => {
cy.get('[data-test="delete-dashboard-button"]').click()
})
Expand Down
32 changes: 32 additions & 0 deletions cypress/integration/ui/responsive_dashboard.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Feature: Small screen dashboard

@nonmutating
Scenario: I view a dashboard
Given I open the "Delivery" dashboard
When I go to small screen
Then the small screen view is shown
When I restore the wide screen
Then the wide screen view is shown

@nonmutating
Scenario: I am editing an existing dashboard
Given I open the "Delivery" dashboard
When I choose to edit dashboard
And dashboard title is changed
And dashboard items are added
When I go to small screen
Then the small screen edit view is shown
When I restore the wide screen
Then the wide screen edit view is shown
And my changes are still there

@nonmutating
Scenario: I am creating a new dashboard
Given I choose to create new dashboard
And dashboard title is changed
And dashboard items are added
When I go to small screen
Then the small screen edit view is shown
When I restore the wide screen
Then the wide screen edit view is shown
And my changes are still there
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { When, Then } from 'cypress-cucumber-preprocessor/steps'

const TEST_DASHBOARD_TITLE = 'TEST_DASHBOARD_TITLE'

When('I go to small screen', () => {
cy.viewport(460, 600)
// to account for debounced window resize
cy.wait(1000) // eslint-disable-line cypress/no-unnecessary-waiting
})

When('dashboard title is changed', () => {
cy.get('[data-test="dashboard-title-input"]').type(TEST_DASHBOARD_TITLE)
})

Then('the small screen view is shown', () => {
//controlbar - no search dashboard field
cy.get('[data-test="link-new-dashboard"]').should('not.be.visible')

//titlebar - only the More button and the title
cy.get('button').contains('Edit').should('not.be.visible')
cy.get('button').contains('Share').should('not.be.visible')
cy.get('button').contains('Add filter').should('not.be.visible')
cy.get('button').contains('More').should('be.visible')
})

When('I restore the wide screen', () => {
cy.viewport(900, 800)
// to account for debounced window resize
cy.wait(1000) // eslint-disable-line cypress/no-unnecessary-waiting
})

Then('the wide screen view is shown', () => {
cy.get('[data-test="link-new-dashboard"]').should('be.visible')

cy.get('button').contains('Edit').should('be.visible')
cy.get('button').contains('Share').should('be.visible')
cy.get('button').contains('Add filter').should('be.visible')
cy.get('button').contains('More').should('be.visible')
})

Then('the small screen edit view is shown', () => {
//no controlbar
cy.contains('Save changes').should('not.exist')
cy.contains('Exit without saving').should('not.exist')

//notice box and no dashboard
cy.contains('dashboards on small screens is not supported').should(
'be.visible'
)
// no title or item grid
cy.get('[data-test="dashboard-title-input"]').should('not.exist')
cy.get('.react-grid-layout').should('not.exist')
})

Then('the wide screen edit view is shown', () => {
//controlbar
cy.get('button').contains('Save changes').should('be.visible')
cy.get('button').contains('Exit without saving').should('be.visible')

cy.get('[data-test="dashboard-title-input"]').should('be.visible')
cy.get('.react-grid-layout').should('be.visible')
})

Then('my changes are still there', () => {
//title or item changes
var re = new RegExp(TEST_DASHBOARD_TITLE, 'g')
cy.get('[data-test="dashboard-title-input"] input').should($input => {
const val = $input.val()

expect(val).to.match(re)
})
})
13 changes: 11 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2021-01-05T09:32:21.165Z\n"
"PO-Revision-Date: 2021-01-05T09:32:21.165Z\n"
"POT-Creation-Date: 2021-01-05T13:33:31.400Z\n"
"PO-Revision-Date: 2021-01-05T13:33:31.400Z\n"

msgid "Untitled dashboard"
msgstr ""
Expand Down Expand Up @@ -65,6 +65,15 @@ msgstr ""
msgid "No access"
msgstr ""

msgid "Not supported"
msgstr ""

msgid "Editing dashboards on small screens is not supported."
msgstr ""

msgid "Creating dashboards on small screens is not supported."
msgstr ""

msgid "Exit print preview"
msgstr ""

Expand Down
71 changes: 37 additions & 34 deletions src/components/Dashboard/EditDashboard.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React, { Component } from 'react'
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import i18n from '@dhis2/d2-i18n'
import PropTypes from 'prop-types'

import TitleBar from '../TitleBar/TitleBar'
import ItemGrid from '../ItemGrid/ItemGrid'
import EditBar from '../ControlBar/EditBar'
import NotSupportedNotice from './NotSupportedNotice'
import { useWindowDimensions } from '../WindowDimensionsProvider'
import LayoutPrintPreview from './PrintLayoutDashboard'
import NoContentMessage from '../../widgets/NoContentMessage'
import { acSetEditDashboard } from '../../actions/editDashboard'
Expand All @@ -21,35 +23,24 @@ import {
HEADERBAR_HEIGHT,
} from '../ControlBar/controlBarDimensions'

export class EditDashboard extends Component {
state = {
initialized: false,
}
import isSmallScreen from '../../modules/isSmallScreen'

initEditDashboard = () => {
if (this.props.dashboard) {
this.setState({ initialized: true })
this.props.setEditDashboard(this.props.dashboard, this.props.items)
}
}

componentDidMount() {
this.initEditDashboard()
}
const EditDashboard = props => {
const { width } = useWindowDimensions()

componentDidUpdate() {
if (!this.state.initialized) {
this.initEditDashboard()
useEffect(() => {
if (props.dashboard) {
props.setEditDashboard(props.dashboard, props.items)
}
}
}, [props.dashboard])

renderGrid = () => {
if (this.props.isPrintPreviewView) {
const renderGrid = () => {
if (props.isPrintPreviewView) {
return <LayoutPrintPreview fromEdit={true} />
}

const height =
this.props.windowHeight - HEADERBAR_HEIGHT - getControlBarHeight(1)
props.windowHeight - HEADERBAR_HEIGHT - getControlBarHeight(1)

return (
<div className="dashboard-wrapper" style={{ height }}>
Expand All @@ -59,18 +50,30 @@ export class EditDashboard extends Component {
)
}

render() {
return (
<>
<EditBar />
{this.props.updateAccess ? (
this.renderGrid()
) : (
<NoContentMessage text={i18n.t('No access')} />
)}
</>
)
}
const renderEditView = () => (
<>
<EditBar />
{props.updateAccess ? (
renderGrid()
) : (
<NoContentMessage text={i18n.t('No access')} />
)}
</>
)

return (
<>
{isSmallScreen(width) ? (
<NotSupportedNotice
message={i18n.t(
'Editing dashboards on small screens is not supported.'
)}
/>
) : (
renderEditView()
)}
</>
)
}

EditDashboard.propTypes = {
Expand Down
67 changes: 43 additions & 24 deletions src/components/Dashboard/NewDashboard.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React, { Component } from 'react'
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import i18n from '@dhis2/d2-i18n'

import EditBar from '../ControlBar/EditBar'
import TitleBar from '../TitleBar/TitleBar'
import ItemGrid from '../ItemGrid/ItemGrid'
import LayoutPrintPreview from './PrintLayoutDashboard'
import NotSupportedNotice from './NotSupportedNotice'

import { acSetEditNewDashboard } from '../../actions/editDashboard'
import { sGetIsPrintPreviewView } from '../../reducers/editDashboard'
Expand All @@ -16,29 +18,46 @@ import {
HEADERBAR_HEIGHT,
} from '../ControlBar/controlBarDimensions'

class NewDashboard extends Component {
componentDidMount() {
this.props.setNewDashboard()
}

render() {
const height =
this.props.windowHeight - HEADERBAR_HEIGHT - getControlBarHeight(1)

return (
<>
<EditBar />
{this.props.isPrintPreviewView ? (
<LayoutPrintPreview fromEdit={true} />
) : (
<div className="dashboard-wrapper" style={{ height }}>
<TitleBar edit={true} />
<ItemGrid edit={true} />
</div>
)}
</>
)
}
import { useWindowDimensions } from '../WindowDimensionsProvider'
import isSmallScreen from '../../modules/isSmallScreen'

const NewDashboard = props => {
const { width } = useWindowDimensions()

useEffect(() => {
props.setNewDashboard()
}, [])

const height =
props.windowHeight - HEADERBAR_HEIGHT - getControlBarHeight(1)

const renderNewView = () => (
<>
<EditBar />
{props.isPrintPreviewView ? (
<LayoutPrintPreview fromEdit={true} />
) : (
<div className="dashboard-wrapper" style={{ height }}>
<TitleBar edit={true} />
<ItemGrid edit={true} />
</div>
)}
</>
)

return (
<>
{isSmallScreen(width) ? (
<NotSupportedNotice
message={i18n.t(
'Creating dashboards on small screens is not supported.'
)}
/>
) : (
renderNewView()
)}
</>
)
}

NewDashboard.propTypes = {
Expand Down
Loading

0 comments on commit 9932951

Please sign in to comment.