Skip to content

Commit

Permalink
feat(DHIS2-17002): display custom text before and after a section (#373)
Browse files Browse the repository at this point in the history
* feat(DHIS2-17002): display custom text before and after a section

* refactor: apply code review comments
  • Loading branch information
kabaros authored Mar 18, 2024
1 parent 72c96bf commit 0fdd239
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 80 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@tanstack/react-query-persist-client": "4.24.10",
"chart.js": "3.9.1",
"classnames": "2.3.2",
"dompurify": "^3.0.9",
"expr-eval": "2.0.2",
"final-form": "4.20.9",
"final-form-set-field-data": "1.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,6 @@ export const PivotedCategoryComboTableBody = React.memo(
}
)

export const DisplayOptionsProps = PropTypes.shape({
pivotMode: PropTypes.oneOf(['move_categories', 'pivot']),
pivotedCategory: PropTypes.string,
textAfterSection: PropTypes.string,
textBeforeSection: PropTypes.string,
})

PivotedCategoryComboTableBody.propTypes = {
categoryCombo: PropTypes.shape({
id: PropTypes.string.isRequired,
Expand All @@ -167,7 +160,12 @@ PivotedCategoryComboTableBody.propTypes = {
valueType: PropTypes.string,
})
),
displayOptions: DisplayOptionsProps,
displayOptions: PropTypes.shape({
afterSectionText: PropTypes.string,
beforeSectionText: PropTypes.string,
pivotMode: PropTypes.oneOf(['move_categories', 'pivot']),
pivotedCategory: PropTypes.string,
}),
/** Greyed fields is a Set where .has(fieldId) is true if that field is greyed/disabled */
greyedFields: PropTypes.instanceOf(Set),
}
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
export {
PivotedCategoryComboTableBody,
DisplayOptionsProps,
} from '../category-combo-table-body-pivoted/category-combo-table-body-pivoted.js'
export { PivotedCategoryComboTableBody } from '../category-combo-table-body-pivoted/category-combo-table-body-pivoted.js'
24 changes: 24 additions & 0 deletions src/data-workspace/section-form/section-description.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as DOMPurify from 'dompurify'
import PropTypes from 'prop-types'
import React from 'react'
import styles from './section.module.css'

export const SectionDescription = ({ children }) => {
if (!children) {
return null
}
const html = DOMPurify.sanitize(children, {
ALLOWED_TAGS: ['a', 'b', 'strong', 'underline'],
})

return (
<div
className={styles.sectionDescription}
dangerouslySetInnerHTML={{ __html: html }}
></div>
)
}

SectionDescription.propTypes = {
children: PropTypes.node,
}
148 changes: 80 additions & 68 deletions src/data-workspace/section-form/section.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ import PropTypes from 'prop-types'
import React, { useMemo, useState } from 'react'
import { useMetadata, selectors } from '../../shared/index.js'
import { CategoryComboTableBody } from '../category-combo-table-body/index.js'
import {
PivotedCategoryComboTableBody,
DisplayOptionsProps,
} from '../category-combo-table-body-pivoted/index.js'
import { PivotedCategoryComboTableBody } from '../category-combo-table-body-pivoted/index.js'
import { getFieldId } from '../get-field-id.js'
import { IndicatorsTableBody } from '../indicators-table-body/indicators-table-body.js'
import { SectionDescription } from './section-description.js'
import styles from './section.module.css'

export function SectionFormSection({ section, dataSetId, globalFilterText }) {
Expand Down Expand Up @@ -77,72 +75,86 @@ export function SectionFormSection({ section, dataSetId, globalFilterText }) {
? PivotedCategoryComboTableBody
: CategoryComboTableBody

const { beforeSectionText, afterSectionText } = displayOptions

return (
<Table className={styles.table} suppressZebraStriping>
<TableHead>
<TableRowHead>
<TableCellHead colSpan="100%" className={styles.headerCell}>
<div className={styles.labelWrapper}>
<div className={styles.title}>
{section.displayName}
</div>
{section.description && (
<div className={styles.description}>
{section.description ||
'Placeholder section description'}
</div>
)}
</div>
</TableCellHead>
</TableRowHead>
<TableRowHead>
<TableCellHead colSpan="100%" className={headerCellStyles}>
<label
htmlFor={filterInputId}
className={styles.filterWrapper}
<div>
<SectionDescription>{beforeSectionText}</SectionDescription>
<Table className={styles.table} suppressZebraStriping>
<TableHead>
<TableRowHead>
<TableCellHead
colSpan="100%"
className={styles.headerCell}
>
<IconFilter16 color={colors.grey600} />
<input
name={filterInputId}
id={filterInputId}
type="text"
placeholder={i18n.t(
'Type here to filter in this section'
<div className={styles.labelWrapper}>
<div className={styles.title}>
{section.displayName}
</div>
{section.description && (
<div className={styles.description}>
{section.description ||
'Placeholder section description'}
</div>
)}
value={filterText}
onChange={({ target }) =>
setFilterText(target.value)
}
className={styles.filterInput}
/>
</label>
</TableCellHead>
</TableRowHead>
</TableHead>
{groupedDataElements.map(({ categoryCombo, dataElements }, i) => (
<TableComponet
key={i} //if disableDataElementAutoGroup then duplicate catCombo-ids, so have to use index
categoryCombo={categoryCombo}
dataElements={dataElements}
filterText={filterText}
globalFilterText={globalFilterText}
maxColumnsInSection={maxColumnsInSection}
renderRowTotals={section.showRowTotals}
renderColumnTotals={section.showColumnTotals}
greyedFields={greyedFields}
displayOptions={displayOptions}
/>
))}
{indicators.length > 0 && (
<IndicatorsTableBody
indicators={indicators}
renderRowTotals={section.showRowTotals}
maxColumnsInSection={maxColumnsInSection}
filterText={filterText}
globalFilterText={globalFilterText}
/>
)}
</Table>
</div>
</TableCellHead>
</TableRowHead>
<TableRowHead>
<TableCellHead
colSpan="100%"
className={headerCellStyles}
>
<label
htmlFor={filterInputId}
className={styles.filterWrapper}
>
<IconFilter16 color={colors.grey600} />
<input
name={filterInputId}
id={filterInputId}
type="text"
placeholder={i18n.t(
'Type here to filter in this section'
)}
value={filterText}
onChange={({ target }) =>
setFilterText(target.value)
}
className={styles.filterInput}
/>
</label>
</TableCellHead>
</TableRowHead>
</TableHead>
{groupedDataElements.map(
({ categoryCombo, dataElements }, i) => (
<TableComponet
key={i} //if disableDataElementAutoGroup then duplicate catCombo-ids, so have to use index
categoryCombo={categoryCombo}
dataElements={dataElements}
filterText={filterText}
globalFilterText={globalFilterText}
maxColumnsInSection={maxColumnsInSection}
renderRowTotals={section.showRowTotals}
renderColumnTotals={section.showColumnTotals}
greyedFields={greyedFields}
displayOptions={displayOptions}
/>
)
)}
{indicators.length > 0 && (
<IndicatorsTableBody
indicators={indicators}
renderRowTotals={section.showRowTotals}
maxColumnsInSection={maxColumnsInSection}
filterText={filterText}
globalFilterText={globalFilterText}
/>
)}
</Table>
<SectionDescription>{afterSectionText}</SectionDescription>
</div>
)
}

Expand All @@ -156,7 +168,7 @@ SectionFormSection.propTypes = {
description: PropTypes.string,
disableDataElementAutoGroup: PropTypes.bool,
displayName: PropTypes.string,
displayOptions: DisplayOptionsProps,
displayOptions: PropTypes.string,
greyedFields: PropTypes.array,
id: PropTypes.string,
showColumnTotals: PropTypes.bool,
Expand Down
14 changes: 14 additions & 0 deletions src/data-workspace/section-form/section.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,18 @@
.hideForPrint {
composes: hideForPrint from '../../app/app.css'
}
}

/* section description area */
.sectionDescription {
margin: 12px 4px 8px;
font-size: 13px;
color: var(--colors-grey800)
}

.sectionDescription :global(a):link,
.sectionDescription :global(a):visited,
.sectionDescription :global(a):hover,
.sectionDescription :global(a):active {
color: var(--colors-blue700)
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6787,6 +6787,11 @@ domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3:
dependencies:
domelementtype "^2.3.0"

dompurify@^3.0.9:
version "3.0.9"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.9.tgz#b3f362f24b99f53498c75d43ecbd784b0b3ad65e"
integrity sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ==

domutils@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
Expand Down

1 comment on commit 0fdd239

@dhis2-bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.