Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: distinguish non-existent repetitions from empty values in line lists (DHIS2-15767) #427

Merged
merged 24 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d69db02
fix: add custom styling to undefined cells
martinkrulltott Sep 4, 2023
dfb3b45
fix: update color according to spec change
martinkrulltott Sep 7, 2023
b1a44e9
Merge branch 'master' into feat/DHIS2-15767-undefined-cells
martinkrulltott Sep 11, 2023
bedde9a
fix: add tooltip to undefined cells
martinkrulltott Sep 11, 2023
945f944
chore: update PR template
martinkrulltott Sep 11, 2023
2abe4c6
test: add tests for undefined values
martinkrulltott Sep 12, 2023
f620e9f
test: change test cell to match test.e2e data
martinkrulltott Sep 13, 2023
74e6bcc
Merge branch 'master' into feat/DHIS2-15767-undefined-cells
janhenrikoverland Sep 25, 2023
01617a3
refactor: apply changes / suggestions from recent review
martinkrulltott Sep 25, 2023
dd3a385
chore: update PR template
martinkrulltott Sep 27, 2023
bbbeb5e
chore: merge with master
martinkrulltott Sep 27, 2023
0791232
Merge branch 'master' into feat/DHIS2-15767-undefined-cells
martinkrulltott Sep 28, 2023
8efb241
Merge branch 'master' into feat/DHIS2-15767-undefined-cells
martinkrulltott Oct 2, 2023
5c26627
fix: remove background color for undefined cell
martinkrulltott Oct 3, 2023
0117956
Merge branch 'master' into feat/DHIS2-15767-undefined-cells
janhenrikoverland Oct 3, 2023
ad704c5
fix: change background image for undefined cell
martinkrulltott Oct 3, 2023
85a2b72
Merge branch 'master' into feat/DHIS2-15767-undefined-cells
martinkrulltott Oct 6, 2023
e069d94
chore: merge with master (conflicts in Visualization.js)
martinkrulltott Nov 23, 2023
c585293
Merge branch 'master' into feat/DHIS2-15767-undefined-cells
martinkrulltott Nov 24, 2023
d3256f4
fix: return empty value for undefined boolean cells
martinkrulltott Nov 24, 2023
a412513
Merge branch 'master' into feat/DHIS2-15767-undefined-cells
martinkrulltott Nov 27, 2023
13528fc
Merge branch 'master' into feat/DHIS2-15767-undefined-cells
martinkrulltott Nov 27, 2023
2b6d2b5
fix: always display 'no event' for enrollment
martinkrulltott Nov 29, 2023
c829396
test: change tooltip label
martinkrulltott Nov 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ _text_

### TODO

- [ ] Cypress tests
- [ ] Update docs
- [ ] Manual testing
- [ ] _task_

---
Expand Down
39 changes: 39 additions & 0 deletions cypress/integration/repeatedEvents.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import {
getTableHeaderCells,
expectTableToBeVisible,
getTableDataCells,
getTableRows,
} from '../helpers/table.js'
import { EXTENDED_TIMEOUT } from '../support/util.js'

const getRepeatedEventsTab = () =>
cy.getBySel('conditions-modal-content').contains('Repeated events')
Expand Down Expand Up @@ -221,4 +223,41 @@ describe('repeated events', () => {

getRepeatedEventsTab().should('not.have.class', 'disabled')
})
it('undefined values display properly for a repeated event', () => {
const TEST_CELL = {
row: 6,
column: 3,
}
goToAO('WrIV7ZoYECj')

cy.getBySel('titlebar', EXTENDED_TIMEOUT)
.should('be.visible')
.and('contain', 'E2E: Enrollment - Hemoglobin (repeated)')

getTableRows()
.eq(TEST_CELL.row)
.find('td')
.eq(TEST_CELL.column)
.invoke('text')
.invoke('trim')
.should('equal', '')

getTableRows()
.eq(TEST_CELL.row)
.find('td')
.eq(TEST_CELL.column)
.should(($td) => {
const className = $td[0].className

expect(className).to.match(/Visualization_undefinedCell*/)
})

getTableRows()
.eq(TEST_CELL.row)
.find('td')
.eq(TEST_CELL.column)
.trigger('mouseover')

cy.getBySelLike('tooltip-content').contains('No repeated event')
})
})
7 changes: 5 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: 2023-09-05T07:20:57.111Z\n"
"PO-Revision-Date: 2023-09-05T07:20:57.111Z\n"
"POT-Creation-Date: 2023-09-11T08:06:44.556Z\n"
"PO-Revision-Date: 2023-09-11T08:06:44.556Z\n"

msgid "Add to {{axisName}}"
msgstr "Add to {{axisName}}"
Expand Down Expand Up @@ -382,6 +382,9 @@ msgstr "Not available offline"
msgid "Sort by {{column}}"
msgstr "Sort by {{column}}"

msgid "No repeated event"
msgstr "No repeated event"

msgid "Rows per page"
msgstr "Rows per page"

Expand Down
125 changes: 74 additions & 51 deletions src/components/Visualization/Visualization.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export const PAGE_SIZE = 100
// +/- min width of "Rows per page" select + 2 * padding
// + 30% in case label text are longer than English
export const PAGINATION_MIN_WIDTH = 250
const NOT_DEFINED_VALUE = 'ND'

const getFontSizeClass = (fontSize) => {
switch (fontSize) {
Expand Down Expand Up @@ -312,6 +313,55 @@ export const Visualization = ({

const isInModal = !!filters?.relativePeriodDate

const cellIsUndefined = (rowIndex, columnIndex) => {
const row = (data.rowContext || {})[rowIndex]
return row && row[columnIndex]?.valueStatus === NOT_DEFINED_VALUE
}

const renderCellContent = ({ columnIndex, value, isUndefined, props }) => (
<DataTableCell
{...props}
key={columnIndex}
className={cx(
styles.cell,
fontSizeClass,
sizeClass,
{
[styles.emptyCell]: !value,
[styles.nowrap]: cellValueShouldNotWrap(
data.headers[columnIndex]
),
[styles.undefinedCell]: isUndefined,
},
'bordered'
)}
backgroundColor={
visualization.legend?.style === LEGEND_DISPLAY_STYLE_FILL
? getColorByValueFromLegendSet(
data.headers[columnIndex].legendSet,
value
)
: undefined
}
dataTest={'table-cell'}
>
<div
style={
visualization.legend?.style === LEGEND_DISPLAY_STYLE_TEXT
? {
color: getColorByValueFromLegendSet(
data.headers[columnIndex].legendSet,
value
),
}
: {}
}
>
{formatCellValue(value, data.headers[columnIndex])}
</div>
</DataTableCell>
)

return (
<div className={styles.pluginContainer} ref={containerCallbackRef}>
<div
Expand Down Expand Up @@ -378,58 +428,31 @@ export const Visualization = ({
</DataTableHead>
{/* https://jira.dhis2.org/browse/LIBS-278 */}
<DataTableBody dataTest={'table-body'}>
{data.rows.map((row, index) => (
<DataTableRow key={index} dataTest={'table-row'}>
{row.map((value, index) => (
<DataTableCell
key={index}
className={cx(
styles.cell,
fontSizeClass,
sizeClass,
{
[styles.emptyCell]: !value,
[styles.nowrap]:
cellValueShouldNotWrap(
data.headers[index]
),
},
'bordered'
)}
backgroundColor={
visualization.legend?.style ===
LEGEND_DISPLAY_STYLE_FILL
? getColorByValueFromLegendSet(
data.headers[index]
.legendSet,
value
)
: undefined
}
dataTest={'table-cell'}
>
<div
style={
visualization.legend?.style ===
LEGEND_DISPLAY_STYLE_TEXT
? {
color: getColorByValueFromLegendSet(
data.headers[
index
].legendSet,
value
),
}
: {}
}
>
{formatCellValue(
value,
data.headers[index]
{data.rows.map((row, rowIndex) => (
<DataTableRow key={rowIndex} dataTest={'table-row'}>
{row.map((value, columnIndex) =>
cellIsUndefined(rowIndex, columnIndex) ? (
<Tooltip
content={i18n.t(
'No repeated event'
)}
</div>
</DataTableCell>
))}
>
{(props) =>
renderCellContent({
columnIndex,
value,
isUndefined: true,
props,
})
}
</Tooltip>
) : (
renderCellContent({
columnIndex,
value,
})
)
)}
</DataTableRow>
))}
</DataTableBody>
Expand Down
11 changes: 11 additions & 0 deletions src/components/Visualization/styles/Visualization.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@
white-space: nowrap;
}

.dataTable .undefinedCell {
background-image: repeating-linear-gradient(
45deg,
var(--colors-grey300) 0,
var(--colors-grey300) 0.8px,
transparent 0,
transparent 50%
);
background-size: 8px 8px;
}

/* Sizes for the table footer */
.dataTable .stickyNavigation.sizeComfortable {
padding: 14px 12px;
Expand Down
8 changes: 7 additions & 1 deletion src/components/Visualization/useAnalyticsData.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ const fetchAnalyticsData = async ({
.withParameters({
headers,
totalPages: false,
...(headers.some((header) => Array.isArray(header))
? { rowContext: true }
: {}),
...parameters,
})
.withProgram(visualization.program.id)
Expand Down Expand Up @@ -271,6 +274,8 @@ const extractRows = (analyticsResponse, headers) => {
return filteredRows
}

const extractRowContext = (analyticsResponse) => analyticsResponse.rowContext

const valueTypeIsNumeric = (valueType) =>
[
VALUE_TYPE_NUMBER,
Expand Down Expand Up @@ -316,6 +321,7 @@ const useAnalyticsData = ({
})
const headers = extractHeaders(analyticsResponse)
const rows = extractRows(analyticsResponse, headers)
const rowContext = extractRowContext(analyticsResponse)
const pager = analyticsResponse.metaData.pager
const legendSetIds = []
const headerLegendSetMap = headers.reduce(
Expand Down Expand Up @@ -368,7 +374,7 @@ const useAnalyticsData = ({
}

mounted.current && setError(undefined)
mounted.current && setData({ headers, rows, pager })
mounted.current && setData({ headers, rows, pager, rowContext })
onResponsesReceived(analyticsResponse)
} catch (error) {
mounted.current && setError(error)
Expand Down
Loading