Skip to content

Commit

Permalink
fix: dashboard filter - filter dialog incorrectly shows filter as sel…
Browse files Browse the repository at this point in the history
…ected even though it was removed [DHIS2-9560] (#1074)

The FilterDialog component was always rendered, because FilterSelector is always rendered in the ViewTitleBar. That meant that the filter state was never reset, causing previous item filter to still show.

Fix includes:

* only render the FilterDialog if there is a selected dimension
* move item handling (onSelect, onDeselect...) to the FilterDialog. Since FilterDialog is removed when closed, it will be able to pick up the current state from redux in the useState statement when reopened.
  • Loading branch information
jenniferarnesen authored Sep 24, 2020
1 parent 5a0b3b2 commit 54be7c3
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 136 deletions.
12 changes: 8 additions & 4 deletions src/actions/selected.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { getCustomDashboards, sGetDashboardById } from '../reducers/dashboards'
import {
getCustomDashboards,
sGetDashboardById,
EMPTY_DASHBOARD,
} from '../reducers/dashboards'
import {
SET_SELECTED_ID,
SET_SELECTED_ISLOADING,
Expand Down Expand Up @@ -33,7 +37,6 @@ import {
EVENT_CHART,
MESSAGES,
} from '../modules/itemTypes'
import { orObject } from '../modules/util'

// actions

Expand All @@ -57,8 +60,9 @@ export const tSetSelectedDashboardById = id => async (dispatch, getState) => {
dispatch(acSetSelectedIsLoading(true))

const snackbarTimeout = setTimeout(() => {
const dashboardName = orObject(sGetDashboardById(getState(), id))
.displayName
const dashboardName = (
sGetDashboardById(getState(), id) || EMPTY_DASHBOARD
).displayName
if (sGetSelectedIsLoading(getState()) && dashboardName) {
loadingDashboardMsg.name = dashboardName

Expand Down
7 changes: 1 addition & 6 deletions src/components/Item/ItemHeader/styles/ItemHeader.module.css
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
.itemWrap {
padding: var(--spacers-dp8);
}

.itemHeaderWrap {
display: flex;
margin: var(--spacers-dp4) var(--spacers-dp4) var(--spacers-dp8)
margin: var(--spacers-dp8) var(--spacers-dp4) var(--spacers-dp8)
var(--spacers-dp8);
}

.itemTitle {
font-weight: 700;
color: var(--colors-grey800);
font-size: 14px;
line-height: 28px;
padding: 0;
margin: 0;
align-self: center;
Expand Down
27 changes: 21 additions & 6 deletions src/components/Item/PrintTitlePageItem/Item.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import i18n from '@dhis2/d2-i18n'

import { orObject } from '../../../modules/util'

import {
sGetSelectedId,
sGetSelectedShowDescription,
} from '../../../reducers/selected'
import { sGetDashboardById } from '../../../reducers/dashboards'
import {
sGetDashboardById,
EMPTY_DASHBOARD,
} from '../../../reducers/dashboards'
import { sGetNamedItemFilters } from '../../../reducers/itemFilters'
import { sGetIsEditing } from '../../../reducers/editDashboard'
import {
sGetPrintDashboardName,
sGetPrintDashboardDescription,
} from '../../../reducers/printDashboard'

import classes from './styles/Item.module.css'

Expand Down Expand Up @@ -63,12 +69,21 @@ PrintTitlePageItem.defaultProps = {

const mapStateToProps = state => {
const id = sGetSelectedId(state)
const dashboard = orObject(sGetDashboardById(state, id))
const isEditMode = sGetIsEditing(state)
const viewDashboard = sGetDashboardById(state, id) || EMPTY_DASHBOARD

const name = isEditMode
? sGetPrintDashboardName(state) || i18n.t('Untitled dashboard')
: viewDashboard.displayName

const description = isEditMode
? sGetPrintDashboardDescription(state)
: viewDashboard.displayDescription

return {
name: dashboard.displayName,
name,
description,
itemFilters: sGetNamedItemFilters(state),
description: dashboard.displayDescription,
showDescription: sGetSelectedShowDescription(state),
}
}
Expand Down
147 changes: 95 additions & 52 deletions src/components/ItemFilter/FilterDialog.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { Component } from 'react'
import React, { useState } from 'react'
import PropTypes from 'prop-types'

import { connect } from 'react-redux'
import i18n from '@dhis2/d2-i18n'
import {
Button,
Modal,
Expand All @@ -9,9 +10,6 @@ import {
ModalActions,
ButtonStrip,
} from '@dhis2/ui'

import i18n from '@dhis2/d2-i18n'

import {
PeriodDimension,
DynamicDimension,
Expand All @@ -20,21 +18,71 @@ import {
DIMENSION_ID_ORGUNIT,
} from '@dhis2/analytics'

class FilterDialog extends Component {
onConfirm = id => () => this.props.onConfirm(id)
import { acAddItemFilter, acRemoveItemFilter } from '../../actions/itemFilters'
import { sGetItemFiltersRoot } from '../../reducers/itemFilters'

const FilterDialog = (
{
displayNameProperty,
dimension,
initiallySelectedItems,
addItemFilter,
removeItemFilter,
onClose,
},
context
) => {
const [filters, setFilters] = useState(initiallySelectedItems)

const onSelectItems = ({ dimensionId, items }) => {
setFilters({ [dimensionId]: items })
}

const onDeselectItems = ({ dimensionId, itemIdsToRemove }) => {
const oldList = filters[dimensionId] || []
const newList = oldList.filter(
item => !itemIdsToRemove.includes(item.id)
)

setFilters({ ...filters, [dimensionId]: newList })
}

const onReorderItems = ({ dimensionId, itemIds }) => {
const oldList = filters[dimensionId] || []
const reorderedList = itemIds.map(id =>
oldList.find(item => item.id === id)
)

setFilters({ ...filters, [dimensionId]: reorderedList })
}

const saveFilter = () => {
const id = dimension.id
const filterItems = filters[id]

if (filterItems && filterItems.length) {
addItemFilter({
id,
value: [...filterItems],
})
} else {
removeItemFilter(id)
}

renderDialogContent() {
const { displayNameProperty, dimension, selectedItems } = this.props
const dialogId = dimension.id
onClose(id)
}

const renderDialogContent = () => {
const commonProps = {
d2: this.context.d2,
onSelect: this.props.onSelect,
onDeselect: this.props.onDeselect,
onReorder: this.props.onReorder,
d2: context.d2,
onSelect: onSelectItems,
onDeselect: onDeselectItems,
onReorder: onReorderItems,
}

switch (dialogId) {
const selectedItems = filters[dimension.id] || []

switch (dimension.id) {
case DIMENSION_ID_PERIOD: {
return (
<PeriodDimension
Expand All @@ -55,59 +103,54 @@ class FilterDialog extends Component {
return (
<DynamicDimension
selectedItems={selectedItems}
dimensionId={dialogId}
dimensionId={dimension.id}
onSelect={commonProps.onSelect}
context={commonProps.d2}
/>
)
}
}

render() {
const { dimension, onClose } = this.props
const dialogId = dimension.id

return (
<>
{dialogId && (
<Modal onClose={onClose} position="top" large>
<ModalTitle>{dimension.name}</ModalTitle>
<ModalContent>
{this.renderDialogContent()}
</ModalContent>
<ModalActions>
<ButtonStrip>
<Button secondary onClick={onClose}>
{i18n.t('Cancel')}
</Button>
<Button
primary
onClick={this.onConfirm(dialogId)}
>
{i18n.t('Confirm')}
</Button>
</ButtonStrip>
</ModalActions>
</Modal>
)}
</>
)
}
return (
<>
{dimension.id && (
<Modal onClose={onClose} position="top" large>
<ModalTitle>{dimension.name}</ModalTitle>
<ModalContent>{renderDialogContent()}</ModalContent>
<ModalActions>
<ButtonStrip>
<Button secondary onClick={onClose}>
{i18n.t('Cancel')}
</Button>
<Button primary onClick={saveFilter}>
{i18n.t('Confirm')}
</Button>
</ButtonStrip>
</ModalActions>
</Modal>
)}
</>
)
}

FilterDialog.propTypes = {
addItemFilter: PropTypes.func,
dimension: PropTypes.object,
displayNameProperty: PropTypes.string,
selectedItems: PropTypes.array,
initiallySelectedItems: PropTypes.object,
removeItemFilter: PropTypes.func,
onClose: PropTypes.func,
onConfirm: PropTypes.func,
onDeselect: PropTypes.func,
onReorder: PropTypes.func,
onSelect: PropTypes.func,
}

FilterDialog.contextTypes = {
d2: PropTypes.object,
}

export default FilterDialog
const mapStateToProps = state => ({
initiallySelectedItems: sGetItemFiltersRoot(state),
})

export default connect(mapStateToProps, {
addItemFilter: acAddItemFilter,
removeItemFilter: acRemoveItemFilter,
})(FilterDialog)
Loading

0 comments on commit 54be7c3

Please sign in to comment.