Skip to content

Commit

Permalink
Merge pull request #390 from dhis2/DHIS2-17507/collapse-sections
Browse files Browse the repository at this point in the history
feat: make data sets sections collapsable
  • Loading branch information
flaminic authored Sep 9, 2024
2 parents b48e1ff + 98217d2 commit 1908b30
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ export const PivotedCategoryComboTableBody = React.memo(
categoryCombo,
dataElements,
greyedFields,
/*
/*
filterText,
globalFilterText,
maxColumnsInSection,
renderRowTotals,
renderColumnTotals,*/
displayOptions,
collapsed,
}) {
const { data: metadata } = useMetadata()

Expand Down Expand Up @@ -68,7 +69,12 @@ export const PivotedCategoryComboTableBody = React.memo(
<>
{rowsMatrix.map((row, id /** todo: find suitable id */) => {
return (
<TableRow key={id}>
<TableRow
key={id}
className={classNames({
[styles.sectionRowCollapsed]: collapsed,
})}
>
{row.map((fieldInRow) => {
if (
fieldInRow.type === 'columnHeader' ||
Expand Down Expand Up @@ -150,6 +156,7 @@ PivotedCategoryComboTableBody.propTypes = {
categoryCombo: PropTypes.shape({
id: PropTypes.string.isRequired,
}),
collapsed: PropTypes.bool,
dataElements: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { TableBody, TableRow, TableCell } from '@dhis2/ui'
import { TableBody, TableCell, TableRow } from '@dhis2/ui'
import cx from 'classnames'
import PropTypes from 'prop-types'
import React, { useCallback } from 'react'
import { useMetadata, selectors } from '../../shared/index.js'
import { selectors, useMetadata } from '../../shared/index.js'
import { DataEntryCell, DataEntryField } from '../data-entry-cell/index.js'
import { getFieldId } from '../get-field-id.js'
import { TableBodyHiddenByFiltersRow } from '../table-body-hidden-by-filter-row.js'
Expand All @@ -21,6 +21,7 @@ export const CategoryComboTableBody = React.memo(
maxColumnsInSection,
renderRowTotals,
renderColumnTotals,
collapsed,
}) {
const { data: metadata } = useMetadata()

Expand Down Expand Up @@ -59,7 +60,11 @@ export const CategoryComboTableBody = React.memo(
const hiddenItemsCount = filteredDeIds.size

return (
<TableBody>
<TableBody
className={cx({
[styles.sectionRowCollapsed]: collapsed,
})}
>
<CategoryComboTableBodyHeader
categoryOptionCombos={sortedCOCs}
categories={categories}
Expand Down Expand Up @@ -128,6 +133,7 @@ CategoryComboTableBody.propTypes = {
categoryCombo: PropTypes.shape({
id: PropTypes.string.isRequired,
}),
collapsed: PropTypes.bool,
dataElements: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
Expand Down
1 change: 0 additions & 1 deletion src/data-workspace/section-form/displayOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export const getDisplayOptions = (section) => {

try {
const { displayOptions: displayOptionString } = section

return JSON.parse(displayOptionString)
} catch (e) {
console.error(
Expand Down
5 changes: 2 additions & 3 deletions src/data-workspace/section-form/section-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const SectionForm = ({ dataSet, globalFilterText }) => {
dataSetId={dataSet.id}
key={s.id}
globalFilterText={globalFilterText}
collapsible
/>
))}
</>
Expand All @@ -51,9 +52,7 @@ export const SectionForm = ({ dataSet, globalFilterText }) => {

SectionForm.propTypes = {
dataSet: PropTypes.shape({
displayOptions: PropTypes.shape({
tabsDirection: PropTypes.oneOf(['vertical', 'horizontal']),
}),
displayOptions: PropTypes.string,
id: PropTypes.string,
renderAsTabs: PropTypes.bool,
sections: PropTypes.arrayOf(
Expand Down
109 changes: 75 additions & 34 deletions src/data-workspace/section-form/section.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import i18n from '@dhis2/d2-i18n'
import {
colors,
IconChevronDown16,
IconChevronUp16,
IconFilter16,
Table,
TableCellHead,
Expand All @@ -19,9 +21,16 @@ import { getDisplayOptions } from './displayOptions.js'
import { SectionDescription } from './section-description.js'
import styles from './section.module.css'

export function SectionFormSection({ section, dataSetId, globalFilterText }) {
export function SectionFormSection({
section,
dataSetId,
globalFilterText,
collapsible,
}) {
// Could potentially build table via props instead of rendering children
const [filterText, setFilterText] = useState('')
const [showSectionContent, setShowSectionContent] = useState(true)

const { data } = useMetadata()

const dataElements = selectors.getDataElementsBySection(
Expand Down Expand Up @@ -77,6 +86,15 @@ export function SectionFormSection({ section, dataSetId, globalFilterText }) {

const { beforeSectionText, afterSectionText } = displayOptions

const onSectionHeadClicked = () => {
collapsible &&
setShowSectionContent((displayingContent) => !displayingContent)
}

const onSectionHeadEntered = (e) => {
e.key === 'Enter' && onSectionHeadClicked()
}

return (
<div>
<SectionDescription>{beforeSectionText}</SectionDescription>
Expand All @@ -88,44 +106,61 @@ export function SectionFormSection({ section, dataSetId, globalFilterText }) {
className={styles.headerCell}
>
<div className={styles.labelWrapper}>
<div className={styles.title}>
{section.displayName}
<div
className={styles.collapseIcon}
tabIndex={collapsible ? 0 : -1}
onClick={onSectionHeadClicked}
onKeyDown={onSectionHeadEntered}
>
{collapsible &&
(showSectionContent ? (
<IconChevronUp16 color="var(--colors-white)" />
) : (
<IconChevronDown16 color="var(--colors-white)" />
))}
</div>
{section.description && (
<div className={styles.description}>
{section.description ||
'Placeholder section description'}
<div>
<div className={styles.title}>
{section.displayName}
</div>
)}
{section.description && (
<div className={styles.description}>
{section.description ||
'Placeholder section description'}
</div>
)}
</div>
</div>
</TableCellHead>
</TableRowHead>
<TableRowHead>
<TableCellHead
colSpan="100%"
className={headerCellStyles}
>
<label
htmlFor={filterInputId}
className={styles.filterWrapper}
{showSectionContent && (
<TableRowHead>
<TableCellHead
colSpan="100%"
className={headerCellStyles}
>
<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>
<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) => (
Expand All @@ -140,10 +175,11 @@ export function SectionFormSection({ section, dataSetId, globalFilterText }) {
renderColumnTotals={section.showColumnTotals}
greyedFields={greyedFields}
displayOptions={displayOptions}
collapsed={!showSectionContent}
/>
)
)}
{indicators.length > 0 && (
{indicators.length > 0 && showSectionContent && (
<IndicatorsTableBody
indicators={indicators}
renderRowTotals={section.showRowTotals}
Expand All @@ -159,6 +195,7 @@ export function SectionFormSection({ section, dataSetId, globalFilterText }) {
}

SectionFormSection.propTypes = {
collapsible: PropTypes.bool,
dataSetId: PropTypes.string,
globalFilterText: PropTypes.string,
section: PropTypes.shape({
Expand All @@ -175,3 +212,7 @@ SectionFormSection.propTypes = {
showRowTotals: PropTypes.bool,
}),
}

SectionFormSection.defaultProps = {
collapsible: false,
}
45 changes: 36 additions & 9 deletions src/data-workspace/section-form/section.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
.labelWrapper {
background-color: transparent !important;
}
.title, .description {
.title,
.description {
color: black !important;
}
}
Expand All @@ -23,7 +24,34 @@
background-color: var(--colors-grey800);
line-height: 20px;
padding: 4px 8px;
display: flex;
align-items: center;
gap: 4px;
}

.collapseIcon {
margin-inline-start: -4px;
padding: var(--spacers-dp4);
height: 24px;
width: 24px;
align-self: flex-start;
border-radius: 3px;
cursor: pointer;
}

.collapseIcon:hover {
background-color: var(--colors-grey900);
}

.collapseIcon:focus {
outline: 3px solid var(--theme-focus);
}

/* Prevent focus styles when mouse clicking */
.collapseIcon:focus:not(:focus-visible) {
outline: none;
}

.title {
color: var(--colors-grey050);
font-weight: 400;
Expand Down Expand Up @@ -65,43 +93,42 @@

.sectionTab {
margin-bottom: 8px;

}

.verticalSectionTabWrapper .sectionTab div{
.verticalSectionTabWrapper .sectionTab div {
flex-direction: column;
}

.sectionTab button{
.sectionTab button {
align-self: stretch;
}

.sectionTabWrapper{
.sectionTabWrapper {
display: flex;
gap: 6px;
flex-direction: column;
}

.verticalSectionTabWrapper{
.verticalSectionTabWrapper {
flex-direction: row;
}

@media print {
.hideForPrint {
composes: hideForPrint from '../../app/app.css'
composes: hideForPrint from '../../app/app.css';
}
}

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

.sectionDescription :global(a):link,
.sectionDescription :global(a):visited,
.sectionDescription :global(a):hover,
.sectionDescription :global(a):active {
color: var(--colors-blue700)
color: var(--colors-blue700);
}
8 changes: 6 additions & 2 deletions src/data-workspace/table-body.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
padding: 8px !important;
height: auto !important;
font-size: 13px !important;
line-height: 15px !important;
line-height: 15px !important;
}

.tableHeader {
Expand All @@ -12,6 +12,10 @@
font-weight: 500;
}

.sectionRowCollapsed{
visibility: collapse;
}

.categoryNameHeader {
composes: tableHeader;
font-weight: 300;
Expand Down Expand Up @@ -99,4 +103,4 @@
}
.category {
font-weight: 300;
}
}

1 comment on commit 1908b30

@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.