Skip to content

Commit

Permalink
fix: disable View As menu items for maps without a thematic layer [DH…
Browse files Browse the repository at this point in the history
…IS2-10671] (#1632)

If a map doesn't have a thematic layer, then no chart or table can be rendered. Therefore, disable these menu items and add a tooltip informing the user
  • Loading branch information
jenniferarnesen authored Mar 11, 2021
1 parent 67c3a6f commit c521111
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const ItemContextMenu = props => {
type={item.type}
activeType={activeType}
onActiveTypeChanged={onActiveTypeChanged}
visualization={visualization}
/>
{(allowVisShowInterpretations ||
(allowVisOpenInApp &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import i18n from '@dhis2/d2-i18n'
import TableIcon from '@material-ui/icons/ViewList'
import ChartIcon from '@material-ui/icons/InsertChart'
import MapIcon from '@material-ui/icons/Public'
import getThematicMapViews from '../../../../modules/getThematicMapViews'
import {
CHART,
MAP,
Expand All @@ -13,11 +14,16 @@ import {
isTrackerDomainType,
hasMapView,
} from '../../../../modules/itemTypes'
import { MenuItem, colors } from '@dhis2/ui'
import { MenuItem, Tooltip, colors } from '@dhis2/ui'

const iconFill = { fill: colors.grey600 }

const ViewAsMenuItems = ({ type, activeType, onActiveTypeChanged }) => {
const ViewAsMenuItems = ({
type,
activeType,
visualization,
onActiveTypeChanged,
}) => {
const isTrackerType = isTrackerDomainType(type)

const onViewTable = () =>
Expand All @@ -28,23 +34,63 @@ const ViewAsMenuItems = ({ type, activeType, onActiveTypeChanged }) => {

const onViewMap = () => onActiveTypeChanged(MAP)

const isDisabled = type === MAP && !getThematicMapViews(visualization)

const ViewAsChartMenuItem = () => {
const ChartMenuItem = () => (
<MenuItem
dense
disabled={isDisabled}
label={i18n.t('View as Chart')}
onClick={onViewChart}
icon={<ChartIcon style={iconFill} />}
/>
)

if (isDisabled) {
return (
<Tooltip
content={i18n.t("This map can't be displayed as a chart")}
>
<ChartMenuItem />
</Tooltip>
)
}

return <ChartMenuItem />
}

const ViewAsTableMenuItem = () => {
const TableMenuItem = () => (
<MenuItem
dense
disabled={isDisabled}
label={i18n.t('View as Table')}
onClick={onViewTable}
icon={<TableIcon style={iconFill} />}
/>
)

if (isDisabled) {
return (
<Tooltip
content={i18n.t("This map can't be displayed as a table")}
>
<TableMenuItem />
</Tooltip>
)
}

return <TableMenuItem />
}

return (
<>
{activeType !== CHART && activeType !== EVENT_CHART && (
<MenuItem
dense
label={i18n.t('View as Chart')}
onClick={onViewChart}
icon={<ChartIcon style={iconFill} />}
/>
<ViewAsChartMenuItem />
)}
{activeType !== REPORT_TABLE && activeType !== EVENT_REPORT && (
<MenuItem
dense
label={i18n.t('View as Table')}
onClick={onViewTable}
icon={<TableIcon style={iconFill} />}
/>
<ViewAsTableMenuItem />
)}
{hasMapView(type) && activeType !== MAP && (
<MenuItem
Expand All @@ -61,6 +107,7 @@ const ViewAsMenuItems = ({ type, activeType, onActiveTypeChanged }) => {
ViewAsMenuItems.propTypes = {
activeType: PropTypes.string,
type: PropTypes.string,
visualization: PropTypes.object,
onActiveTypeChanged: PropTypes.func,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ test('renders menu for active type CHART and type MAP', async () => {
const props = Object.assign({}, defaultProps, {
type: MAP,
activeType: CHART,
visualization: {
mapViews: [{ layer: 'thematic' }],
},
})

const { container } = render(<ViewAsMenuItems {...props} />)

expect(container).toMatchSnapshot()
})

test('renders menu for active type MAP and type MAP without Thematic layer', async () => {
const props = Object.assign({}, defaultProps, {
type: MAP,
activeType: MAP,
visualization: {
mapViews: [{ layer: 'earthEngine' }],
},
})

const { container } = render(<ViewAsMenuItems {...props} />)
Expand All @@ -39,6 +56,7 @@ test('renders menu for active type REPORT_TABLE and type CHART', async () => {
const props = Object.assign({}, defaultProps, {
type: CHART,
activeType: REPORT_TABLE,
visualization: {},
})

const { container } = render(<ViewAsMenuItems {...props} />)
Expand All @@ -50,6 +68,7 @@ test('renders menu for active type CHART and type REPORT_TABLE', async () => {
const props = Object.assign({}, defaultProps, {
type: REPORT_TABLE,
activeType: CHART,
visualization: {},
})

const { container } = render(<ViewAsMenuItems {...props} />)
Expand All @@ -61,6 +80,7 @@ test('renders menu for active type EVENT_REPORT and type EVENT_CHART', async ()
const props = Object.assign({}, defaultProps, {
type: EVENT_CHART,
activeType: EVENT_REPORT,
visualization: {},
})

const { container } = render(<ViewAsMenuItems {...props} />)
Expand All @@ -72,6 +92,7 @@ test('renders menu for active type EVENT_CHART and type EVENT_REPORT', async ()
const props = Object.assign({}, defaultProps, {
type: EVENT_REPORT,
activeType: EVENT_CHART,
visualization: {},
})

const { container } = render(<ViewAsMenuItems {...props} />)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ exports[`renders menu for active type CHART and type REPORT_TABLE 1`] = `
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-28"
class="MuiSvgIcon-root-37"
focusable="false"
role="presentation"
style="fill: #6e7a8a;"
Expand Down Expand Up @@ -109,7 +109,7 @@ exports[`renders menu for active type CHART and type REPORT_TABLE 1`] = `
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-28"
class="MuiSvgIcon-root-37"
focusable="false"
role="presentation"
style="fill: #6e7a8a;"
Expand Down Expand Up @@ -144,7 +144,7 @@ exports[`renders menu for active type EVENT_CHART and type EVENT_REPORT 1`] = `
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-46"
class="MuiSvgIcon-root-55"
focusable="false"
role="presentation"
style="fill: #6e7a8a;"
Expand Down Expand Up @@ -179,7 +179,7 @@ exports[`renders menu for active type EVENT_REPORT and type EVENT_CHART 1`] = `
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-37"
class="MuiSvgIcon-root-46"
focusable="false"
role="presentation"
style="fill: #6e7a8a;"
Expand Down Expand Up @@ -265,6 +265,81 @@ exports[`renders menu for active type MAP and type CHART 1`] = `
</div>
`;

exports[`renders menu for active type MAP and type MAP without Thematic layer 1`] = `
<div>
<span
class="jsx-611321200"
data-test="dhis2-uicore-tooltip-reference"
>
<li
class="jsx-665727467 disabled dense"
data-test="dhis2-uicore-menuitem"
>
<a
class="jsx-665727467"
>
<span
class="jsx-665727467 icon"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-19"
focusable="false"
role="presentation"
style="fill: #6e7a8a;"
viewBox="0 0 24 24"
>
<path
d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"
/>
</svg>
</span>
<span
class="jsx-665727467 label"
>
View as Chart
</span>
</a>
</li>
</span>
<span
class="jsx-611321200"
data-test="dhis2-uicore-tooltip-reference"
>
<li
class="jsx-665727467 disabled dense"
data-test="dhis2-uicore-menuitem"
>
<a
class="jsx-665727467"
>
<span
class="jsx-665727467 icon"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-19"
focusable="false"
role="presentation"
style="fill: #6e7a8a;"
viewBox="0 0 24 24"
>
<path
d="M4 14h4v-4H4v4zm0 5h4v-4H4v4zM4 9h4V5H4v4zm5 5h12v-4H9v4zm0 5h12v-4H9v4zM9 5v4h12V5H9z"
/>
</svg>
</span>
<span
class="jsx-665727467 label"
>
View as Table
</span>
</a>
</li>
</span>
</div>
`;

exports[`renders menu for active type REPORT_TABLE and type CHART 1`] = `
<div>
<li
Expand All @@ -279,7 +354,7 @@ exports[`renders menu for active type REPORT_TABLE and type CHART 1`] = `
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-19"
class="MuiSvgIcon-root-28"
focusable="false"
role="presentation"
style="fill: #6e7a8a;"
Expand Down Expand Up @@ -309,7 +384,7 @@ exports[`renders menu for active type REPORT_TABLE and type CHART 1`] = `
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-19"
class="MuiSvgIcon-root-28"
focusable="false"
role="presentation"
style="fill: #6e7a8a;"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import MapPlugin from './MapPlugin'
import DataVisualizerPlugin from './DataVisualizerPlugin'
import NoVisualizationMessage from './NoVisualizationMessage'

import getFilteredVisualization from './getFilteredVisualization'
import getVisualizationConfig from './getVisualizationConfig'
import getFilteredVisualization from '../../../../modules/getFilteredVisualization'
import getVisualizationConfig from '../../../../modules/getVisualizationConfig'
import {
VISUALIZATION,
MAP,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import {
AXIS_ID_FILTERS,
} from '@dhis2/analytics'

import getVisualizationConfig, {
THEMATIC_LAYER,
} from '../getVisualizationConfig'
import { REPORT_TABLE, CHART, MAP } from '../../../../../modules/itemTypes'
import getVisualizationConfig from '../getVisualizationConfig'
import { THEMATIC_LAYER } from '../getThematicMapViews'
import { REPORT_TABLE, CHART, MAP } from '../itemTypes'

describe('getVisualizationConfig', () => {
let visualization
Expand Down
File renamed without changes.
6 changes: 6 additions & 0 deletions src/modules/getThematicMapViews.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const THEMATIC_LAYER = 'thematic'

const getThematicMapViews = map =>
map.mapViews && map.mapViews.find(mv => mv.layer.includes(THEMATIC_LAYER))

export default getThematicMapViews
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import getThematicMapViews from './getThematicMapViews'
import {
VIS_TYPE_COLUMN,
VIS_TYPE_PIVOT_TABLE,
getAdaptedUiLayoutByType,
} from '@dhis2/analytics'
import { REPORT_TABLE, CHART, MAP } from '../../../../modules/itemTypes'

export const THEMATIC_LAYER = 'thematic'

const extractMapView = map =>
map.mapViews && map.mapViews.find(mv => mv.layer.includes(THEMATIC_LAYER))
import { REPORT_TABLE, CHART, MAP } from './itemTypes'

const getWithoutId = object => ({
...object,
Expand All @@ -17,15 +13,15 @@ const getWithoutId = object => ({

const getVisualizationConfig = (visualization, originalType, activeType) => {
if (originalType === MAP && originalType !== activeType) {
const extractedMapView = extractMapView(visualization)
const thematicMapViews = getThematicMapViews(visualization)

if (extractedMapView === undefined) {
if (thematicMapViews === undefined) {
return null
}

return getWithoutId({
...visualization,
...extractedMapView,
...thematicMapViews,
mapViews: undefined,
type: activeType === CHART ? VIS_TYPE_COLUMN : VIS_TYPE_PIVOT_TABLE,
})
Expand Down

0 comments on commit c521111

Please sign in to comment.