Skip to content

Commit

Permalink
fix: adjust filter-badge so that it is only enabled when online and a…
Browse files Browse the repository at this point in the history
…lign tests accordingly
  • Loading branch information
HendrikThePendric committed Dec 4, 2024
1 parent 6698c1c commit cd451b8
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 136 deletions.
86 changes: 41 additions & 45 deletions src/pages/view/FilterBar/FilterBadge.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,66 +6,62 @@ import PropTypes from 'prop-types'
import React from 'react'
import { connect } from 'react-redux'
import { acSetActiveModalDimension } from '../../../actions/activeModalDimension.js'
import { useCacheableSection } from '../../../modules/useCacheableSection.js'
import { sGetSelectedId } from '../../../reducers/selected.js'
import classes from './styles/FilterBadge.module.css'

const FilterBadge = ({ dashboardId, filter, openFilterModal, onRemove }) => {
const { isConnected: online } = useDhis2ConnectionStatus()
const { isCached } = useCacheableSection(dashboardId)
const getFilterValuesText = (values) =>
values.length === 1
? values[0].name
: i18n.t('{{count}} selected', { count: values.length })

const notAllowed = !isCached && !online

const filterText = `${filter.name}: ${
filter.values.length > 1
? i18n.t('{{count}} selected', {
count: filter.values.length,
})
: filter.values[0].name
}`
const FilterBadge = ({ filter, openFilterModal, onRemove }) => {
const { isConnected } = useDhis2ConnectionStatus()

return (
<div className={classes.container} data-test="dashboard-filter-badge">
<button
className={cx(classes.button, classes.filterButton)}
onClick={() =>
openFilterModal({
id: filter.id,
name: filter.name,
})
}
>
{filterText}
</button>
<Tooltip
content={i18n.t('Cannot remove filters while offline')}
openDelay={200}
closeDelay={100}
className={classes.tooltip}
>
{({ onFocus, onBlur, onMouseOver, onMouseOut, ref }) => (
<Tooltip
content={i18n.t('Cannot edit filters while offline')}
openDelay={200}
closeDelay={100}
className={classes.tooltip}
>
{({ onFocus, onBlur, onMouseOver, onMouseOut, ref }) => (
<div
className={classes.container}
data-test="dashboard-filter-badge"
onFocus={() => !isConnected && onFocus()}
onBlur={() => !isConnected && onBlur()}
onMouseOver={() => !isConnected && onMouseOver()}
onMouseOut={() => !isConnected && onMouseOut()}
ref={ref}
>
<button
data-test="filter-badge-button"
className={cx(classes.button, classes.filterButton)}
disabled={!isConnected}
onClick={() =>
openFilterModal({
id: filter.id,
name: filter.name,
})
}
>
{filter.name}: {getFilterValuesText(filter.values)}
</button>
<button
className={cx(classes.button, classes.removeButton, {
[classes.notAllowed]: notAllowed,
})}
onFocus={onFocus}
onBlur={onBlur}
onMouseOver={() => notAllowed && onMouseOver()}
onMouseOut={() => notAllowed && onMouseOut()}
ref={ref}
disabled={notAllowed}
data-test="filter-badge-clear-button"
className={cx(classes.button, classes.removeButton)}
disabled={!isConnected}
onClick={() => onRemove(filter.id)}
>
<IconCross16 />
</button>
)}
</Tooltip>
</div>
</div>
)}
</Tooltip>
)
}

FilterBadge.propTypes = {
dashboardId: PropTypes.string.isRequired,
filter: PropTypes.object.isRequired,
openFilterModal: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
Expand Down
86 changes: 59 additions & 27 deletions src/pages/view/FilterBar/__tests__/FilterBadge.spec.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,47 @@
import { useDhis2ConnectionStatus } from '@dhis2/app-runtime'
import { render } from '@testing-library/react'
import React from 'react'
import { Provider } from 'react-redux'
import configureMockStore from 'redux-mock-store'
import { createStore } from 'redux'
import FilterBadge from '../FilterBadge.js'

const mockStore = configureMockStore()

const store = { selected: { id: 'dashboard1' } }

jest.mock('@dhis2/analytics', () => ({
useCachedDataQuery: () => ({
currentUser: {
username: 'rainbowDash',
id: 'r3nb0d5h',
},
}),
}))

jest.mock('@dhis2/app-runtime', () => ({
useDhis2ConnectionStatus: () => ({ isConnected: true }),
useCacheableSection: jest.fn(() => ({
isCached: false,
recordingState: 'default',
})),
useDhis2ConnectionStatus: jest.fn(() => ({ isConnected: true })),
}))

test('Filter Badge displays badge containing number of items in filter', () => {
const baseState = { selected: { id: 'dashboard1' } }
const createMockStore = (state) =>
createStore(() => Object.assign({}, baseState, state))

test('Displays badge containing number of filter items when filtered on multiple', () => {
const filter = {
id: 'ponies',
name: 'Ponies',
values: [{ name: 'Rainbow Dash' }, { name: 'Twilight Sparkle' }],
}
const { container } = render(
<Provider store={mockStore(store)}>
const { getByTestId } = render(
<Provider store={createMockStore()}>
<FilterBadge
filter={filter}
openFilterModal={jest.fn()}
removeFilter={jest.fn}
onRemove={Function.prototype}
/>
</Provider>
)
expect(getByTestId('filter-badge-button')).toHaveTextContent(
'Ponies: 2 selected'
)
})

test('Displays badge with filter item name when only one filter item is present', () => {
const filter = {
id: 'ponies',
name: 'Ponies',
values: [{ name: 'Twilight Sparkle' }],
}
const { getByTestId } = render(
<Provider store={createMockStore()}>
<FilterBadge
filter={filter}
openFilterModal={jest.fn()}
Expand All @@ -41,18 +50,40 @@ test('Filter Badge displays badge containing number of items in filter', () => {
/>
</Provider>
)
expect(container).toMatchSnapshot()
expect(getByTestId('filter-badge-button')).toHaveTextContent(
'Ponies: Twilight Sparkle'
)
})

test('FilterBadge displays badge with filter item name when only one filter item', () => {
test('Has enabled buttons when online', () => {
const filter = {
id: 'ponies',
name: 'Ponies',
values: [{ name: 'Twilight Sparkle' }],
}
const { getByTestId } = render(
<Provider store={createMockStore()}>
<FilterBadge
filter={filter}
openFilterModal={jest.fn()}
removeFilter={jest.fn}
onRemove={Function.prototype}
/>
</Provider>
)
expect(getByTestId('filter-badge-button')).toBeEnabled()
expect(getByTestId('filter-badge-clear-button')).toBeEnabled()
})

const { container } = render(
<Provider store={mockStore(store)}>
test('Has disabled buttons when offline', () => {
useDhis2ConnectionStatus.mockImplementation(() => ({ isConnected: false }))
const filter = {
id: 'ponies',
name: 'Ponies',
values: [{ name: 'Twilight Sparkle' }],
}
const { getByTestId } = render(
<Provider store={createMockStore()}>
<FilterBadge
filter={filter}
openFilterModal={jest.fn()}
Expand All @@ -61,5 +92,6 @@ test('FilterBadge displays badge with filter item name when only one filter item
/>
</Provider>
)
expect(container).toMatchSnapshot()
expect(getByTestId('filter-badge-button')).toBeDisabled()
expect(getByTestId('filter-badge-clear-button')).toBeDisabled()
})

This file was deleted.

10 changes: 5 additions & 5 deletions src/pages/view/FilterBar/styles/FilterBadge.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
cursor: pointer;
}

.button:hover:not(.notAllowed) {
.button:disabled {
cursor: not-allowed;
}

.button:hover:not(:disabled) {
background-color: var(--colors-grey800);
}

Expand All @@ -29,7 +33,3 @@
border-start-end-radius: 4px;
border-end-end-radius: 4px;
}

.removeButton.notAllowed {
cursor: not-allowed;
}

0 comments on commit cd451b8

Please sign in to comment.