From e034fc94628ca4abc292dbf55b358df7d158ce0c Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 9 Jan 2023 15:33:47 +0100 Subject: [PATCH 01/23] feat(consistency-improvements): Implement changes for vaccinations per agegroup. --- .../components/narrow-coverage-table.tsx | 73 ++----- .../components/wide-coverage-table.tsx | 187 ++++++------------ 2 files changed, 81 insertions(+), 179 deletions(-) diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx index 11171b4be8..013b914822 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx @@ -1,94 +1,63 @@ -import { Box, Spacer } from '~/components/base'; +import { AgeGroup } from '~/domain/vaccine/components/age-group'; +import { Bar } from '~/domain/vaccine/components/bar'; import { BoldText } from '~/components/typography'; -import { useIntl } from '~/intl'; +import { Box, Spacer } from '~/components/base'; +import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; +import { fontSizes } from '~/style/theme'; import { formatAgeGroupString } from '~/utils/format-age-group-string'; import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { - COLOR_FULLY_VACCINATED, - COLOR_AUTUMN_2022_SHOT, -} from '~/domain/vaccine/common'; -import { Bar } from '~/domain/vaccine/components/bar'; import { NarrowPercentage } from '~/domain/vaccine/components/narrow-percentage'; -import { AgeGroup } from '~/domain/vaccine/components/age-group'; import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; import { SiteText } from '~/locale'; +import { useIntl } from '~/intl'; +import styled from 'styled-components'; interface NarrowCoverageTableProps { text: SiteText['pages']['vaccinations_page']['nl']['vaccination_coverage']; values: NlVaccineCoveragePerAgeGroupValue[]; } -export const NarrowCoverageTable = ({ - values, - text, -}: NarrowCoverageTableProps) => { +export const NarrowCoverageTable = ({ values, text }: NarrowCoverageTableProps) => { const { commonTexts, formatPercentage } = useIntl(); return ( - {text.headers.agegroup} + {text.headers.agegroup} {values.map((item, index) => ( - + - + - + - + ))} ); }; + +const StyledBoldText = styled(BoldText)` + font-size: ${fontSizes[2]}; +`; diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx index 6d9022cfed..7a26137fa3 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx @@ -1,20 +1,16 @@ -import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; -import css from '@styled-system/css'; -import styled from 'styled-components'; +import { AgeGroup } from '~/domain/vaccine/components/age-group'; +import { Bar } from '~/domain/vaccine/components/bar'; import { Box } from '~/components/base'; -import { InlineText } from '~/components/typography'; -import { useIntl } from '~/intl'; -import { asResponsiveArray } from '~/style/utils'; +import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; +import { fontWeights, space, fontSizes } from '~/style/theme'; import { formatAgeGroupString } from '~/utils/format-age-group-string'; import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { - COLOR_FULLY_VACCINATED, - COLOR_AUTUMN_2022_SHOT, -} from '~/domain/vaccine/common'; -import { Bar } from '~/domain/vaccine/components/bar'; -import { WidePercentage } from '~/domain/vaccine/components/wide-percentage'; -import { AgeGroup } from '~/domain/vaccine/components/age-group'; +import { InlineText } from '~/components/typography'; +import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; import { SiteText } from '~/locale'; +import { useIntl } from '~/intl'; +import { WidePercentage } from '~/domain/vaccine/components/wide-percentage'; +import styled from 'styled-components'; interface WideCoverageTableProps { text: SiteText['pages']['vaccinations_page']['nl']['vaccination_coverage']; values: NlVaccineCoveragePerAgeGroupValue[]; @@ -26,117 +22,48 @@ export const WideCoverageTable = ({ values, text }: WideCoverageTableProps) => { return ( - + - + {text.headers.agegroup} - - - {text.headers.autumn_2022_shot} - + + {text.headers.autumn_2022_shot} - - - {text.headers.fully_vaccinated} - + + {text.headers.fully_vaccinated} - - - {text.headers.difference_autumn_2022_shot_and_fully_vaccinated} - + + {text.headers.difference_autumn_2022_shot_and_fully_vaccinated} - + + {values.map((item, index) => ( - + - - + + @@ -147,33 +74,39 @@ export const WideCoverageTable = ({ values, text }: WideCoverageTableProps) => { ); }; -const StyledTable = styled.table( - css({ - borderCollapse: 'collapse', - width: '100%', - }) -); +const StyledTable = styled.table` + border-collapse: collapse; + width: 100%; +`; + +const Row = styled.tr` + border-bottom: 1px solid silver; +`; +interface HeaderCellProps { + isColumn?: boolean; + hasPaddingRight?: boolean; + width?: string; +} + +const HeaderCell = styled.th` + font-weight: ${({ isColumn }) => (isColumn ? fontWeights.normal : fontWeights.bold)}; + padding-block: ${({ isColumn }) => (isColumn ? space[3] : undefined)}; + padding-bottom: ${({ isColumn }) => (isColumn ? undefined : space[2])}; + padding-right: ${({ hasPaddingRight }) => (hasPaddingRight ? space[3] : undefined)}; + text-align: left; + vertical-align: middle; + width: ${({ width }) => (width ? width : undefined)}; -const Row = styled.tr( - css({ - borderBottom: '1px solid', - borderColor: 'silver', - }) -); + > span { + font-size: ${fontSizes[2]}; + } +`; -const HeaderCell = styled.th<{ isColumn?: boolean }>((headerCellProps) => - css({ - textAlign: 'left', - fontWeight: headerCellProps.isColumn ? 'normal' : 'bold', - verticalAlign: 'middle', - pb: headerCellProps.isColumn ? undefined : 2, - py: headerCellProps.isColumn ? 3 : undefined, - }) -); +const Cell = styled.td` + padding-block: ${space[3]}; + vertical-align: middle; +`; -const Cell = styled.td( - css({ - py: 3, - verticalAlign: 'middle', - }) -); +const TableHead = styled.thead` + border-bottom: 1px solid silver; +`; From e870068907c088d387b3f9cb0860fbde2551ce0e Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 9 Jan 2023 18:04:47 +0100 Subject: [PATCH 02/23] feat(consistency-improvements): Implement changes for variants table. --- .../components/wide-coverage-table.tsx | 5 +- .../components/narrow-variants-table.tsx | 65 +++++-------------- .../components/percentage-bar-with-number.tsx | 21 ++---- .../components/shared-table-components.tsx | 63 +++++++++--------- .../components/variant-difference.tsx | 50 +++++++++----- .../components/wide-variants-table.tsx | 40 ++++-------- 6 files changed, 101 insertions(+), 143 deletions(-) diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx index 7a26137fa3..7a75632cd4 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx @@ -11,6 +11,7 @@ import { SiteText } from '~/locale'; import { useIntl } from '~/intl'; import { WidePercentage } from '~/domain/vaccine/components/wide-percentage'; import styled from 'styled-components'; + interface WideCoverageTableProps { text: SiteText['pages']['vaccinations_page']['nl']['vaccination_coverage']; values: NlVaccineCoveragePerAgeGroupValue[]; @@ -33,9 +34,7 @@ export const WideCoverageTable = ({ values, text }: WideCoverageTableProps) => { {text.headers.fully_vaccinated} - - {text.headers.difference_autumn_2022_shot_and_fully_vaccinated} - + diff --git a/packages/app/src/domain/variants/variants-table-tile/components/narrow-variants-table.tsx b/packages/app/src/domain/variants/variants-table-tile/components/narrow-variants-table.tsx index 4b8af6956b..029af61faa 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/narrow-variants-table.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/narrow-variants-table.tsx @@ -1,4 +1,4 @@ -import { DifferenceDecimal } from '@corona-dashboard/common'; +import { colors, DifferenceDecimal } from '@corona-dashboard/common'; import css from '@styled-system/css'; import { useMemo } from 'react'; import styled from 'styled-components'; @@ -9,21 +9,14 @@ import { VariantRow } from '~/domain/variants/static-props'; import { useIntl } from '~/intl'; import { getMaximumNumberOfDecimals } from '~/utils/get-maximum-number-of-decimals'; import { useCollapsible } from '~/utils/use-collapsible'; -import { - Cell, - HeaderCell, - PercentageBarWithNumber, - StyledTable, - VariantDifference, - VariantNameCell, -} from '.'; +import { Cell, HeaderCell, PercentageBarWithNumber, StyledTable, VariantDifference, VariantNameCell } from '.'; import { TableText } from '../types'; import { NoPercentageData } from './no-percentage-data'; -type NarrowVariantsTableProps = { +interface NarrowVariantsTableProps { rows: VariantRow[]; text: TableText; -}; +} export function NarrowVariantsTable(props: NarrowVariantsTableProps) { const intl = useIntl(); @@ -31,9 +24,7 @@ export function NarrowVariantsTable(props: NarrowVariantsTableProps) { const columnNames = text.kolommen; const formatValue = useMemo(() => { - const numberOfDecimals = getMaximumNumberOfDecimals( - rows.map((x) => x.percentage ?? 0) - ); + const numberOfDecimals = getMaximumNumberOfDecimals(rows.map((x) => x.percentage ?? 0)); return (value: number) => intl.formatPercentage(value, { minimumFractionDigits: numberOfDecimals, @@ -51,23 +42,18 @@ export function NarrowVariantsTable(props: NarrowVariantsTableProps) { {rows.map((row) => ( - + ))} ); } -type MobileVariantRowProps = { +interface MobileVariantRowProps { row: VariantRow; text: TableText; formatValue: (value: number) => string; -}; +} function MobileVariantRow(props: MobileVariantRowProps) { const { row, text, formatValue } = props; @@ -78,22 +64,9 @@ function MobileVariantRow(props: MobileVariantRowProps) { return ( <> - + - {isPresent(row.percentage) ? ( - - ) : ( - - )} + {isPresent(row.percentage) ? : } {collapsible.button()} @@ -105,13 +78,8 @@ function MobileVariantRow(props: MobileVariantRowProps) { {columnNames.vorige_meting}: - {isPresent(row.difference) && - isPresent(row.difference.difference) && - isPresent(row.difference.old_value) ? ( - + {isPresent(row.difference) && isPresent(row.difference.difference) && isPresent(row.difference.old_value) ? ( + ) : ( '-' )} @@ -124,9 +92,6 @@ function MobileVariantRow(props: MobileVariantRowProps) { ); } -const MobileCell = styled.td( - css({ - borderBottom: '1px solid', - borderBottomColor: 'gray2', - }) -); +const MobileCell = styled.td` + border-bottom: 1px solid ${colors.gray2}; +`; diff --git a/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx b/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx index dcd83d8dd3..6167dd8f31 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx @@ -1,25 +1,18 @@ import { Box } from '~/components/base'; import { PercentageBar } from '~/components/percentage-bar'; -import { BoldText } from '~/components/typography'; +import { InlineText } from '~/components/typography'; -export function PercentageBarWithNumber({ - percentage, - color, - formatValue, -}: { +interface PercentageBarWithNumberProps { percentage: number; color: string; formatValue: (value: number) => string; -}) { +} + +export function PercentageBarWithNumber({ percentage, color, formatValue }: PercentageBarWithNumberProps) { return ( - + - {formatValue(percentage)}% + {formatValue(percentage)}% diff --git a/packages/app/src/domain/variants/variants-table-tile/components/shared-table-components.tsx b/packages/app/src/domain/variants/variants-table-tile/components/shared-table-components.tsx index 4726660762..dc7f4af1d6 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/shared-table-components.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/shared-table-components.tsx @@ -1,36 +1,39 @@ -import css from '@styled-system/css'; +import { colors } from '@corona-dashboard/common'; +import { fontWeights, space } from '~/style/theme'; import styled from 'styled-components'; -export const StyledTable = styled.table( - css({ - borderCollapse: 'collapse', - width: '100%', - }) -); +export const StyledTable = styled.table` + border-collapse: collapse; + width: 100%; +`; -export const HeaderCell = styled.th( - css({ - textAlign: 'left', - fontWeight: 'normal', - borderBottom: '1px solid', - borderBottomColor: 'gray2', - verticalAlign: 'top', - }) -); +interface HeaderCellProps { + isFirst?: boolean; + isLast?: boolean; +} -export const Cell = styled.td<{ +export const HeaderCell = styled.th` + border-bottom: 1px solid ${colors.gray2}; + font-size: ${space[3]}; + font-weight: ${fontWeights.bold}; + padding-bottom: ${space[2]}; + text-align: left; + vertical-align: top; + width: ${({ isFirst, isLast }) => (isFirst ? '30%' : isLast ? '25%' : undefined)}; +`; + +interface CellProps { + alignRight?: boolean; + border?: boolean; + hasPaddingRight?: boolean; mobile?: boolean; narrow?: boolean; - border?: boolean; - alignRight?: boolean; -}>((x) => - css({ - p: 0, - py: 3, - float: x.alignRight ? 'right' : undefined, - maxWidth: x.narrow ? '2rem' : undefined, - borderBottom: x.border || !x.mobile ? '1px solid' : undefined, - borderBottomColor: x.border || !x.mobile ? 'gray2' : undefined, - verticalAlign: 'top', - }) -); +} + +export const Cell = styled.td` + border-bottom: ${({ border, mobile }) => (border || !mobile ? `1px solid ${colors.gray2}` : undefined)}; + float: ${({ alignRight }) => (alignRight ? 'right' : undefined)}; + max-width: ${({ narrow }) => (narrow ? space[4] : undefined)}; + padding: ${({ hasPaddingRight }) => (hasPaddingRight ? `${space[3]} ${space[3]} ${space[3]} ${space[0]}` : `${space[3]} ${space[0]}`)}; + vertical-align: top; +`; diff --git a/packages/app/src/domain/variants/variants-table-tile/components/variant-difference.tsx b/packages/app/src/domain/variants/variants-table-tile/components/variant-difference.tsx index bb507e5c3a..ee37be1010 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/variant-difference.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/variant-difference.tsx @@ -1,11 +1,17 @@ import { colors, DifferenceDecimal } from '@corona-dashboard/common'; -import css from '@styled-system/css'; -import styled from 'styled-components'; -import { useIntl } from '~/intl'; +import { space } from '~/style/theme'; import { TableText } from '../types'; import { TrendDirection, TrendIcon } from '~/components/trend-icon'; +import { useIntl } from '~/intl'; +import styled from 'styled-components'; + +interface VariantDifferenceProps { + isWideTable?: boolean; + text: TableText; + value: DifferenceDecimal; +} -export function VariantDifference({ value, text }: { value: DifferenceDecimal; text: TableText }) { +export function VariantDifference({ value, text, isWideTable }: VariantDifferenceProps) { const { formatPercentage } = useIntl(); const options = { @@ -14,9 +20,8 @@ export function VariantDifference({ value, text }: { value: DifferenceDecimal; t }; let returnValue: React.ReactNode = ( - - - {text.verschil.gelijk} + + {text.verschil.gelijk} ); @@ -55,14 +60,23 @@ export function VariantDifference({ value, text }: { value: DifferenceDecimal; t return <>{returnValue}; } -const Difference = styled.div<{ color: string }>((x) => - css({ - svg: { - color: x.color, - mr: 1, - width: '12px', - height: '12px', - verticalAlign: 'middle', - }, - }) -); +interface DifferenceProps { + color: string; + hasDifference?: boolean; + isWideTable?: boolean; +} + +const Difference = styled.div` + span { + /* The value of space[3] is a combination of the icon width plus the icon's margin-right */ + padding-left: ${({ hasDifference, isWideTable }) => (!hasDifference && isWideTable ? space[3] : undefined)}; + } + + svg { + color: ${({ color }) => color}; + margin-right: ${space[1]}; + width: 12px; + height: 12px; + vertical-align: middle; + } +`; diff --git a/packages/app/src/domain/variants/variants-table-tile/components/wide-variants-table.tsx b/packages/app/src/domain/variants/variants-table-tile/components/wide-variants-table.tsx index 9b5ac41787..921d15de38 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/wide-variants-table.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/wide-variants-table.tsx @@ -5,32 +5,23 @@ import { Box } from '~/components/base'; import { VariantRow } from '~/domain/variants/static-props'; import { useIntl } from '~/intl'; import { getMaximumNumberOfDecimals } from '~/utils/get-maximum-number-of-decimals'; -import { - Cell, - HeaderCell, - PercentageBarWithNumber, - StyledTable, - VariantDifference, - VariantNameCell, -} from '.'; +import { Cell, HeaderCell, PercentageBarWithNumber, StyledTable, VariantDifference, VariantNameCell } from '.'; import { TableText } from '../types'; import { NoPercentageData } from './no-percentage-data'; const columnKeys = ['variant_titel', 'percentage', 'vorige_meting'] as const; -type WideVariantsTableProps = { +interface WideVariantsTableProps { rows: VariantRow[]; text: TableText; -}; +} export function WideVariantsTable(props: WideVariantsTableProps) { const { rows, text } = props; const intl = useIntl(); const formatValue = useMemo(() => { - const numberOfDecimals = getMaximumNumberOfDecimals( - rows.map((x) => x.percentage ?? 0) - ); + const numberOfDecimals = getMaximumNumberOfDecimals(rows.map((x) => x.percentage ?? 0)); return (value: number) => intl.formatPercentage(value, { minimumFractionDigits: numberOfDecimals, @@ -42,8 +33,10 @@ export function WideVariantsTable(props: WideVariantsTableProps) { - {columnKeys.map((key) => ( - {text.kolommen[key]} + {columnKeys.map((key, index) => ( + + {text.kolommen[key]} + ))} @@ -51,27 +44,18 @@ export function WideVariantsTable(props: WideVariantsTableProps) { {rows.map((row) => ( - + {isPresent(row.percentage) ? ( - + ) : ( )} - {isPresent(row.difference) && - isPresent(row.difference.difference) && - isPresent(row.difference.old_value) ? ( - + {isPresent(row.difference) && isPresent(row.difference.difference) && isPresent(row.difference.old_value) ? ( + ) : ( '-' )} From deb11e615f1e242e6cdb51b759f8367195aede99 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Wed, 11 Jan 2023 14:33:20 +0100 Subject: [PATCH 03/23] feat: WIP and behavior table improvements --- .../src/components/tables/desktop-table.tsx | 0 .../src/components/tables/mobile-table.tsx | 185 ++++++++ .../domain/behavior/behavior-table-tile.tsx | 396 ++++++++---------- .../behavior/components/behavior-trend.tsx | 54 ++- .../vaccine/components/wide-percentage.tsx | 16 +- .../components/shared-table-components.tsx | 2 +- packages/app/src/style/theme.ts | 4 +- 7 files changed, 396 insertions(+), 261 deletions(-) create mode 100644 packages/app/src/components/tables/desktop-table.tsx create mode 100644 packages/app/src/components/tables/mobile-table.tsx diff --git a/packages/app/src/components/tables/desktop-table.tsx b/packages/app/src/components/tables/desktop-table.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/app/src/components/tables/mobile-table.tsx b/packages/app/src/components/tables/mobile-table.tsx new file mode 100644 index 0000000000..5f41371392 --- /dev/null +++ b/packages/app/src/components/tables/mobile-table.tsx @@ -0,0 +1,185 @@ +// import { AgeGroup } from '~/domain/vaccine/components/age-group'; +// import { Bar } from '~/domain/vaccine/components/bar'; +// import { BoldText, InlineText } from '~/components/typography'; +// import { Box, Spacer } from '~/components/base'; +// import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; +// import { fontSizes, space } from '~/style/theme'; +// import { formatAgeGroupString } from '~/utils/format-age-group-string'; +// import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; +// import { NarrowPercentage } from '~/domain/vaccine/components/narrow-percentage'; +// import { NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; +// import { SiteText } from '~/locale'; +// import { useIntl } from '~/intl'; +// import styled from 'styled-components'; +// import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; + +// interface MobileTableProps { +// text: SiteText['pages']['vaccinations_page']['nl']['vaccination_coverage'] | string; +// values: NlBehaviorValue | VrBehaviorArchived_20221019Value; +// hasAgeGroups?: boolean; +// isBehaviourTable?: boolean; +// } + +// export const MobileTable = ({ values, text, hasAgeGroups, isBehaviourTable }: MobileTableProps) => { +// const { commonTexts, formatPercentage } = useIntl(); + +// return ( +// +// +// +// +// +// {text.header} +// +// +// + +// +// {values.map((item, _index) => ( +// <> +// {/* Mobile/narrow screens */} +// +// +// +// { isBehaviourTable && +// <> +// +// +// + +// anchorButtonClickHandler(item.id, scrollRef)}> +// +// {item.description} +// +// +// +// } + +// { hasAgeGroups && +// +// } +// + +// +// +// +// Coronaregel volgen: +// } +// color={colors.yellow3} +// justifyContent="flex-start" +// /> +// +// +// + +// +// +// Coronaregel steunen: +// } +// color={colors.blue6} +// justifyContent="flex-start" +// /> +// +// +// +// +// +// + +// {/* Old */} +// {/* +// +// +// +// +// +// +// +// +// +// +// */} +// +// ))} +// +// +// +// ); +// }; + +// const StyledBoldText = styled(BoldText)` +// font-size: ${fontSizes[2]}; +// `; + +// interface PercentageBarWithoutNumberProps { +// percentage: number; +// color: string; +// marginBottom?: string; +// } + +// function PercentageBarWithoutNumber({ percentage, color, marginBottom }: PercentageBarWithoutNumberProps) { +// return ( +// +// +// +// +// +// ); +// } + +// const StyledTable = styled.table` +// border-collapse: collapse; +// width: 100%; +// `; + +// type RowProps = DisplayProps; + +// const Row = styled.tr` +// flex-wrap: wrap; +// justify-content: space-between; +// ${compose(display)}; +// `; + +// type HeaderCellProps = WidthProps & DisplayProps; + +// const HeaderCell = styled.th` +// border-bottom: 1px solid ${colors.gray2}; +// text-align: left; +// font-weight: ${fontWeights.bold}; +// vertical-align: middle; +// padding-bottom: ${space[2]}; +// ${compose(width)}; +// ${compose(display)}; +// ` + +// type CellProps = MinWidthProps & BorderProps; + +// const Cell = styled.td` +// border-bottom: 1px solid ${colors.gray2}; +// padding: ${space[3]} ${space[0]}; +// vertical-align: middle; +// ${compose(minWidth)}; +// ${compose(border)}; +// ` + +// const StyledAnchor = styled(Anchor)` +// &:hover { +// color: ${colors.blue8}; +// } +// ` diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index 18a589b285..c930e3db7a 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -1,21 +1,20 @@ -import { colors, NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; -import { ChevronRight } from '@corona-dashboard/icons'; -import css from '@styled-system/css'; -import React, { useMemo } from 'react'; -import scrollIntoView from 'scroll-into-view-if-needed'; -import styled from 'styled-components'; -import { isDefined, isPresent } from 'ts-is-present'; +import { Anchor, InlineText, Text } from '~/components/typography'; +import { BehaviorIcon } from './components/behavior-icon'; +import { BehaviorIdentifier } from './logic/behavior-types'; +import { BehaviorTrend } from './components/behavior-trend'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; +import { colors, NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; +import { compose, display, DisplayProps, width, WidthProps, minWidth, MinWidthProps, border, BorderProps } from 'styled-system'; +import { fontWeights, space } from '~/style/theme'; +import { isDefined, isPresent } from 'ts-is-present'; import { PercentageBar } from '~/components/percentage-bar'; -import { Anchor, InlineText, Text, BoldText } from '~/components/typography'; -import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; -import { asResponsiveArray } from '~/style/utils'; -import { BehaviorIcon } from './components/behavior-icon'; -import { BehaviorTrend } from './components/behavior-trend'; -import { BehaviorIdentifier } from './logic/behavior-types'; import { useBehaviorLookupKeys } from './logic/use-behavior-lookup-keys'; +import { WidePercentage } from '../vaccine/components/wide-percentage'; +import React, { useMemo } from 'react'; +import scrollIntoView from 'scroll-into-view-if-needed'; +import styled from 'styled-components'; interface BehaviorTableTileProps { title: string; @@ -31,108 +30,146 @@ interface BehaviorTableTileProps { const trendColumnWidth = 125; -export function BehaviorTableTile({ title, description, complianceExplanation, supportExplanation, value, annotation, setCurrentId, scrollRef, text }: BehaviorTableTileProps) { +export function BehaviorTableTile({ title, description, value, annotation, setCurrentId, scrollRef, text }: BehaviorTableTileProps) { const behaviorsTableData = useBehaviorTableData(value as NlBehaviorValue); + const anchorButtonClickHandler = (id: BehaviorIdentifier, scrollRef: { current: HTMLDivElement | null }) => { + scrollIntoView(scrollRef.current as Element); + setCurrentId(id); + }; + return ( - - - - {complianceExplanation} - - - - {supportExplanation} - - - - {text.basisregels.header_basisregel} + {text.basisregels.header_basisregel} + + Coronaregel volgen - - {text.basisregels.header_percentage} - - - {text.basisregels.header_trend} + + Coronaregel steunen + + {/* Empty header cell to respect design */} + {behaviorsTableData.map((behavior) => ( - - - - - + // Mobile/narrow screens + <> + {/* Mobile/narrow screens */} + + + + + + + + anchorButtonClickHandler(behavior.id, scrollRef)}> + + {behavior.description} + + + + + + + + Coronaregel volgen: + } + color={colors.yellow3} + justifyContent="flex-start" + /> + + + + + + + Coronaregel steunen: + } + color={colors.blue6} + justifyContent="flex-start" + /> + + + - - - - - - - - - - - - - - + + + {/* + } + color={colors.blue6} + justifyContent="flex-start" /> + + + + } + color={colors.yellow3} + justifyContent="flex-start" /> + + + + + + + + */} + + + {/* Desktop/wide screens */} + + + + + + + + anchorButtonClickHandler(behavior.id, scrollRef)}> + + {behavior.description} + + + + + + + } + color={colors.blue6} + justifyContent="flex-start" + /> + + + + } + color={colors.yellow3} + justifyContent="flex-start" + /> + + + + + + + + + + ))} - + + {annotation} @@ -141,71 +178,15 @@ export function BehaviorTableTile({ title, description, complianceExplanation, s ); } -/** - * Render every word in a span and add the chevron to the last word. - * this is for the word wrapping when the screen gets smaller. - */ -function DescriptionWithIcon({ - description, - id, - setCurrentId, - scrollRef, -}: { - description: string; - id: BehaviorIdentifier; - setCurrentId: React.Dispatch>; - scrollRef: { current: HTMLDivElement | null }; -}) { - const splittedWords = description.split(' '); - - const buttonClickHandler = () => { - scrollIntoView(scrollRef.current as Element); - setCurrentId(id); - }; - - return ( - - - {splittedWords.map((word, index) => ( - - {splittedWords.length - 1 === index ? ( - - {word} - - - - - ) : ( - `${word} ` - )} - - ))} - - - ); +interface PercentageBarWithoutNumberProps { + percentage: number; + color: string; + marginBottom?: string; } -function PercentageBarWithNumber({ percentage, color }: { percentage: number; color: string }) { - const { formatPercentage } = useIntl(); +function PercentageBarWithoutNumber({ percentage, color, marginBottom }: PercentageBarWithoutNumberProps) { return ( - - - {`${formatPercentage(percentage)}%`} - + @@ -213,64 +194,6 @@ function PercentageBarWithNumber({ percentage, color }: { percentage: number; co ); } -const ExplanationBox = styled.div<{ background: string }>((x) => - css({ - height: '17px', - width: '17px', - background: x.background, - float: 'left', - mt: '3px', - mr: 1, - borderRadius: '3px', - }) -); - -const StyledTable = styled.table( - css({ - borderCollapse: 'collapse', - width: '100%', - }) -); - -const Row = styled.tr( - css({ - display: asResponsiveArray({ - _: 'flex', - sm: 'table-row', - md: 'flex', - lg: 'table-row', - }), - flexWrap: 'wrap', - justifyContent: 'space-between', - }) -); - -const HeaderCell = styled.th( - css({ - textAlign: 'left', - fontWeight: 'bold', - verticalAlign: 'middle', - }) -); - -const Cell = styled.td( - css({ - borderBottom: `1px solid ${colors.gray2}`, - p: 0, - py: 2, - verticalAlign: 'middle', - - '&:first-child': { - borderBottom: asResponsiveArray({ - _: 'none', - sm: `1px solid ${colors.gray2}`, - md: 'none', - lg: `1px solid ${colors.gray2}`, - }), - }, - }) -); - function useBehaviorTableData(value: NlBehaviorValue) { const behaviorLookupKeys = useBehaviorLookupKeys(); @@ -298,3 +221,44 @@ function useBehaviorTableData(value: NlBehaviorValue) { .sort((a, b) => (b.compliancePercentage ?? 0) - (a.compliancePercentage ?? 0)); }, [value, behaviorLookupKeys]); } + +const StyledTable = styled.table` + border-collapse: collapse; + width: 100%; +`; + +type RowProps = DisplayProps; + +const Row = styled.tr` + flex-wrap: wrap; + justify-content: space-between; + ${compose(display)}; +`; + +type HeaderCellProps = WidthProps & DisplayProps; + +const HeaderCell = styled.th` + border-bottom: 1px solid ${colors.gray2}; + text-align: left; + font-weight: ${fontWeights.bold}; + vertical-align: middle; + padding-bottom: ${space[2]}; + ${compose(width)}; + ${compose(display)}; +`; + +type CellProps = MinWidthProps & BorderProps; + +const Cell = styled.td` + border-bottom: 1px solid ${colors.gray2}; + padding: ${space[3]} ${space[0]}; + vertical-align: middle; + ${compose(minWidth)}; + ${compose(border)}; +`; + +const StyledAnchor = styled(Anchor)` + &:hover { + color: ${colors.blue8}; + } +`; diff --git a/packages/app/src/domain/behavior/components/behavior-trend.tsx b/packages/app/src/domain/behavior/components/behavior-trend.tsx index 3f1e2e31e1..3d91b53dd0 100644 --- a/packages/app/src/domain/behavior/components/behavior-trend.tsx +++ b/packages/app/src/domain/behavior/components/behavior-trend.tsx @@ -1,10 +1,9 @@ import { colors } from '@corona-dashboard/common'; -import css from '@styled-system/css'; import styled from 'styled-components'; import { Box } from '~/components/base'; -import { SiteText } from '~/locale'; import { BehaviorTrendType } from '../logic/behavior-types'; import { TrendDirection, TrendIcon } from '~/components/trend-icon'; +import { space } from '~/style/theme'; type TrendIcon = { direction: 'UP' | 'DOWN' | ' NEUTRAL'; @@ -13,48 +12,45 @@ type TrendIcon = { interface BehaviorTrendProps { trend: BehaviorTrendType | null; color?: string; - text: SiteText['pages']['behavior_page']['shared']; + text: string; } -const Trend = styled.span((a) => - css({ - whiteSpace: 'nowrap', - display: 'inline-block', - - svg: { - color: a.color ?? colors.blue6, - mr: 1, - width: '12px', - height: '12px', - verticalAlign: 'middle', - }, - }) -); - -export function BehaviorTrend({ trend, color, text }: BehaviorTrendProps) { +export function BehaviorTrend({ trend, text }: BehaviorTrendProps) { if (trend === 'up') { return ( - + + {text} - {text.basisregels.trend_hoger} ); } if (trend === 'down') { return ( - + + {text} - {text.basisregels.trend_lager} ); } if (trend === 'equal') { - return ( - - - {text.basisregels.trend_gelijk} - - ); + return {text}; } return ; } + +interface TrendProps { + color: string; +} + +const Trend = styled.span` + white-space: nowrap; + display: flex; + align-items: center; + color: ${({ color }) => color}; + + svg { + margin-left: ${space[1]}; + height: 12px; + width: 12px; + } +`; diff --git a/packages/app/src/domain/vaccine/components/wide-percentage.tsx b/packages/app/src/domain/vaccine/components/wide-percentage.tsx index 8d14f5f4a2..8466ec480a 100644 --- a/packages/app/src/domain/vaccine/components/wide-percentage.tsx +++ b/packages/app/src/domain/vaccine/components/wide-percentage.tsx @@ -4,16 +4,12 @@ import { InlineText } from '~/components/typography'; import { asResponsiveArray } from '~/style/utils'; interface PercentageWideNumberProps { - value: string; + value: string | React.ReactNode; color: string; justifyContent: string; } -export function WidePercentage({ - value, - color, - justifyContent, -}: PercentageWideNumberProps) { +export function WidePercentage({ value, color, justifyContent }: PercentageWideNumberProps) { return ( - + {value} ); diff --git a/packages/app/src/domain/vaccine/vaccine-campaigns-tile/components/shared-table-components.tsx b/packages/app/src/domain/vaccine/vaccine-campaigns-tile/components/shared-table-components.tsx index 360e1240d6..273e0c57bc 100644 --- a/packages/app/src/domain/vaccine/vaccine-campaigns-tile/components/shared-table-components.tsx +++ b/packages/app/src/domain/vaccine/vaccine-campaigns-tile/components/shared-table-components.tsx @@ -14,7 +14,7 @@ interface StyledHeaderCellProps { export const StyledHeaderCell = styled.th` font-size: ${fontSizes[1]}; - fontweight: ${fontWeights.bold}; + font-weight: ${fontWeights.bold}; padding: ${({ isMobile }) => (isMobile ? space[3] : space[2])} ${space[3]}; text-align: left; vertical-align: top; diff --git a/packages/app/src/style/theme.ts b/packages/app/src/style/theme.ts index 4b4a4c6714..36764083f5 100644 --- a/packages/app/src/style/theme.ts +++ b/packages/app/src/style/theme.ts @@ -72,14 +72,14 @@ interface Breakpoints extends Array { } // @ts-expect-error ignore error, missing props are assigned after this line -const breakpoints: Breakpoints = ['26em', '48em', '60em', '75em', '100em']; +export const breakpoints: Breakpoints = ['26em', '48em', '60em', '75em', '100em']; breakpoints.xs = breakpoints[0]; // ~420px breakpoints.sm = breakpoints[1]; // ~768px breakpoints.md = breakpoints[2]; // ~960px breakpoints.lg = breakpoints[3]; // ~1200px breakpoints.xl = breakpoints[4]; // ~1600px -const mediaQueries = { +export const mediaQueries = { xs: `screen and (min-width: ${breakpoints[0]})`, sm: `screen and (min-width: ${breakpoints[1]})`, md: `screen and (min-width: ${breakpoints[2]})`, From 01b6e42836e48f23b29514e9ac47ee1cc6a2cf8f Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Wed, 11 Jan 2023 17:33:23 +0100 Subject: [PATCH 04/23] feat(table adjustments): Created generic component for mobile tables. WIP. Co-authored-by: VWSCoronaDashboard26 --- .../percentage-bar-without-number.tsx | 18 + .../tables/components/percentage-data.tsx | 43 +++ .../src/components/tables/mobile-table.tsx | 314 +++++++----------- .../domain/behavior/behavior-table-tile.tsx | 116 +++---- .../vaccine/components/narrow-percentage.tsx | 41 +-- 5 files changed, 248 insertions(+), 284 deletions(-) create mode 100644 packages/app/src/components/tables/components/percentage-bar-without-number.tsx create mode 100644 packages/app/src/components/tables/components/percentage-data.tsx diff --git a/packages/app/src/components/tables/components/percentage-bar-without-number.tsx b/packages/app/src/components/tables/components/percentage-bar-without-number.tsx new file mode 100644 index 0000000000..4dda13f788 --- /dev/null +++ b/packages/app/src/components/tables/components/percentage-bar-without-number.tsx @@ -0,0 +1,18 @@ +import { Box } from '~/components/base'; +import { PercentageBar } from '~/components/percentage-bar'; + +interface PercentageBarWithoutNumberProps { + color: string; + percentage: number; + marginBottom?: string; +} + +export const PercentageBarWithoutNumber = ({ color, percentage, marginBottom }: PercentageBarWithoutNumberProps) => { + return ( + + + + + + ); +} \ No newline at end of file diff --git a/packages/app/src/components/tables/components/percentage-data.tsx b/packages/app/src/components/tables/components/percentage-data.tsx new file mode 100644 index 0000000000..683783288f --- /dev/null +++ b/packages/app/src/components/tables/components/percentage-data.tsx @@ -0,0 +1,43 @@ +import { BehaviorTrend } from "~/domain/behavior/components/behavior-trend" +import { Box } from "~/components/base" +import { colors } from "@corona-dashboard/common" +import { NarrowPercentage } from "~/domain/vaccine/components/narrow-percentage" +import { PercentageBarWithoutNumber } from "./percentage-bar-without-number" +import { space } from "~/style/theme" + +export type PercentageDataPoint = { + title: string; + trendDirection?: 'up' | 'down' | 'equal' | null; + percentage: { + color: string; + value: number; + }; +}; + +interface PercentageDataProps { + percentageDataPoints: PercentageDataPoint[]; +} + +export const PercentageData = ({percentageDataPoints}: PercentageDataProps) => { + return ( + <> + {percentageDataPoints.map((percentageDataPoint, index) => ( + + + + ) : percentageDataPoint.percentage.value + } + color={percentageDataPoint.percentage.color} + textLabel={percentageDataPoint.title} + /> + + + + + ))} + + ) +} \ No newline at end of file diff --git a/packages/app/src/components/tables/mobile-table.tsx b/packages/app/src/components/tables/mobile-table.tsx index 5f41371392..197efc5955 100644 --- a/packages/app/src/components/tables/mobile-table.tsx +++ b/packages/app/src/components/tables/mobile-table.tsx @@ -1,185 +1,129 @@ -// import { AgeGroup } from '~/domain/vaccine/components/age-group'; -// import { Bar } from '~/domain/vaccine/components/bar'; -// import { BoldText, InlineText } from '~/components/typography'; -// import { Box, Spacer } from '~/components/base'; -// import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; -// import { fontSizes, space } from '~/style/theme'; -// import { formatAgeGroupString } from '~/utils/format-age-group-string'; -// import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -// import { NarrowPercentage } from '~/domain/vaccine/components/narrow-percentage'; -// import { NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; -// import { SiteText } from '~/locale'; -// import { useIntl } from '~/intl'; -// import styled from 'styled-components'; -// import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; - -// interface MobileTableProps { -// text: SiteText['pages']['vaccinations_page']['nl']['vaccination_coverage'] | string; -// values: NlBehaviorValue | VrBehaviorArchived_20221019Value; -// hasAgeGroups?: boolean; -// isBehaviourTable?: boolean; -// } - -// export const MobileTable = ({ values, text, hasAgeGroups, isBehaviourTable }: MobileTableProps) => { -// const { commonTexts, formatPercentage } = useIntl(); - -// return ( -// -// -// -// -// -// {text.header} -// -// -// - -// -// {values.map((item, _index) => ( -// <> -// {/* Mobile/narrow screens */} -// -// -// -// { isBehaviourTable && -// <> -// -// -// - -// anchorButtonClickHandler(item.id, scrollRef)}> -// -// {item.description} -// -// -// -// } - -// { hasAgeGroups && -// -// } -// - -// -// -// -// Coronaregel volgen: -// } -// color={colors.yellow3} -// justifyContent="flex-start" -// /> -// -// -// - -// -// -// Coronaregel steunen: -// } -// color={colors.blue6} -// justifyContent="flex-start" -// /> -// -// -// -// -// -// - -// {/* Old */} -// {/* -// -// -// -// -// -// -// -// -// -// -// */} -// -// ))} -// -// -// -// ); -// }; - -// const StyledBoldText = styled(BoldText)` -// font-size: ${fontSizes[2]}; -// `; - -// interface PercentageBarWithoutNumberProps { -// percentage: number; -// color: string; -// marginBottom?: string; -// } - -// function PercentageBarWithoutNumber({ percentage, color, marginBottom }: PercentageBarWithoutNumberProps) { -// return ( -// -// -// -// -// -// ); -// } - -// const StyledTable = styled.table` -// border-collapse: collapse; -// width: 100%; -// `; - -// type RowProps = DisplayProps; - -// const Row = styled.tr` -// flex-wrap: wrap; -// justify-content: space-between; -// ${compose(display)}; -// `; - -// type HeaderCellProps = WidthProps & DisplayProps; - -// const HeaderCell = styled.th` -// border-bottom: 1px solid ${colors.gray2}; -// text-align: left; -// font-weight: ${fontWeights.bold}; -// vertical-align: middle; -// padding-bottom: ${space[2]}; -// ${compose(width)}; -// ${compose(display)}; -// ` - -// type CellProps = MinWidthProps & BorderProps; - -// const Cell = styled.td` -// border-bottom: 1px solid ${colors.gray2}; -// padding: ${space[3]} ${space[0]}; -// vertical-align: middle; -// ${compose(minWidth)}; -// ${compose(border)}; -// ` - -// const StyledAnchor = styled(Anchor)` -// &:hover { -// color: ${colors.blue8}; -// } -// ` +import { AgeGroup } from '~/domain/vaccine/components/age-group'; +import { Anchor, InlineText } from '~/components/typography'; +import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; +import { BehaviorIdentifier } from '~/domain/behavior/logic/behavior-types'; +import { border, BorderProps, compose, display, DisplayProps, minWidth, MinWidthProps, width, WidthProps } from 'styled-system'; +import { Box } from '~/components/base'; +import { colors, NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; +import { fontWeights, space } from '~/style/theme'; +import { formatAgeGroupString } from '~/utils/format-age-group-string'; +import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; +import { PercentageData, PercentageDataPoint } from './components/percentage-data'; +import { SiteText } from '~/locale'; +import { useIntl } from '~/intl'; +import styled from 'styled-components'; + +type PercentageData = PercentageDataPoint[][]; + +type ScrollRef = { current: HTMLDivElement | null }; + +interface MobileTableProps { + headerText: string; + // tableData: NlBehaviorValue | VrBehaviorArchived_20221019Value; + tableData: any[]; + percentageData: PercentageData; + hasAgeGroups?: boolean; + isBehaviourTable?: boolean; + onClickConfig?: { + handler: (id: BehaviorIdentifier, scrollRef: ScrollRef) => void, + scrollRef: ScrollRef; + }; +} + +export const MobileTable = ({ tableData, headerText, hasAgeGroups, isBehaviourTable, percentageData, onClickConfig }: MobileTableProps) => { + const { commonTexts } = useIntl(); + + return ( + + + + + + {headerText} + + + + + + {tableData.map((item, tableDataIndex) => ( + + + + {isBehaviourTable && ( + <> + + + + + onClickConfig.handler(item.id, onClickConfig.scrollRef) : undefined}> + + {item.description} + + + + )} + + {hasAgeGroups && ( + + )} + + + + {percentageData.map((percentageDataPoints, percentageDataIndex) => ( + percentageDataIndex === tableDataIndex && + ))} + + + + ))} + +
+
+ ); +}; + +const Table = styled.table` + border-collapse: collapse; + width: 100%; +`; + +type RowProps = DisplayProps; + +const Row = styled.tr` + flex-wrap: wrap; + justify-content: space-between; + ${compose(display)}; +`; + +type HeaderCellProps = WidthProps & DisplayProps; + +const HeaderCell = styled.th` + border-bottom: 1px solid ${colors.gray2}; + font-weight: ${fontWeights.bold}; + padding-bottom: ${space[2]}; + text-align: left; + vertical-align: middle; + ${compose(width)}; + ${compose(display)}; +`; + +type CellProps = MinWidthProps & BorderProps; + +const Cell = styled.td` + border-bottom: 1px solid ${colors.gray2}; + padding: ${space[3]} ${space[0]}; + vertical-align: middle; + ${compose(minWidth)}; + ${compose(border)}; +`; + +const BehaviorAnchor = styled(Anchor)` + &:hover { + color: ${colors.blue8}; + } +`; diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index c930e3db7a..edac271e6f 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -15,6 +15,8 @@ import { WidePercentage } from '../vaccine/components/wide-percentage'; import React, { useMemo } from 'react'; import scrollIntoView from 'scroll-into-view-if-needed'; import styled from 'styled-components'; +import { MobileTable } from '~/components/tables/mobile-table'; +import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; interface BehaviorTableTileProps { title: string; @@ -32,6 +34,26 @@ const trendColumnWidth = 125; export function BehaviorTableTile({ title, description, value, annotation, setCurrentId, scrollRef, text }: BehaviorTableTileProps) { const behaviorsTableData = useBehaviorTableData(value as NlBehaviorValue); + const percentageData: PercentageDataPoint[][] = behaviorsTableData.map(behavior => { + return [ + { + title: 'Coronaregel volgen', + trendDirection: behavior.complianceTrend, + percentage: { + color: colors.blue6, + value: behavior.compliancePercentage + } + }, + { + title: 'Coronaregel steunen', + trendDirection: behavior.supportTrend, + percentage: { + color: colors.yellow3, + value: behavior.supportPercentage + } + } + ] + }); const anchorButtonClickHandler = (id: BehaviorIdentifier, scrollRef: { current: HTMLDivElement | null }) => { scrollIntoView(scrollRef.current as Element); @@ -40,7 +62,18 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu return ( - + + + {/* @@ -51,81 +84,14 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu Coronaregel steunen - - {/* Empty header cell to respect design */} {behaviorsTableData.map((behavior) => ( - // Mobile/narrow screens <> - {/* Mobile/narrow screens */} - - - - - - - - anchorButtonClickHandler(behavior.id, scrollRef)}> - - {behavior.description} - - - - - - - - Coronaregel volgen: - } - color={colors.yellow3} - justifyContent="flex-start" - /> - - - - - - - Coronaregel steunen: - } - color={colors.blue6} - justifyContent="flex-start" - /> - - - - - - - {/* - } - color={colors.blue6} - justifyContent="flex-start" /> - - - - } - color={colors.yellow3} - justifyContent="flex-start" /> - - - - - - - - */} - - - {/* Desktop/wide screens */} - + Desktop/wide screens + {/* @@ -163,11 +129,11 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu - - ))} - - - + + ))} + + + } */} diff --git a/packages/app/src/domain/vaccine/components/narrow-percentage.tsx b/packages/app/src/domain/vaccine/components/narrow-percentage.tsx index 813b4e9561..7bea7a345f 100644 --- a/packages/app/src/domain/vaccine/components/narrow-percentage.tsx +++ b/packages/app/src/domain/vaccine/components/narrow-percentage.tsx @@ -1,38 +1,31 @@ -import css from '@styled-system/css'; import { Box } from '~/components/base'; import { InlineText } from '~/components/typography'; -import { asResponsiveArray } from '~/style/utils'; +import { space } from '~/style/theme'; + interface NarrowPercentageProps { - value: string; + value: number | React.ReactNode; color: string; textLabel: string; } -export function NarrowPercentage({ - value, - color, - textLabel, -}: NarrowPercentageProps) { +export function NarrowPercentage({ value, color, textLabel }: NarrowPercentageProps) { return ( - - + + {`${textLabel}:`} - - {value} + + + + {value} + ); } From 6991f7bc30d86aa46ef5e90d3b7bacb0784780b6 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 16 Jan 2023 16:18:15 +0100 Subject: [PATCH 05/23] feat(table improvements): Finalize mobile table design. --- .../components/shared-styled-components.tsx | 46 ++++++ .../src/components/tables/mobile-table.tsx | 58 +------ .../domain/behavior/behavior-table-tile.tsx | 146 +++++++++--------- .../vaccine/components/narrow-percentage.tsx | 7 +- .../vaccine/components/wide-percentage.tsx | 1 + 5 files changed, 133 insertions(+), 125 deletions(-) create mode 100644 packages/app/src/components/tables/components/shared-styled-components.tsx diff --git a/packages/app/src/components/tables/components/shared-styled-components.tsx b/packages/app/src/components/tables/components/shared-styled-components.tsx new file mode 100644 index 0000000000..a2f017c803 --- /dev/null +++ b/packages/app/src/components/tables/components/shared-styled-components.tsx @@ -0,0 +1,46 @@ +import { Anchor } from '~/components/typography'; +import { colors } from '@corona-dashboard/common'; +import { DisplayProps, compose, display, WidthProps, width, MinWidthProps, BorderProps, minWidth, border } from 'styled-system'; +import { fontWeights, space } from '~/style/theme'; +import styled from 'styled-components'; + +export const Table = styled.table` + border-collapse: collapse; + width: 100%; +`; + +type RowProps = DisplayProps; + +export const Row = styled.tr` + flex-wrap: wrap; + justify-content: space-between; + ${compose(display)}; +`; + +type HeaderCellProps = WidthProps & DisplayProps; + +export const HeaderCell = styled.th` + border-bottom: 1px solid ${colors.gray2}; + font-weight: ${fontWeights.bold}; + padding-bottom: ${space[2]}; + text-align: left; + vertical-align: middle; + ${compose(width)}; + ${compose(display)}; +`; + +type CellProps = MinWidthProps & BorderProps; + +export const Cell = styled.td` + border-bottom: 1px solid ${colors.gray2}; + padding: ${space[3]} ${space[0]}; + vertical-align: middle; + ${compose(minWidth)}; + ${compose(border)}; +`; + +export const BehaviorAnchor = styled(Anchor)` + &:hover { + color: ${colors.blue8}; + } +`; diff --git a/packages/app/src/components/tables/mobile-table.tsx b/packages/app/src/components/tables/mobile-table.tsx index 197efc5955..9bff25ff9e 100644 --- a/packages/app/src/components/tables/mobile-table.tsx +++ b/packages/app/src/components/tables/mobile-table.tsx @@ -1,17 +1,16 @@ import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { Anchor, InlineText } from '~/components/typography'; +import { BehaviorAnchor, Cell, HeaderCell, Row, Table } from './components/shared-styled-components'; import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; import { BehaviorIdentifier } from '~/domain/behavior/logic/behavior-types'; -import { border, BorderProps, compose, display, DisplayProps, minWidth, MinWidthProps, width, WidthProps } from 'styled-system'; import { Box } from '~/components/base'; -import { colors, NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; -import { fontWeights, space } from '~/style/theme'; import { formatAgeGroupString } from '~/utils/format-age-group-string'; import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; +import { InlineText } from '~/components/typography'; +import { NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; import { PercentageData, PercentageDataPoint } from './components/percentage-data'; import { SiteText } from '~/locale'; +import { space } from '~/style/theme'; import { useIntl } from '~/intl'; -import styled from 'styled-components'; type PercentageData = PercentageDataPoint[][]; @@ -38,16 +37,14 @@ export const MobileTable = ({ tableData, headerText, hasAgeGroups, isBehaviourTa - - {headerText} - + {headerText} {tableData.map((item, tableDataIndex) => ( - - + + {isBehaviourTable && ( <> @@ -86,44 +83,3 @@ export const MobileTable = ({ tableData, headerText, hasAgeGroups, isBehaviourTa ); }; - -const Table = styled.table` - border-collapse: collapse; - width: 100%; -`; - -type RowProps = DisplayProps; - -const Row = styled.tr` - flex-wrap: wrap; - justify-content: space-between; - ${compose(display)}; -`; - -type HeaderCellProps = WidthProps & DisplayProps; - -const HeaderCell = styled.th` - border-bottom: 1px solid ${colors.gray2}; - font-weight: ${fontWeights.bold}; - padding-bottom: ${space[2]}; - text-align: left; - vertical-align: middle; - ${compose(width)}; - ${compose(display)}; -`; - -type CellProps = MinWidthProps & BorderProps; - -const Cell = styled.td` - border-bottom: 1px solid ${colors.gray2}; - padding: ${space[3]} ${space[0]}; - vertical-align: middle; - ${compose(minWidth)}; - ${compose(border)}; -`; - -const BehaviorAnchor = styled(Anchor)` - &:hover { - color: ${colors.blue8}; - } -`; diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index edac271e6f..373ee37947 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -17,6 +17,7 @@ import scrollIntoView from 'scroll-into-view-if-needed'; import styled from 'styled-components'; import { MobileTable } from '~/components/tables/mobile-table'; import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; +import { useBreakpoints } from '~/utils/use-breakpoints'; interface BehaviorTableTileProps { title: string; @@ -33,6 +34,7 @@ interface BehaviorTableTileProps { const trendColumnWidth = 125; export function BehaviorTableTile({ title, description, value, annotation, setCurrentId, scrollRef, text }: BehaviorTableTileProps) { + const breakpoints = useBreakpoints(true); const behaviorsTableData = useBehaviorTableData(value as NlBehaviorValue); const percentageData: PercentageDataPoint[][] = behaviorsTableData.map(behavior => { return [ @@ -62,78 +64,80 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu return ( - - - {/* - - - - {text.basisregels.header_basisregel} - - Coronaregel volgen - - - Coronaregel steunen - - - - - - {behaviorsTableData.map((behavior) => ( - <> - Desktop/wide screens - {/* - - - - - - - anchorButtonClickHandler(behavior.id, scrollRef)}> - - {behavior.description} + {breakpoints.lg ? ( + + + + + {text.basisregels.header_basisregel} + + Coronaregel volgen + + + Coronaregel steunen + + + + + + {behaviorsTableData.map((behavior) => ( + <> + {/* Desktop/wide screens */} + + + + + - - - - - - } - color={colors.blue6} - justifyContent="flex-start" - /> - - - - } - color={colors.yellow3} - justifyContent="flex-start" - /> - - - - - - - - - - - ))} - - - } */} + + anchorButtonClickHandler(behavior.id, scrollRef)}> + + {behavior.description} + + + + + + + } + color={colors.blue6} + justifyContent="flex-start" + /> + + + + } + color={colors.yellow3} + justifyContent="flex-start" + /> + + + + + + + + + + + ))} + + + + ) : ( + + )} diff --git a/packages/app/src/domain/vaccine/components/narrow-percentage.tsx b/packages/app/src/domain/vaccine/components/narrow-percentage.tsx index 7bea7a345f..c22b545e16 100644 --- a/packages/app/src/domain/vaccine/components/narrow-percentage.tsx +++ b/packages/app/src/domain/vaccine/components/narrow-percentage.tsx @@ -9,11 +9,12 @@ interface NarrowPercentageProps { textLabel: string; } +// TODO: AP: Move to tables directory export function NarrowPercentage({ value, color, textLabel }: NarrowPercentageProps) { return ( - - - {`${textLabel}:`} + + + {textLabel}: diff --git a/packages/app/src/domain/vaccine/components/wide-percentage.tsx b/packages/app/src/domain/vaccine/components/wide-percentage.tsx index 8466ec480a..12c9934ffe 100644 --- a/packages/app/src/domain/vaccine/components/wide-percentage.tsx +++ b/packages/app/src/domain/vaccine/components/wide-percentage.tsx @@ -9,6 +9,7 @@ interface PercentageWideNumberProps { justifyContent: string; } +// TODO: AP: Move to tables directory export function WidePercentage({ value, color, justifyContent }: PercentageWideNumberProps) { return ( Date: Mon, 16 Jan 2023 17:38:51 +0100 Subject: [PATCH 06/23] feat(table improvements): Implement mobile tables for autumn vaccine campaign table. --- .../tables/components/percentage-data.tsx | 7 ++- .../src/components/tables/mobile-table.tsx | 10 +-- ...utumn-2022-shot-coverage-per-age-group.tsx | 62 +++++++++++-------- .../vaccine/components/narrow-percentage.tsx | 2 +- 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/packages/app/src/components/tables/components/percentage-data.tsx b/packages/app/src/components/tables/components/percentage-data.tsx index 683783288f..1c45e28822 100644 --- a/packages/app/src/components/tables/components/percentage-data.tsx +++ b/packages/app/src/components/tables/components/percentage-data.tsx @@ -10,7 +10,7 @@ export type PercentageDataPoint = { trendDirection?: 'up' | 'down' | 'equal' | null; percentage: { color: string; - value: number; + value: number | string; }; }; @@ -34,8 +34,9 @@ export const PercentageData = ({percentageDataPoints}: PercentageDataProps) => { textLabel={percentageDataPoint.title} /> - - + + {/* In some cases, the percentage value is a string so it needs to be parsed for the progress bar to be filled properly. */} + ))} diff --git a/packages/app/src/components/tables/mobile-table.tsx b/packages/app/src/components/tables/mobile-table.tsx index 9bff25ff9e..dac0bb13c6 100644 --- a/packages/app/src/components/tables/mobile-table.tsx +++ b/packages/app/src/components/tables/mobile-table.tsx @@ -5,7 +5,7 @@ import { BehaviorIdentifier } from '~/domain/behavior/logic/behavior-types'; import { Box } from '~/components/base'; import { formatAgeGroupString } from '~/utils/format-age-group-string'; import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { InlineText } from '~/components/typography'; +import { BoldText } from '~/components/typography'; import { NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; import { PercentageData, PercentageDataPoint } from './components/percentage-data'; import { SiteText } from '~/locale'; @@ -45,7 +45,7 @@ export const MobileTable = ({ tableData, headerText, hasAgeGroups, isBehaviourTa {tableData.map((item, tableDataIndex) => ( - + {isBehaviourTable && ( <> @@ -53,9 +53,9 @@ export const MobileTable = ({ tableData, headerText, hasAgeGroups, isBehaviourTa onClickConfig.handler(item.id, onClickConfig.scrollRef) : undefined}> - - {item.description} - + + {item.description} + )} diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index 135bf2840a..6a4cd9165b 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -1,13 +1,13 @@ -import { - assert, - NlVaccineCoveragePerAgeGroupValue, -} from '@corona-dashboard/common'; +import { assert, NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; import { NarrowCoverageTable } from './components/narrow-coverage-table'; import { WideCoverageTable } from './components/wide-coverage-table'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; +import { MobileTable } from '~/components/tables/mobile-table'; +import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; +import { useIntl } from '~/intl'; interface Autumn2022ShotCoveragePerAgeGroupProps { title: string; @@ -18,39 +18,47 @@ interface Autumn2022ShotCoveragePerAgeGroupProps { text: SiteText['pages']['vaccinations_page']['nl']['vaccination_coverage']; } -export const Autumn2022ShotCoveragePerAgeGroup = ({ - title, - description, - metadata, - values, - sortingOrder, - text, -}: Autumn2022ShotCoveragePerAgeGroupProps) => { +export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata, values, sortingOrder, text }: Autumn2022ShotCoveragePerAgeGroupProps) => { const breakpoints = useBreakpoints(true); + const { formatPercentage } = useIntl(); const getSortingOrder = (ageGroup: string) => { - const index = sortingOrder.findIndex( - (sortingIndex) => sortingIndex === ageGroup - ); - - assert( - index >= 0, - `[${Autumn2022ShotCoveragePerAgeGroup.name}] No sorting order defined for age group ${ageGroup}` - ); - + const index = sortingOrder.findIndex((sortingIndex) => sortingIndex === ageGroup); + assert(index >= 0, `[${Autumn2022ShotCoveragePerAgeGroup.name}] No sorting order defined for age group ${ageGroup}`); return index; }; - const sortedValues = values.sort( - (a, b) => - getSortingOrder(a.age_group_range) - getSortingOrder(b.age_group_range) - ); + const sortedValues = values.sort((a, b) => getSortingOrder(a.age_group_range) - getSortingOrder(b.age_group_range)); + const percentageData = sortedValues.map(value => { + return [ + { + title: text.headers.autumn_2022_shot, + percentage: { + color: COLOR_AUTUMN_2022_SHOT, + value: value.autumn_2022_vaccinated_percentage !== null ? `${formatPercentage(value.autumn_2022_vaccinated_percentage)}%` : text.no_data + } + }, + { + title: text.headers.fully_vaccinated, + percentage: { + color: COLOR_FULLY_VACCINATED, + value: `${formatPercentage(value.fully_vaccinated_percentage)}%` + } + } + ] + }); + return ( - {breakpoints.md ? ( + {breakpoints.lg ? ( ) : ( - + )} ); diff --git a/packages/app/src/domain/vaccine/components/narrow-percentage.tsx b/packages/app/src/domain/vaccine/components/narrow-percentage.tsx index c22b545e16..ffdca97952 100644 --- a/packages/app/src/domain/vaccine/components/narrow-percentage.tsx +++ b/packages/app/src/domain/vaccine/components/narrow-percentage.tsx @@ -13,7 +13,7 @@ interface NarrowPercentageProps { export function NarrowPercentage({ value, color, textLabel }: NarrowPercentageProps) { return ( - + {textLabel}: From 9e87d32a8f68b06a180f31c28f8403390ddd907f Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Wed, 18 Jan 2023 15:28:05 +0100 Subject: [PATCH 07/23] feat(table improvements): Implement mobile tables for all tables. --- .../tables/logic/get-percentage-data.ts | 48 +++++++++++++++ .../src/components/tables/mobile-table.tsx | 6 +- .../domain/behavior/behavior-table-tile.tsx | 42 ++++++------- ...utumn-2022-shot-coverage-per-age-group.tsx | 47 +++++---------- .../components/narrow-coverage-table.tsx | 1 + .../booster-shot-coverage-per-age-group.tsx | 58 ++++++++---------- .../components/narrow-coverage-table.tsx | 1 + .../domain/vaccine/logic/get-sorting-order.ts | 8 +++ .../components/narrow-coverage-table.tsx | 1 + .../vaccine-coverage-per-age-group.tsx | 60 +++++++++---------- 10 files changed, 149 insertions(+), 123 deletions(-) create mode 100644 packages/app/src/components/tables/logic/get-percentage-data.ts create mode 100644 packages/app/src/domain/vaccine/logic/get-sorting-order.ts diff --git a/packages/app/src/components/tables/logic/get-percentage-data.ts b/packages/app/src/components/tables/logic/get-percentage-data.ts new file mode 100644 index 0000000000..b2f6fa5abe --- /dev/null +++ b/packages/app/src/components/tables/logic/get-percentage-data.ts @@ -0,0 +1,48 @@ +import { createFormatting } from "@corona-dashboard/common"; +import { PercentageDataPoint } from "../components/percentage-data"; + +type percentageParam = { propertyKey: string, shouldFormat?: boolean }; +type percentageParams = { first: percentageParam, second: percentageParam }; +type trendDirectionParams = { first: percentageParam, second: percentageParam }; +type colorParam = { first: string, second: string }; +type titleParam = { first: string, second: string }; + +// Returns an array of objects corresponding to percentage data used by tables on the dashboard +export const getPercentageData = ( + dataset: any[], // TODO:AP - figure out how to properly type this + title: titleParam, + color: colorParam, + percentageKeys: percentageParams, + trendDirection?: trendDirectionParams, + noDataText?: string, + formatPercentage?: ReturnType['formatPercentage'] +): PercentageDataPoint[][] => { + const getPercentageValue = (datasetItem: any, percentageItem: percentageParam) => { + if (formatPercentage === undefined) return; + + return typeof percentageItem !== 'number' && datasetItem[percentageItem.propertyKey] !== null + ? `${formatPercentage(datasetItem[percentageItem.propertyKey])}%` + : noDataText; + } + + return dataset.map((datasetItem) => { + return [ + { + title: title.first, + trendDirection: trendDirection?.first.propertyKey !== undefined && trendDirection.first.propertyKey in datasetItem ? datasetItem[trendDirection.first.propertyKey] : null, + percentage: { + color: color.first, + value: percentageKeys.first.shouldFormat ? getPercentageValue(datasetItem, percentageKeys.first) : datasetItem[percentageKeys.first.propertyKey], + }, + }, + { + title: title.second, + trendDirection: trendDirection?.second.propertyKey !== undefined && trendDirection.second.propertyKey in datasetItem ? datasetItem[trendDirection.second.propertyKey] : null, + percentage: { + color: color.second, + value: percentageKeys.second.shouldFormat ? getPercentageValue(datasetItem, percentageKeys.second) : datasetItem[percentageKeys.second.propertyKey], + }, + }, + ]; + }); +}; diff --git a/packages/app/src/components/tables/mobile-table.tsx b/packages/app/src/components/tables/mobile-table.tsx index dac0bb13c6..4f88067067 100644 --- a/packages/app/src/components/tables/mobile-table.tsx +++ b/packages/app/src/components/tables/mobile-table.tsx @@ -2,10 +2,10 @@ import { AgeGroup } from '~/domain/vaccine/components/age-group'; import { BehaviorAnchor, Cell, HeaderCell, Row, Table } from './components/shared-styled-components'; import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; import { BehaviorIdentifier } from '~/domain/behavior/logic/behavior-types'; +import { BoldText } from '~/components/typography'; import { Box } from '~/components/base'; import { formatAgeGroupString } from '~/utils/format-age-group-string'; import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { BoldText } from '~/components/typography'; import { NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; import { PercentageData, PercentageDataPoint } from './components/percentage-data'; import { SiteText } from '~/locale'; @@ -19,7 +19,7 @@ type ScrollRef = { current: HTMLDivElement | null }; interface MobileTableProps { headerText: string; // tableData: NlBehaviorValue | VrBehaviorArchived_20221019Value; - tableData: any[]; + tableData: any[]; // TODO:AP - figure out how to properly type this. percentageData: PercentageData; hasAgeGroups?: boolean; isBehaviourTable?: boolean; @@ -37,7 +37,7 @@ export const MobileTable = ({ tableData, headerText, hasAgeGroups, isBehaviourTa
- {headerText} + {headerText} - Mobile table diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index 373ee37947..b6280e24bb 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -7,17 +7,18 @@ import { ChartTile } from '~/components/chart-tile'; import { colors, NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; import { compose, display, DisplayProps, width, WidthProps, minWidth, MinWidthProps, border, BorderProps } from 'styled-system'; import { fontWeights, space } from '~/style/theme'; +import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { isDefined, isPresent } from 'ts-is-present'; +import { MobileTable } from '~/components/tables/mobile-table'; import { PercentageBar } from '~/components/percentage-bar'; +import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; import { SiteText } from '~/locale'; import { useBehaviorLookupKeys } from './logic/use-behavior-lookup-keys'; +import { useBreakpoints } from '~/utils/use-breakpoints'; import { WidePercentage } from '../vaccine/components/wide-percentage'; import React, { useMemo } from 'react'; import scrollIntoView from 'scroll-into-view-if-needed'; import styled from 'styled-components'; -import { MobileTable } from '~/components/tables/mobile-table'; -import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; -import { useBreakpoints } from '~/utils/use-breakpoints'; interface BehaviorTableTileProps { title: string; @@ -36,27 +37,18 @@ const trendColumnWidth = 125; export function BehaviorTableTile({ title, description, value, annotation, setCurrentId, scrollRef, text }: BehaviorTableTileProps) { const breakpoints = useBreakpoints(true); const behaviorsTableData = useBehaviorTableData(value as NlBehaviorValue); - const percentageData: PercentageDataPoint[][] = behaviorsTableData.map(behavior => { - return [ - { - title: 'Coronaregel volgen', - trendDirection: behavior.complianceTrend, - percentage: { - color: colors.blue6, - value: behavior.compliancePercentage - } - }, - { - title: 'Coronaregel steunen', - trendDirection: behavior.supportTrend, - percentage: { - color: colors.yellow3, - value: behavior.supportPercentage - } - } - ] - }); - + const titles = { first: 'Coronaregel volgen', second: 'Coronaregel steunen' }; + const colorValues = { first: colors.blue6, second: colors.yellow3 }; + const percentageKeys = { + first: { propertyKey: 'compliancePercentage', shouldFormat: false }, + second: { propertyKey: 'supportPercentage', shouldFormat: false } + } + const trendDirectionKeys = { + first: { propertyKey: 'complianceTrend' }, + second: { propertyKey: 'supportTrend' } + } + const percentageData: PercentageDataPoint[][] = getPercentageData(behaviorsTableData, titles, colorValues, percentageKeys, trendDirectionKeys); + const anchorButtonClickHandler = (id: BehaviorIdentifier, scrollRef: { current: HTMLDivElement | null }) => { scrollIntoView(scrollRef.current as Element); setCurrentId(id); @@ -154,6 +146,7 @@ interface PercentageBarWithoutNumberProps { marginBottom?: string; } +// TODO:AP - Can be deleted after desktop-table is implemented function PercentageBarWithoutNumber({ percentage, color, marginBottom }: PercentageBarWithoutNumberProps) { return ( @@ -192,6 +185,7 @@ function useBehaviorTableData(value: NlBehaviorValue) { }, [value, behaviorLookupKeys]); } +// TODO:AP - All of the styled components could be deleted after implementing desktop table - see shared-styled-components const StyledTable = styled.table` border-collapse: collapse; width: 100%; diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index 6a4cd9165b..5ffde937f7 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -1,13 +1,15 @@ -import { assert, NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; import { ChartTile } from '~/components/chart-tile'; +import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; +import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; +import { getSortingOrder } from '../logic/get-sorting-order'; import { MetadataProps } from '~/components/metadata'; -import { NarrowCoverageTable } from './components/narrow-coverage-table'; -import { WideCoverageTable } from './components/wide-coverage-table'; +import { MobileTable } from '~/components/tables/mobile-table'; +import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; -import { MobileTable } from '~/components/tables/mobile-table'; -import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; import { useIntl } from '~/intl'; +import { WideCoverageTable } from './components/wide-coverage-table'; +import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; interface Autumn2022ShotCoveragePerAgeGroupProps { title: string; @@ -21,32 +23,15 @@ interface Autumn2022ShotCoveragePerAgeGroupProps { export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata, values, sortingOrder, text }: Autumn2022ShotCoveragePerAgeGroupProps) => { const breakpoints = useBreakpoints(true); const { formatPercentage } = useIntl(); - - const getSortingOrder = (ageGroup: string) => { - const index = sortingOrder.findIndex((sortingIndex) => sortingIndex === ageGroup); - assert(index >= 0, `[${Autumn2022ShotCoveragePerAgeGroup.name}] No sorting order defined for age group ${ageGroup}`); - return index; - }; - - const sortedValues = values.sort((a, b) => getSortingOrder(a.age_group_range) - getSortingOrder(b.age_group_range)); - const percentageData = sortedValues.map(value => { - return [ - { - title: text.headers.autumn_2022_shot, - percentage: { - color: COLOR_AUTUMN_2022_SHOT, - value: value.autumn_2022_vaccinated_percentage !== null ? `${formatPercentage(value.autumn_2022_vaccinated_percentage)}%` : text.no_data - } - }, - { - title: text.headers.fully_vaccinated, - percentage: { - color: COLOR_FULLY_VACCINATED, - value: `${formatPercentage(value.fully_vaccinated_percentage)}%` - } - } - ] - }); + const componentName = Autumn2022ShotCoveragePerAgeGroup.name; + const sortedValues = values.sort((a, b) => getSortingOrder(a.age_group_range, sortingOrder, componentName) - getSortingOrder(b.age_group_range, sortingOrder, componentName)); + const titles = { first: text.headers.autumn_2022_shot, second: text.headers.fully_vaccinated }; + const colors = { first: COLOR_AUTUMN_2022_SHOT, second: COLOR_FULLY_VACCINATED }; + const percentageKeys = { + first: { propertyKey: 'autumn_2022_vaccinated_percentage', shouldFormat: true }, + second: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true } + } + const percentageData: PercentageDataPoint[][] = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.no_data, formatPercentage); return ( diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx index 013b914822..13ef6af257 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx @@ -17,6 +17,7 @@ interface NarrowCoverageTableProps { values: NlVaccineCoveragePerAgeGroupValue[]; } +// TODO:AP - delete before merging branch export const NarrowCoverageTable = ({ values, text }: NarrowCoverageTableProps) => { const { commonTexts, formatPercentage } = useIntl(); diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx index b0eac85aec..de9abcf43e 100644 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx @@ -1,15 +1,16 @@ -import { - assert, - NlVaccineCoveragePerAgeGroupArchived_20220908Value, - VrVaccineCoveragePerAgeGroupArchived_20220908Value, - GmVaccineCoveragePerAgeGroupArchived_20220908Value, -} from '@corona-dashboard/common'; import { ChartTile } from '~/components/chart-tile'; +import { COLOR_FULLY_BOOSTERED, COLOR_FULLY_VACCINATED } from '../common'; +import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; +import { getSortingOrder } from '../logic/get-sorting-order'; import { MetadataProps } from '~/components/metadata'; -import { NarrowCoverageTable } from './components/narrow-coverage-table'; -import { WideCoverageTable } from './components/wide-coverage-table'; +import { MobileTable } from '~/components/tables/mobile-table'; +import { NlVaccineCoveragePerAgeGroupArchived_20220908Value, VrVaccineCoveragePerAgeGroupArchived_20220908Value, GmVaccineCoveragePerAgeGroupArchived_20220908Value } from '@corona-dashboard/common'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; +import { useIntl } from '~/intl'; +import { WideCoverageTable } from './components/wide-coverage-table'; +import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; + interface BoosterCoveragePerAgeGroupProps { title: string; description: string; @@ -22,37 +23,30 @@ interface BoosterCoveragePerAgeGroupProps { text: SiteText['pages']['vaccinations_page']['nl']; } -export function BoosterShotCoveragePerAgeGroup({ - title, - description, - metadata, - values, - sortingOrder, - text, -}: BoosterCoveragePerAgeGroupProps) { +export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text}: BoosterCoveragePerAgeGroupProps) { const breakpoints = useBreakpoints(true); - - const getSortingOrder = (ageGroup: string) => { - const index = sortingOrder.findIndex((x) => x === ageGroup); - - assert( - index >= 0, - `[${BoosterShotCoveragePerAgeGroup.name}] No sorting order defined for age group ${ageGroup}` - ); - - return index; + const { formatPercentage } = useIntl(); + const componentName = BoosterShotCoveragePerAgeGroup.name; + const sortedValues = values.sort((a, b) => getSortingOrder(a.age_group_range, sortingOrder, componentName) - getSortingOrder(b.age_group_range, sortingOrder, componentName)); + const titles = { first: text.vaccination_coverage.headers.fully_vaccinated, second: text.archived.vaccination_coverage.campaign_headers.booster_shot }; + const colors = { first: COLOR_FULLY_VACCINATED, second: COLOR_FULLY_BOOSTERED}; + const percentageKeys = { + first: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true}, + second: { propertyKey: 'booster_shot_percentage', shouldFormat: true} }; + const percentageData: PercentageDataPoint[][] = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.vaccination_coverage.no_data, formatPercentage); - const sortedValues = values.sort( - (a, b) => - getSortingOrder(a.age_group_range) - getSortingOrder(b.age_group_range) - ); return ( - {breakpoints.md ? ( + {breakpoints.lg ? ( ) : ( - + )} ); diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/narrow-coverage-table.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/narrow-coverage-table.tsx index cf7ba5a8c4..c957312395 100644 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/narrow-coverage-table.tsx +++ b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/narrow-coverage-table.tsx @@ -15,6 +15,7 @@ import { } from '@corona-dashboard/common'; import { SiteText } from '~/locale'; +// TODO:AP - delete before merging branch export function NarrowCoverageTable({ values, text, diff --git a/packages/app/src/domain/vaccine/logic/get-sorting-order.ts b/packages/app/src/domain/vaccine/logic/get-sorting-order.ts new file mode 100644 index 0000000000..e38388e9c7 --- /dev/null +++ b/packages/app/src/domain/vaccine/logic/get-sorting-order.ts @@ -0,0 +1,8 @@ +import { assert } from "@corona-dashboard/common"; + +// Determines the sorting order for a ordered data +export const getSortingOrder = (ageGroup: string, sortingOrder: string[], componentName: string) => { + const index = sortingOrder.findIndex((sortingIndex) => sortingIndex === ageGroup); + assert(index >= 0, `[${componentName}] No sorting order defined for age group ${ageGroup}`); + return index; +}; diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/narrow-coverage-table.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/narrow-coverage-table.tsx index c76fc99651..76483292db 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/narrow-coverage-table.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/narrow-coverage-table.tsx @@ -11,6 +11,7 @@ import { AgeGroup } from '~/domain/vaccine/components/age-group'; import { GmVaccineCoveragePerAgeGroupArchivedValue, NlVaccineCoveragePerAgeGroupArchivedValue, VrVaccineCoveragePerAgeGroupArchivedValue } from '@corona-dashboard/common'; import { SiteText } from '~/locale'; +// TODO:AP - delete before merging branch export function NarrowCoverageTable({ values, text, diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx index 2b9bcae1eb..d4aaeb99f3 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx @@ -1,15 +1,16 @@ -import { - assert, - GmVaccineCoveragePerAgeGroupArchivedValue, - NlVaccineCoveragePerAgeGroupArchivedValue, - VrVaccineCoveragePerAgeGroupArchivedValue, -} from '@corona-dashboard/common'; +import { ARCHIVED_COLORS } from '../common'; import { ChartTile } from '~/components/chart-tile'; +import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; +import { getSortingOrder } from '../logic/get-sorting-order'; +import { GmVaccineCoveragePerAgeGroupArchivedValue, NlVaccineCoveragePerAgeGroupArchivedValue, VrVaccineCoveragePerAgeGroupArchivedValue } from '@corona-dashboard/common'; import { MetadataProps } from '~/components/metadata'; -import { NarrowCoverageTable } from '~/domain/vaccine/vaccine-coverage-per-age-group/components/narrow-coverage-table'; -import { WideCoverageTable } from '~/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table'; +import { MobileTable } from '~/components/tables/mobile-table'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; +import { useIntl } from '~/intl'; +import { WideCoverageTable } from '~/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table'; +import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; + interface VaccineCoveragePerAgeGroupProps { title: string; description: string; @@ -22,37 +23,30 @@ interface VaccineCoveragePerAgeGroupProps { text: SiteText['pages']['vaccinations_page']['nl']; } -export function VaccineCoveragePerAgeGroup({ - title, - description, - metadata, - values, - sortingOrder, - text, -}: VaccineCoveragePerAgeGroupProps) { +export function VaccineCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text}: VaccineCoveragePerAgeGroupProps) { const breakpoints = useBreakpoints(true); + const { formatPercentage } = useIntl(); + const componentName = VaccineCoveragePerAgeGroup.name; + const sortedValues = values.sort((a, b) => getSortingOrder(a.age_group_range, sortingOrder, componentName) - getSortingOrder(b.age_group_range, sortingOrder, componentName)); + const titles = { first: text.archived.vaccination_coverage.campaign_headers.first_shot, second: text.archived.vaccination_coverage.campaign_headers.coverage }; + const colors = { first: ARCHIVED_COLORS.COLOR_HAS_ONE_SHOT, second: ARCHIVED_COLORS.COLOR_FULLY_VACCINATED }; + const percentageKeys = { + first: { propertyKey: 'has_one_shot_percentage', shouldFormat: true }, + second: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true } + } + const percentageData: PercentageDataPoint[][] = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.vaccination_coverage.no_data, formatPercentage); - const getSortingOrder = (ageGroup: string) => { - const index = sortingOrder.findIndex((x) => x === ageGroup); - - assert( - index >= 0, - `[${VaccineCoveragePerAgeGroup.name}] No sorting order defined for age group ${ageGroup}` - ); - - return index; - }; - - const sortedValues = values.sort( - (a, b) => - getSortingOrder(a.age_group_range) - getSortingOrder(b.age_group_range) - ); return ( - {breakpoints.md ? ( + {breakpoints.lg ? ( ) : ( - + )} ); From 5c939e0466313eb8673bc1523d73a0e4e16bc8e5 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 19 Jan 2023 13:42:37 +0100 Subject: [PATCH 08/23] feat(table-improvements): Create and implement WideTable for behavior advice table. Rename some stuff. Extract types to its own file. Co-authored-by: Ros, Luuk --- .../components/desktop-percentage-data.tsx | 46 +++++ ...ge-data.tsx => mobile-percentage-data.tsx} | 18 +- .../components/shared-styled-components.tsx | 22 ++- .../src/components/tables/desktop-table.tsx | 0 .../tables/logic/get-percentage-data.ts | 2 +- .../{mobile-table.tsx => narrow-table.tsx} | 41 ++--- packages/app/src/components/tables/types.ts | 22 +++ .../app/src/components/tables/wide-table.tsx | 84 +++++++++ .../domain/behavior/behavior-table-tile.tsx | 168 +++--------------- ...utumn-2022-shot-coverage-per-age-group.tsx | 7 +- .../components/wide-coverage-table.tsx | 1 + .../booster-shot-coverage-per-age-group.tsx | 7 +- .../vaccine-coverage-per-age-group.tsx | 7 +- 13 files changed, 224 insertions(+), 201 deletions(-) create mode 100644 packages/app/src/components/tables/components/desktop-percentage-data.tsx rename packages/app/src/components/tables/components/{percentage-data.tsx => mobile-percentage-data.tsx} (89%) delete mode 100644 packages/app/src/components/tables/desktop-table.tsx rename packages/app/src/components/tables/{mobile-table.tsx => narrow-table.tsx} (74%) create mode 100644 packages/app/src/components/tables/types.ts create mode 100644 packages/app/src/components/tables/wide-table.tsx diff --git a/packages/app/src/components/tables/components/desktop-percentage-data.tsx b/packages/app/src/components/tables/components/desktop-percentage-data.tsx new file mode 100644 index 0000000000..86b2d5d9c2 --- /dev/null +++ b/packages/app/src/components/tables/components/desktop-percentage-data.tsx @@ -0,0 +1,46 @@ +import { colors } from '@corona-dashboard/common'; +import { Box } from '~/components/base'; +import { BehaviorTrend } from '~/domain/behavior/components/behavior-trend'; +import { WidePercentage } from '~/domain/vaccine/components/wide-percentage'; +import { space } from '~/style/theme'; +import { PercentageDataPoint } from '../types'; +import { tableColumnWidths } from '../wide-table'; +import { PercentageBarWithoutNumber } from './percentage-bar-without-number'; +import { Cell } from './shared-styled-components'; + +interface PercentageDataProps { + percentageDataPoints: PercentageDataPoint[]; +} + +export const PercentageData = ({ percentageDataPoints }: PercentageDataProps) => { + return ( + <> + {percentageDataPoints.map((percentageDataPoint, index) => ( + + + ) : percentageDataPoint.percentage.value + } + color={percentageDataPoint.percentage.color} + justifyContent="flex-start" + /> + + ))} + + + + {percentageDataPoints.map((percentageDataPoint, index) => ( + + ))} + + + + ); +}; diff --git a/packages/app/src/components/tables/components/percentage-data.tsx b/packages/app/src/components/tables/components/mobile-percentage-data.tsx similarity index 89% rename from packages/app/src/components/tables/components/percentage-data.tsx rename to packages/app/src/components/tables/components/mobile-percentage-data.tsx index 1c45e28822..9c793e9dcf 100644 --- a/packages/app/src/components/tables/components/percentage-data.tsx +++ b/packages/app/src/components/tables/components/mobile-percentage-data.tsx @@ -1,18 +1,10 @@ -import { BehaviorTrend } from "~/domain/behavior/components/behavior-trend" -import { Box } from "~/components/base" import { colors } from "@corona-dashboard/common" +import { Box } from "~/components/base" +import { BehaviorTrend } from "~/domain/behavior/components/behavior-trend" import { NarrowPercentage } from "~/domain/vaccine/components/narrow-percentage" -import { PercentageBarWithoutNumber } from "./percentage-bar-without-number" import { space } from "~/style/theme" - -export type PercentageDataPoint = { - title: string; - trendDirection?: 'up' | 'down' | 'equal' | null; - percentage: { - color: string; - value: number | string; - }; -}; +import { PercentageDataPoint } from "../types" +import { PercentageBarWithoutNumber } from "./percentage-bar-without-number" interface PercentageDataProps { percentageDataPoints: PercentageDataPoint[]; @@ -25,7 +17,7 @@ export const PercentageData = ({percentageDataPoints}: PercentageDataProps) => { ) : percentageDataPoint.percentage.value diff --git a/packages/app/src/components/tables/components/shared-styled-components.tsx b/packages/app/src/components/tables/components/shared-styled-components.tsx index a2f017c803..1ba12e8976 100644 --- a/packages/app/src/components/tables/components/shared-styled-components.tsx +++ b/packages/app/src/components/tables/components/shared-styled-components.tsx @@ -1,14 +1,18 @@ -import { Anchor } from '~/components/typography'; import { colors } from '@corona-dashboard/common'; -import { DisplayProps, compose, display, WidthProps, width, MinWidthProps, BorderProps, minWidth, border } from 'styled-system'; -import { fontWeights, space } from '~/style/theme'; import styled from 'styled-components'; +import { border, BorderProps, compose, display, DisplayProps, minWidth, MinWidthProps, width, WidthProps } from 'styled-system'; +import { Anchor } from '~/components/typography'; +import { fontWeights, mediaQueries, space } from '~/style/theme'; export const Table = styled.table` border-collapse: collapse; width: 100%; `; +export const TableHead = styled.thead` + border-bottom: 1px solid ${colors.gray2}; +`; + type RowProps = DisplayProps; export const Row = styled.tr` @@ -25,18 +29,20 @@ export const HeaderCell = styled.th` padding-bottom: ${space[2]}; text-align: left; vertical-align: middle; - ${compose(width)}; - ${compose(display)}; + ${compose(display, width)}; + + @media ${mediaQueries.lg} { + padding-right: ${space[2]}; + } `; type CellProps = MinWidthProps & BorderProps; export const Cell = styled.td` border-bottom: 1px solid ${colors.gray2}; - padding: ${space[3]} ${space[0]}; + padding-block: ${space[3]}; vertical-align: middle; - ${compose(minWidth)}; - ${compose(border)}; + ${compose(border, minWidth)}; `; export const BehaviorAnchor = styled(Anchor)` diff --git a/packages/app/src/components/tables/desktop-table.tsx b/packages/app/src/components/tables/desktop-table.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/app/src/components/tables/logic/get-percentage-data.ts b/packages/app/src/components/tables/logic/get-percentage-data.ts index b2f6fa5abe..fd1b9918f6 100644 --- a/packages/app/src/components/tables/logic/get-percentage-data.ts +++ b/packages/app/src/components/tables/logic/get-percentage-data.ts @@ -1,5 +1,5 @@ import { createFormatting } from "@corona-dashboard/common"; -import { PercentageDataPoint } from "../components/percentage-data"; +import { PercentageDataPoint } from "../types"; type percentageParam = { propertyKey: string, shouldFormat?: boolean }; type percentageParams = { first: percentageParam, second: percentageParam }; diff --git a/packages/app/src/components/tables/mobile-table.tsx b/packages/app/src/components/tables/narrow-table.tsx similarity index 74% rename from packages/app/src/components/tables/mobile-table.tsx rename to packages/app/src/components/tables/narrow-table.tsx index 4f88067067..ad8e10b1fa 100644 --- a/packages/app/src/components/tables/mobile-table.tsx +++ b/packages/app/src/components/tables/narrow-table.tsx @@ -1,35 +1,22 @@ -import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { BehaviorAnchor, Cell, HeaderCell, Row, Table } from './components/shared-styled-components'; -import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; -import { BehaviorIdentifier } from '~/domain/behavior/logic/behavior-types'; -import { BoldText } from '~/components/typography'; import { Box } from '~/components/base'; +import { BoldText } from '~/components/typography'; +import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; +import { AgeGroup } from '~/domain/vaccine/components/age-group'; +import { useIntl } from '~/intl'; +import { space } from '~/style/theme'; import { formatAgeGroupString } from '~/utils/format-age-group-string'; import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; -import { PercentageData, PercentageDataPoint } from './components/percentage-data'; -import { SiteText } from '~/locale'; -import { space } from '~/style/theme'; -import { useIntl } from '~/intl'; - -type PercentageData = PercentageDataPoint[][]; - -type ScrollRef = { current: HTMLDivElement | null }; +import { PercentageData } from './components/mobile-percentage-data'; +import { BehaviorAnchor, Cell, HeaderCell, Row, Table } from './components/shared-styled-components'; +import { CommonTableProps } from './types'; -interface MobileTableProps { +interface NarrowTableProps extends CommonTableProps { headerText: string; - // tableData: NlBehaviorValue | VrBehaviorArchived_20221019Value; tableData: any[]; // TODO:AP - figure out how to properly type this. - percentageData: PercentageData; - hasAgeGroups?: boolean; - isBehaviourTable?: boolean; - onClickConfig?: { - handler: (id: BehaviorIdentifier, scrollRef: ScrollRef) => void, - scrollRef: ScrollRef; - }; } -export const MobileTable = ({ tableData, headerText, hasAgeGroups, isBehaviourTable, percentageData, onClickConfig }: MobileTableProps) => { +// Component shown for tables on narrow screens. +export const NarrowTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percentageData, onClickConfig }: NarrowTableProps) => { const { commonTexts } = useIntl(); return ( @@ -43,10 +30,10 @@ export const MobileTable = ({ tableData, headerText, hasAgeGroups, isBehaviourTa {tableData.map((item, tableDataIndex) => ( - + - {isBehaviourTable && ( + {hasIcon && ( <> @@ -72,7 +59,7 @@ export const MobileTable = ({ tableData, headerText, hasAgeGroups, isBehaviourTa {percentageData.map((percentageDataPoints, percentageDataIndex) => ( - percentageDataIndex === tableDataIndex && + percentageDataIndex === tableDataIndex && ))} diff --git a/packages/app/src/components/tables/types.ts b/packages/app/src/components/tables/types.ts new file mode 100644 index 0000000000..d2e2c16bd1 --- /dev/null +++ b/packages/app/src/components/tables/types.ts @@ -0,0 +1,22 @@ +import { BehaviorIdentifier } from "~/domain/behavior/logic/behavior-types"; + +export type PercentageDataPoint = { + title: string; + trendDirection?: 'up' | 'down' | 'equal' | null; + percentage: { + color: string; + value: number | string; + }; +}; + +type ScrollRef = { current: HTMLDivElement | null }; + +export interface CommonTableProps { + percentageData: PercentageDataPoint[][]; + hasAgeGroups?: boolean; + hasIcon?: boolean; + onClickConfig?: { + handler: (id: BehaviorIdentifier, scrollRef: ScrollRef) => void, + scrollRef: ScrollRef; + }; +} diff --git a/packages/app/src/components/tables/wide-table.tsx b/packages/app/src/components/tables/wide-table.tsx new file mode 100644 index 0000000000..5f9434bdb8 --- /dev/null +++ b/packages/app/src/components/tables/wide-table.tsx @@ -0,0 +1,84 @@ +import { colors } from '@corona-dashboard/common'; +import styled from 'styled-components'; +import { Box } from '~/components/base'; +import { InlineText } from '~/components/typography'; +import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; +import { AgeGroup } from '~/domain/vaccine/components/age-group'; +import { useIntl } from '~/intl'; +import { space } from '~/style/theme'; +import { formatAgeGroupString } from '~/utils/format-age-group-string'; +import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; +import { PercentageData } from './components/desktop-percentage-data'; +import { BehaviorAnchor, Cell, HeaderCell, Table, TableHead } from './components/shared-styled-components'; +import { CommonTableProps } from './types'; + +export const tableColumnWidths = { + labelColumn: '300px', + percentageColumn: '150px', + percentageBarColumn: '20%' +} + +interface WideTableProps extends CommonTableProps { + headerText: { [key: string]: string }; // Covert this to an object + tableData: any[]; // TODO:AP - figure out how to properly type this. Create an interface for it which requires only the data actually used in this component. +} + +// Component shown for tables on wide screens. +export const WideTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percentageData, onClickConfig }: WideTableProps) => { + const { commonTexts } = useIntl(); + + return ( + +
+ + + {headerText.firstColumn} - Desktop table + {headerText.secondColumn} + {headerText.thirdColumn} + {headerText.fourthColumn} + + + + + {tableData.map((item, tableDataIndex) => ( + + + { hasIcon && ( + + + + + + onClickConfig.handler(item.id, onClickConfig.scrollRef) : undefined}> + + {item.description} + + + + )} + + { hasAgeGroups && ( + + ) + } + + + {percentageData.map((percentageDataPoints, percentageDataIndex) => ( + percentageDataIndex === tableDataIndex && + ))} + + ))} + +
+
+ ); +}; + +const Row = styled.tr` + border-bottom: 1px solid ${colors.gray2}; +`; diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index b6280e24bb..2514c666b2 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -1,24 +1,18 @@ -import { Anchor, InlineText, Text } from '~/components/typography'; -import { BehaviorIcon } from './components/behavior-icon'; -import { BehaviorIdentifier } from './logic/behavior-types'; -import { BehaviorTrend } from './components/behavior-trend'; +import { colors, NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; +import React, { useMemo } from 'react'; +import scrollIntoView from 'scroll-into-view-if-needed'; +import { isDefined, isPresent } from 'ts-is-present'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; -import { colors, NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; -import { compose, display, DisplayProps, width, WidthProps, minWidth, MinWidthProps, border, BorderProps } from 'styled-system'; -import { fontWeights, space } from '~/style/theme'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; -import { isDefined, isPresent } from 'ts-is-present'; -import { MobileTable } from '~/components/tables/mobile-table'; -import { PercentageBar } from '~/components/percentage-bar'; -import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; +import { NarrowTable } from '~/components/tables/narrow-table'; +import { WideTable } from '~/components/tables/wide-table'; +import { Text } from '~/components/typography'; import { SiteText } from '~/locale'; -import { useBehaviorLookupKeys } from './logic/use-behavior-lookup-keys'; +import { space } from '~/style/theme'; import { useBreakpoints } from '~/utils/use-breakpoints'; -import { WidePercentage } from '../vaccine/components/wide-percentage'; -import React, { useMemo } from 'react'; -import scrollIntoView from 'scroll-into-view-if-needed'; -import styled from 'styled-components'; +import { BehaviorIdentifier } from './logic/behavior-types'; +import { useBehaviorLookupKeys } from './logic/use-behavior-lookup-keys'; interface BehaviorTableTileProps { title: string; @@ -32,8 +26,6 @@ interface BehaviorTableTileProps { text: SiteText['pages']['behavior_page']['shared']; } -const trendColumnWidth = 125; - export function BehaviorTableTile({ title, description, value, annotation, setCurrentId, scrollRef, text }: BehaviorTableTileProps) { const breakpoints = useBreakpoints(true); const behaviorsTableData = useBehaviorTableData(value as NlBehaviorValue); @@ -47,7 +39,7 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu first: { propertyKey: 'complianceTrend' }, second: { propertyKey: 'supportTrend' } } - const percentageData: PercentageDataPoint[][] = getPercentageData(behaviorsTableData, titles, colorValues, percentageKeys, trendDirectionKeys); + const percentageData = getPercentageData(behaviorsTableData, titles, colorValues, percentageKeys, trendDirectionKeys); const anchorButtonClickHandler = (id: BehaviorIdentifier, scrollRef: { current: HTMLDivElement | null }) => { scrollIntoView(scrollRef.current as Element); @@ -57,69 +49,23 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu return ( {breakpoints.lg ? ( - - - - - {text.basisregels.header_basisregel} - - Coronaregel volgen - - - Coronaregel steunen - - - - - - {behaviorsTableData.map((behavior) => ( - <> - {/* Desktop/wide screens */} - - - - - - - - anchorButtonClickHandler(behavior.id, scrollRef)}> - - {behavior.description} - - - - - - - } - color={colors.blue6} - justifyContent="flex-start" - /> - - - - } - color={colors.yellow3} - justifyContent="flex-start" - /> - - - - - - - - - - - ))} - - - + ) : ( - )} @@ -140,22 +86,6 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu ); } -interface PercentageBarWithoutNumberProps { - percentage: number; - color: string; - marginBottom?: string; -} - -// TODO:AP - Can be deleted after desktop-table is implemented -function PercentageBarWithoutNumber({ percentage, color, marginBottom }: PercentageBarWithoutNumberProps) { - return ( - - - - - - ); -} function useBehaviorTableData(value: NlBehaviorValue) { const behaviorLookupKeys = useBehaviorLookupKeys(); @@ -184,45 +114,3 @@ function useBehaviorTableData(value: NlBehaviorValue) { .sort((a, b) => (b.compliancePercentage ?? 0) - (a.compliancePercentage ?? 0)); }, [value, behaviorLookupKeys]); } - -// TODO:AP - All of the styled components could be deleted after implementing desktop table - see shared-styled-components -const StyledTable = styled.table` - border-collapse: collapse; - width: 100%; -`; - -type RowProps = DisplayProps; - -const Row = styled.tr` - flex-wrap: wrap; - justify-content: space-between; - ${compose(display)}; -`; - -type HeaderCellProps = WidthProps & DisplayProps; - -const HeaderCell = styled.th` - border-bottom: 1px solid ${colors.gray2}; - text-align: left; - font-weight: ${fontWeights.bold}; - vertical-align: middle; - padding-bottom: ${space[2]}; - ${compose(width)}; - ${compose(display)}; -`; - -type CellProps = MinWidthProps & BorderProps; - -const Cell = styled.td` - border-bottom: 1px solid ${colors.gray2}; - padding: ${space[3]} ${space[0]}; - vertical-align: middle; - ${compose(minWidth)}; - ${compose(border)}; -`; - -const StyledAnchor = styled(Anchor)` - &:hover { - color: ${colors.blue8}; - } -`; diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index 5ffde937f7..6324f67ba2 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -3,13 +3,12 @@ import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { getSortingOrder } from '../logic/get-sorting-order'; import { MetadataProps } from '~/components/metadata'; -import { MobileTable } from '~/components/tables/mobile-table'; +import { NarrowTable } from '~/components/tables/narrow-table'; import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; import { useIntl } from '~/intl'; import { WideCoverageTable } from './components/wide-coverage-table'; -import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; interface Autumn2022ShotCoveragePerAgeGroupProps { title: string; @@ -31,14 +30,14 @@ export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata first: { propertyKey: 'autumn_2022_vaccinated_percentage', shouldFormat: true }, second: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true } } - const percentageData: PercentageDataPoint[][] = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.no_data, formatPercentage); + const percentageData = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.no_data, formatPercentage); return ( {breakpoints.lg ? ( ) : ( - { const { commonTexts, formatPercentage } = useIntl(); diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx index de9abcf43e..ca7dc7ed28 100644 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx @@ -3,13 +3,12 @@ import { COLOR_FULLY_BOOSTERED, COLOR_FULLY_VACCINATED } from '../common'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { getSortingOrder } from '../logic/get-sorting-order'; import { MetadataProps } from '~/components/metadata'; -import { MobileTable } from '~/components/tables/mobile-table'; +import { NarrowTable } from '~/components/tables/narrow-table'; import { NlVaccineCoveragePerAgeGroupArchived_20220908Value, VrVaccineCoveragePerAgeGroupArchived_20220908Value, GmVaccineCoveragePerAgeGroupArchived_20220908Value } from '@corona-dashboard/common'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; import { useIntl } from '~/intl'; import { WideCoverageTable } from './components/wide-coverage-table'; -import { PercentageDataPoint } from '~/components/tables/components/percentage-data'; interface BoosterCoveragePerAgeGroupProps { title: string; @@ -34,14 +33,14 @@ export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, v first: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true}, second: { propertyKey: 'booster_shot_percentage', shouldFormat: true} }; - const percentageData: PercentageDataPoint[][] = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.vaccination_coverage.no_data, formatPercentage); + const percentageData = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.vaccination_coverage.no_data, formatPercentage); return ( {breakpoints.lg ? ( ) : ( - {breakpoints.lg ? ( ) : ( - Date: Thu, 19 Jan 2023 15:19:06 +0100 Subject: [PATCH 09/23] feat(table-improvements): Use WideTable for all vaccine coverage tables. --- .../components/desktop-percentage-data.tsx | 2 +- .../components/shared-styled-components.tsx | 4 +-- .../app/src/components/tables/wide-table.tsx | 12 +++---- .../domain/behavior/behavior-table-tile.tsx | 11 ++---- ...utumn-2022-shot-coverage-per-age-group.tsx | 24 +++++++++---- .../booster-shot-coverage-per-age-group.tsx | 24 +++++++++---- .../components/wide-coverage-table.tsx | 1 + .../vaccine/components/wide-percentage.tsx | 35 +++++++++++-------- .../components/wide-coverage-table.tsx | 1 + .../vaccine-coverage-per-age-group.tsx | 24 +++++++++---- 10 files changed, 85 insertions(+), 53 deletions(-) diff --git a/packages/app/src/components/tables/components/desktop-percentage-data.tsx b/packages/app/src/components/tables/components/desktop-percentage-data.tsx index 86b2d5d9c2..c8cab5d8f6 100644 --- a/packages/app/src/components/tables/components/desktop-percentage-data.tsx +++ b/packages/app/src/components/tables/components/desktop-percentage-data.tsx @@ -29,7 +29,7 @@ export const PercentageData = ({ percentageDataPoints }: PercentageDataProps) =>
))} - + {percentageDataPoints.map((percentageDataPoint, index) => ( ` ${compose(display)}; `; -type HeaderCellProps = WidthProps & DisplayProps; +type HeaderCellProps = WidthProps & DisplayProps & MinWidthProps; export const HeaderCell = styled.th` border-bottom: 1px solid ${colors.gray2}; @@ -29,7 +29,7 @@ export const HeaderCell = styled.th` padding-bottom: ${space[2]}; text-align: left; vertical-align: middle; - ${compose(display, width)}; + ${compose(display, width, minWidth)}; @media ${mediaQueries.lg} { padding-right: ${space[2]}; diff --git a/packages/app/src/components/tables/wide-table.tsx b/packages/app/src/components/tables/wide-table.tsx index 5f9434bdb8..06df29608e 100644 --- a/packages/app/src/components/tables/wide-table.tsx +++ b/packages/app/src/components/tables/wide-table.tsx @@ -13,9 +13,9 @@ import { BehaviorAnchor, Cell, HeaderCell, Table, TableHead } from './components import { CommonTableProps } from './types'; export const tableColumnWidths = { - labelColumn: '300px', - percentageColumn: '150px', - percentageBarColumn: '20%' + labelColumn: '30%', + percentageColumn: '20%', + percentageBarColumn: '30%' } interface WideTableProps extends CommonTableProps { @@ -32,9 +32,9 @@ export const WideTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percen - {headerText.firstColumn} - Desktop table - {headerText.secondColumn} - {headerText.thirdColumn} + {headerText.firstColumn} - Desktop table + {headerText.secondColumn} + {headerText.thirdColumn} {headerText.fourthColumn} diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index 2514c666b2..d56d53ebc8 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -45,6 +45,7 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu scrollIntoView(scrollRef.current as Element); setCurrentId(id); }; + const onClickConfig = { handler: anchorButtonClickHandler, scrollRef: scrollRef } return ( @@ -58,10 +59,7 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu }} tableData={behaviorsTableData} percentageData={percentageData} - onClickConfig={{ - handler: anchorButtonClickHandler, - scrollRef: scrollRef - }} + onClickConfig={onClickConfig} hasIcon /> ) : ( @@ -69,10 +67,7 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu tableData={behaviorsTableData} percentageData={percentageData} headerText={text.basisregels.header_basisregel} - onClickConfig={{ - handler: anchorButtonClickHandler, - scrollRef: scrollRef - }} + onClickConfig={onClickConfig} hasIcon /> )} diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index 6324f67ba2..8fb60f777a 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -1,14 +1,14 @@ +import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; import { ChartTile } from '~/components/chart-tile'; -import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; -import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; -import { getSortingOrder } from '../logic/get-sorting-order'; import { MetadataProps } from '~/components/metadata'; +import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; -import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; +import { WideTable } from '~/components/tables/wide-table'; +import { COLOR_AUTUMN_2022_SHOT, COLOR_FULLY_VACCINATED } from '~/domain/vaccine/common'; +import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; -import { useIntl } from '~/intl'; -import { WideCoverageTable } from './components/wide-coverage-table'; +import { getSortingOrder } from '../logic/get-sorting-order'; interface Autumn2022ShotCoveragePerAgeGroupProps { title: string; @@ -35,7 +35,17 @@ export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata return ( {breakpoints.lg ? ( - + ) : ( {breakpoints.lg ? ( - + ) : ( - - {value} - + + + {value} + ); } + +interface StyledInlineTextProps { + justifyContent: string +} + +const StyledInlineText = styled(InlineText)` + align-items: center; + display: flex; + font-size: ${fontSizes[2]}; + justify-content: ${({justifyContent}) => justifyContent}; + line-height: ${lineHeights[2]}; + padding-right: ${space[4]}; + text-align: left; +` diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table.tsx index 6e9b44eb74..b4d80fd1e0 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table.tsx @@ -18,6 +18,7 @@ interface WideCoverageTable { values: NlVaccineCoveragePerAgeGroupArchivedValue[] | VrVaccineCoveragePerAgeGroupArchivedValue[] | GmVaccineCoveragePerAgeGroupArchivedValue[]; } +// TODO:AP - delete before merging export function WideCoverageTable({ values, text }: WideCoverageTable) { const { commonTexts, formatPercentage } = useIntl(); const formatCoveragePercentage = useVaccineCoveragePercentageFormatter(); diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx index e5cb8e4eee..8670f57e27 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx @@ -1,14 +1,14 @@ -import { ARCHIVED_COLORS } from '../common'; -import { ChartTile } from '~/components/chart-tile'; -import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; -import { getSortingOrder } from '../logic/get-sorting-order'; import { GmVaccineCoveragePerAgeGroupArchivedValue, NlVaccineCoveragePerAgeGroupArchivedValue, VrVaccineCoveragePerAgeGroupArchivedValue } from '@corona-dashboard/common'; +import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; +import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; +import { WideTable } from '~/components/tables/wide-table'; +import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; -import { useIntl } from '~/intl'; -import { WideCoverageTable } from '~/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table'; +import { ARCHIVED_COLORS } from '../common'; +import { getSortingOrder } from '../logic/get-sorting-order'; interface VaccineCoveragePerAgeGroupProps { title: string; @@ -38,7 +38,17 @@ export function VaccineCoveragePerAgeGroup({ title, description, metadata, value return ( {breakpoints.lg ? ( - + ) : ( Date: Fri, 20 Jan 2023 15:30:19 +0100 Subject: [PATCH 10/23] feat(table-improvements): Implement narrow and wide table for behaviour per age group table. --- .../app/src/components/percentage-bar.tsx | 92 +++---- .../percentage-bar-without-number.tsx | 2 +- .../behavior/behavior-per-age-group-tile.tsx | 255 +++++------------- .../domain/behavior/behavior-table-tile.tsx | 8 +- ...utumn-2022-shot-coverage-per-age-group.tsx | 1 + .../domain/vaccine/components/age-group.tsx | 7 +- packages/app/src/pages/landelijk/gedrag.tsx | 2 - .../app/src/utils/format-age-group-string.ts | 8 +- 8 files changed, 108 insertions(+), 267 deletions(-) diff --git a/packages/app/src/components/percentage-bar.tsx b/packages/app/src/components/percentage-bar.tsx index 4dc45262b0..b5f8e5639a 100644 --- a/packages/app/src/components/percentage-bar.tsx +++ b/packages/app/src/components/percentage-bar.tsx @@ -1,7 +1,7 @@ -import { css } from '@styled-system/css'; -import styled from 'styled-components'; import { Box } from '~/components/base'; import { colors } from '@corona-dashboard/common'; +import styled from 'styled-components'; +import { space } from '~/style/theme'; interface PercentageProps { percentage: number; @@ -11,69 +11,45 @@ interface PercentageProps { backgroundColor?: string; } -export function PercentageBar({ - percentage, - height, - color, - backgroundColor = colors.gray2, - backgroundStyle = 'normal', -}: PercentageProps) { +export function PercentageBar({ percentage, height, color, backgroundColor = colors.gray2, backgroundStyle = 'normal' }: PercentageProps) { const minWidth = percentage > 0 ? '2px' : undefined; - - backgroundColor = - backgroundStyle === 'normal' - ? backgroundColor - ? backgroundColor - : 'gray2' - : backgroundColor; + backgroundColor = backgroundStyle === 'normal' ? backgroundColor ? backgroundColor : 'gray2' : backgroundColor; return ( - - - - - + + + + ); } -const Wrapper = styled.div( - css({ - display: 'flex', - position: 'relative', - width: '100%', - }) -); +interface StyledDivProps { + backgroundStyle: string; + backgroundColor: string; + height?: string | number; +} + +const StyledDiv = styled.div` + /* Created by https://stripesgenerator.com/ */ + background-color: ${({backgroundStyle, backgroundColor}) => backgroundStyle !== 'hatched' ? backgroundColor : undefined }; + background-image: ${({backgroundStyle, backgroundColor}) => backgroundStyle === 'hatched' ? `linear-gradient(45deg, ${backgroundColor} 30%, #ffffff 30%, #ffffff 50%, ${backgroundColor} 50%, ${backgroundColor} 80%, #ffffff 80%, #ffffff 100%)` : undefined }; + background-size: ${({backgroundStyle}) => backgroundStyle === 'hatched' ? '7.07px 7.07px' : undefined }; + flex: 1; + height: ${({height}) => height ? height : undefined}; + left: ${space[0]}; + top: ${space[0]}; +`; -const Bar = styled.div<{ +interface BarProps { height?: number | string; minWidth?: string; color?: string; -}>((x) => - css({ - backgroundColor: x.color ? x.color : 'currentcolor', - height: x.height ?? '0.8em', - minWidth: x.minWidth, - zIndex: 3, - }) -); +} + +const Bar = styled.div` + background-color: ${({color}) => color ? color : 'currentcolor'}; + height: ${({height}) => height ?? '0.8em'}; + min-width: ${({minWidth}) => minWidth}; + transition: width .3s; + z-index: 3; +` diff --git a/packages/app/src/components/tables/components/percentage-bar-without-number.tsx b/packages/app/src/components/tables/components/percentage-bar-without-number.tsx index 4dda13f788..ddac4e6293 100644 --- a/packages/app/src/components/tables/components/percentage-bar-without-number.tsx +++ b/packages/app/src/components/tables/components/percentage-bar-without-number.tsx @@ -11,7 +11,7 @@ export const PercentageBarWithoutNumber = ({ color, percentage, marginBottom }: return ( - + ); diff --git a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx index 72e28962b1..0daf6644e9 100644 --- a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx @@ -1,229 +1,106 @@ import { colors, NlBehaviorPerAgeGroup } from '@corona-dashboard/common'; -import css from '@styled-system/css'; import React from 'react'; -import styled from 'styled-components'; -import { isPresent } from 'ts-is-present'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; -import { BoldText, Text } from '~/components/typography'; +import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; +import { NarrowTable } from '~/components/tables/narrow-table'; +import { WideTable } from '~/components/tables/wide-table'; +import { Text } from '~/components/typography'; +import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; -import { asResponsiveArray } from '~/style/utils'; import { keys } from '~/utils'; import { assert } from '~/utils/assert'; import { useBreakpoints } from '~/utils/use-breakpoints'; import { SelectBehavior } from './components/select-behavior'; import { BehaviorIdentifier } from './logic/behavior-types'; -const AGE_KEYS = ['70_plus', '55_69', '40_54', '25_39', '16_24'] as const; +// The data for behaviour age groups does not include birth year ranges, so this has been added manually +const AGE_KEYS_NEW = [ + {ageGroup: '70_plus', birthYearRange: '-1952'}, + {ageGroup: '55_69', birthYearRange: '1953-1967'}, + {ageGroup: '40_54', birthYearRange: '1968-1983'}, + {ageGroup: '25_39', birthYearRange: '1983-1998'}, + {ageGroup: '16_24', birthYearRange: '1998-2007'}, +] as const; interface BehaviorPerAgeGroupProps { title: string; description: string; - complianceExplanation: string; - supportExplanation: string; data: NlBehaviorPerAgeGroup; currentId: BehaviorIdentifier; setCurrentId: React.Dispatch>; text: Pick; } -export function BehaviorPerAgeGroup({ - title, - description, - data, - complianceExplanation, - supportExplanation, - currentId, - setCurrentId, - text, -}: BehaviorPerAgeGroupProps) { +export function BehaviorPerAgeGroup({ title, description, data, currentId, setCurrentId, text }: BehaviorPerAgeGroupProps) { const breakpoints = useBreakpoints(); + const { commonTexts, formatPercentage } = useIntl(); + const complianceValue = data[`${currentId}_compliance` as keyof typeof data] || undefined; + const supportValue = data[`${currentId}_support` as keyof typeof data] || undefined; - const complianceValue = - data[`${currentId}_compliance` as keyof typeof data] || undefined; - const supportValue = - data[`${currentId}_support` as keyof typeof data] || undefined; + assert(typeof complianceValue !== 'number', `[${BehaviorPerAgeGroup.name}] There is a problem by filtering the numbers out (complianceValue)`); + assert(typeof supportValue !== 'number', `[${BehaviorPerAgeGroup.name}] There is a problem by filtering the numbers out (supportValue)`); - assert( - typeof complianceValue !== 'number', - `[${BehaviorPerAgeGroup.name}] There is a problem by filtering the numbers out (complianceValue)` - ); - assert( - typeof supportValue !== 'number', - `[${BehaviorPerAgeGroup.name}] There is a problem by filtering the numbers out (supportValue)` - ); - - const hasComplianceValues = - complianceValue && - keys(complianceValue).every((key) => complianceValue[key] === null) === - false; - const hasSupportValues = - supportValue && - keys(supportValue).every((key) => supportValue[key] === null) === false; + const hasComplianceValues = complianceValue && keys(complianceValue).every((key) => complianceValue[key] === null) === false; + const hasSupportValues = supportValue && keys(supportValue).every((key) => supportValue[key] === null) === false; const dataAvailable = hasComplianceValues || hasSupportValues; + const requiredData = AGE_KEYS_NEW.map((age, index) => { + return { + id: `${age.ageGroup}-${index}`, + compliancePercentage: complianceValue?.[age.ageGroup], + supportPercentage: supportValue?.[age.ageGroup], + age_group_total: null, // Passing null as the dataset does not contain information about the total number of people in an age group. + age_group_range: text.shared.leeftijden.tabel[age.ageGroup], + birthyear_range: age.birthYearRange + } + }); + + const titles = { first: 'Coronaregel volgen', second: 'Coronaregel steunen' }; + const colorValues = { first: colors.blue6, second: colors.yellow3 }; + const percentageKeys = { + first: { propertyKey: 'compliancePercentage', shouldFormat: true }, + second: { propertyKey: 'supportPercentage', shouldFormat: true } + } + const percentageData = getPercentageData(requiredData, titles, colorValues, percentageKeys, undefined, commonTexts.common.no_data, formatPercentage) return ( - + - - {dataAvailable ? ( - - - - - - {text.shared.leeftijden.tabel.age_group} - - - {text.shared.leeftijden.tabel.recent_research} - - - - - {AGE_KEYS.map((age, index) => { - const ageValueCompliance = complianceValue?.[age]; - const ageValueSupport = supportValue?.[age]; - - if (!ageValueCompliance && !ageValueSupport) { - return null; - } - return ( - - {text.shared.leeftijden.tabel[age]} - - {ageValueCompliance ? ( - - ) : ( - - {text.shared.leeftijden.tabel.compliance_no_data} - - )} - {ageValueSupport ? ( - - ) : ( - - {text.shared.leeftijden.tabel.support_no_data} - - )} - - - ); - })} - - - - - - {complianceExplanation} - - - - {supportExplanation} - + + {dataAvailable ? + breakpoints.lg ? ( + + ) : ( + + ) : ( + + {text.shared.leeftijden.tabel.error} - - ) : ( - - - {text.shared.leeftijden.tabel.error} - - - )} + ) + } ); } - -interface PercentageBarProps { - amount: number | null; - color: string; -} - -function PercentageBar({ amount, color }: PercentageBarProps) { - if (!isPresent(amount)) { - return null; - } - - return ( - - {`${amount}%`} - - - - - ); -} - -const StyledTable = styled.table( - css({ - borderCollapse: 'collapse', - width: '100%', - mb: 4, - }) -); - -const HeaderCell = styled.th( - css({ - textAlign: 'left', - fontWeight: 'bold', - verticalAlign: 'middle', - }) -); - -const Cell = styled.td((x) => - css({ - color: x.color, - borderBottom: '1px solid', - borderBottomColor: 'gray2', - p: 0, - py: 2, - minHeight: 100, - verticalAlign: 'middle', - }) -); - -const ExplanationBox = styled.div<{ background: string }>((x) => - css({ - height: '17px', - width: '17px', - background: x.background, - float: 'left', - mt: '3px', - mr: 1, - borderRadius: '3px', - }) -); diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index d56d53ebc8..4424d08a27 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -52,9 +52,9 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu {breakpoints.lg ? ( diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index 8fb60f777a..3394eccc2f 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -20,6 +20,7 @@ interface Autumn2022ShotCoveragePerAgeGroupProps { } export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata, values, sortingOrder, text }: Autumn2022ShotCoveragePerAgeGroupProps) => { +console.log('values :', values); const breakpoints = useBreakpoints(true); const { formatPercentage } = useIntl(); const componentName = Autumn2022ShotCoveragePerAgeGroup.name; diff --git a/packages/app/src/domain/vaccine/components/age-group.tsx b/packages/app/src/domain/vaccine/components/age-group.tsx index 5a8227e754..3fa3fcee0f 100644 --- a/packages/app/src/domain/vaccine/components/age-group.tsx +++ b/packages/app/src/domain/vaccine/components/age-group.tsx @@ -9,12 +9,7 @@ interface AgeGroupProps { text: string; } -export function AgeGroup({ - range, - ageGroupTotal, - birthyear_range, - text, -}: AgeGroupProps) { +export function AgeGroup({ range, ageGroupTotal, birthyear_range, text }: AgeGroupProps) { const { formatNumber } = useIntl(); const totalText = replaceVariablesInText(text, { diff --git a/packages/app/src/pages/landelijk/gedrag.tsx b/packages/app/src/pages/landelijk/gedrag.tsx index bfc58de97c..8029d6d1cd 100644 --- a/packages/app/src/pages/landelijk/gedrag.tsx +++ b/packages/app/src/pages/landelijk/gedrag.tsx @@ -194,8 +194,6 @@ export default function BehaviorPage(props: StaticProps) Date: Fri, 20 Jan 2023 17:03:41 +0100 Subject: [PATCH 11/23] feat(table-improvements): Add new footers to behaviour page tables. --- .../src/components/tables/narrow-table.tsx | 88 ++++++++++--------- .../app/src/components/tables/wide-table.tsx | 42 +++++---- .../behavior/behavior-per-age-group-tile.tsx | 57 ++++++------ .../domain/behavior/behavior-table-tile.tsx | 60 ++++++++----- .../behavior/components/behavior-trend.tsx | 12 +-- ...utumn-2022-shot-coverage-per-age-group.tsx | 16 ++-- packages/app/src/pages/landelijk/gedrag.tsx | 14 ++- .../pages/veiligheidsregio/[code]/gedrag.tsx | 10 ++- 8 files changed, 164 insertions(+), 135 deletions(-) diff --git a/packages/app/src/components/tables/narrow-table.tsx b/packages/app/src/components/tables/narrow-table.tsx index ad8e10b1fa..385cd5b356 100644 --- a/packages/app/src/components/tables/narrow-table.tsx +++ b/packages/app/src/components/tables/narrow-table.tsx @@ -15,58 +15,64 @@ interface NarrowTableProps extends CommonTableProps { tableData: any[]; // TODO:AP - figure out how to properly type this. } -// Component shown for tables on narrow screens. +// Component shown for tables on narrow screens. export const NarrowTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percentageData, onClickConfig }: NarrowTableProps) => { const { commonTexts } = useIntl(); return (
- - - {headerText} - Mobile table - - + + + {headerText} + + - - {tableData.map((item, tableDataIndex) => ( - - - - {hasIcon && ( - <> - - - + + {tableData.map((item, tableDataIndex) => ( + + + + {hasIcon && ( + <> + + + - onClickConfig.handler(item.id, onClickConfig.scrollRef) : undefined}> - - {item.description} - - - - )} + onClickConfig.handler(item.id, onClickConfig.scrollRef) : undefined} + > + + {item.description} + + + + )} - {hasAgeGroups && ( - - )} - + {hasAgeGroups && ( + + )} + - - {percentageData.map((percentageDataPoints, percentageDataIndex) => ( + + {percentageData.map( + (percentageDataPoints, percentageDataIndex) => percentageDataIndex === tableDataIndex && - ))} - - - - ))} - -
+ )} +
+
+ + ))} + +
); }; diff --git a/packages/app/src/components/tables/wide-table.tsx b/packages/app/src/components/tables/wide-table.tsx index 06df29608e..bbfe25daa7 100644 --- a/packages/app/src/components/tables/wide-table.tsx +++ b/packages/app/src/components/tables/wide-table.tsx @@ -15,8 +15,8 @@ import { CommonTableProps } from './types'; export const tableColumnWidths = { labelColumn: '30%', percentageColumn: '20%', - percentageBarColumn: '30%' -} + percentageBarColumn: '30%', +}; interface WideTableProps extends CommonTableProps { headerText: { [key: string]: string }; // Covert this to an object @@ -32,9 +32,15 @@ export const WideTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percen - {headerText.firstColumn} - Desktop table - {headerText.secondColumn} - {headerText.thirdColumn} + + {headerText.firstColumn} + + + {headerText.secondColumn} + + + {headerText.thirdColumn} + {headerText.fourthColumn} @@ -43,7 +49,7 @@ export const WideTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percen {tableData.map((item, tableDataIndex) => ( - { hasIcon && ( + {hasIcon && ( @@ -57,20 +63,20 @@ export const WideTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percen )} - { hasAgeGroups && ( - - ) - } + {hasAgeGroups && ( + + )} - {percentageData.map((percentageDataPoints, percentageDataIndex) => ( - percentageDataIndex === tableDataIndex && - ))} + {percentageData.map( + (percentageDataPoints, percentageDataIndex) => + percentageDataIndex === tableDataIndex && + )} ))} diff --git a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx index 0daf6644e9..335ac307b8 100644 --- a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx @@ -2,6 +2,7 @@ import { colors, NlBehaviorPerAgeGroup } from '@corona-dashboard/common'; import React from 'react'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; +import { MetadataProps } from '~/components/metadata'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; import { WideTable } from '~/components/tables/wide-table'; @@ -16,11 +17,11 @@ import { BehaviorIdentifier } from './logic/behavior-types'; // The data for behaviour age groups does not include birth year ranges, so this has been added manually const AGE_KEYS_NEW = [ - {ageGroup: '70_plus', birthYearRange: '-1952'}, - {ageGroup: '55_69', birthYearRange: '1953-1967'}, - {ageGroup: '40_54', birthYearRange: '1968-1983'}, - {ageGroup: '25_39', birthYearRange: '1983-1998'}, - {ageGroup: '16_24', birthYearRange: '1998-2007'}, + { ageGroup: '70_plus', birthYearRange: '-1952' }, + { ageGroup: '55_69', birthYearRange: '1953-1967' }, + { ageGroup: '40_54', birthYearRange: '1968-1983' }, + { ageGroup: '25_39', birthYearRange: '1983-1998' }, + { ageGroup: '16_24', birthYearRange: '1998-2007' }, ] as const; interface BehaviorPerAgeGroupProps { @@ -30,9 +31,10 @@ interface BehaviorPerAgeGroupProps { currentId: BehaviorIdentifier; setCurrentId: React.Dispatch>; text: Pick; + metadata: MetadataProps; } -export function BehaviorPerAgeGroup({ title, description, data, currentId, setCurrentId, text }: BehaviorPerAgeGroupProps) { +export function BehaviorPerAgeGroup({ title, description, data, currentId, setCurrentId, text, metadata }: BehaviorPerAgeGroupProps) { const breakpoints = useBreakpoints(); const { commonTexts, formatPercentage } = useIntl(); const complianceValue = data[`${currentId}_compliance` as keyof typeof data] || undefined; @@ -51,54 +53,45 @@ export function BehaviorPerAgeGroup({ title, description, data, currentId, setCu supportPercentage: supportValue?.[age.ageGroup], age_group_total: null, // Passing null as the dataset does not contain information about the total number of people in an age group. age_group_range: text.shared.leeftijden.tabel[age.ageGroup], - birthyear_range: age.birthYearRange - } + birthyear_range: age.birthYearRange, + }; }); const titles = { first: 'Coronaregel volgen', second: 'Coronaregel steunen' }; const colorValues = { first: colors.blue6, second: colors.yellow3 }; - const percentageKeys = { + const percentageKeys = { first: { propertyKey: 'compliancePercentage', shouldFormat: true }, - second: { propertyKey: 'supportPercentage', shouldFormat: true } - } - const percentageData = getPercentageData(requiredData, titles, colorValues, percentageKeys, undefined, commonTexts.common.no_data, formatPercentage) + second: { propertyKey: 'supportPercentage', shouldFormat: true }, + }; + const percentageData = getPercentageData(requiredData, titles, colorValues, percentageKeys, undefined, commonTexts.common.no_data, formatPercentage); return ( - + - + - {dataAvailable ? + {dataAvailable ? ( breakpoints.lg ? ( - ) : ( - - ) : ( - - {text.shared.leeftijden.tabel.error} - + ) - } + ) : ( + + {text.shared.leeftijden.tabel.error} + + )} diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index 4424d08a27..9ba17d9d3b 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -4,6 +4,7 @@ import scrollIntoView from 'scroll-into-view-if-needed'; import { isDefined, isPresent } from 'ts-is-present'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; +import { MetadataProps } from '~/components/metadata'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; import { WideTable } from '~/components/tables/wide-table'; @@ -11,6 +12,7 @@ import { Text } from '~/components/typography'; import { SiteText } from '~/locale'; import { space } from '~/style/theme'; import { useBreakpoints } from '~/utils/use-breakpoints'; +import { BehaviorTrend } from './components/behavior-trend'; import { BehaviorIdentifier } from './logic/behavior-types'; import { useBehaviorLookupKeys } from './logic/use-behavior-lookup-keys'; @@ -24,38 +26,39 @@ interface BehaviorTableTileProps { setCurrentId: React.Dispatch>; scrollRef: { current: HTMLDivElement | null }; text: SiteText['pages']['behavior_page']['shared']; + metadata: MetadataProps; } -export function BehaviorTableTile({ title, description, value, annotation, setCurrentId, scrollRef, text }: BehaviorTableTileProps) { +export function BehaviorTableTile({ title, description, value, annotation, setCurrentId, scrollRef, text, metadata }: BehaviorTableTileProps) { const breakpoints = useBreakpoints(true); const behaviorsTableData = useBehaviorTableData(value as NlBehaviorValue); const titles = { first: 'Coronaregel volgen', second: 'Coronaregel steunen' }; const colorValues = { first: colors.blue6, second: colors.yellow3 }; - const percentageKeys = { + const percentageKeys = { first: { propertyKey: 'compliancePercentage', shouldFormat: false }, - second: { propertyKey: 'supportPercentage', shouldFormat: false } - } + second: { propertyKey: 'supportPercentage', shouldFormat: false }, + }; const trendDirectionKeys = { first: { propertyKey: 'complianceTrend' }, - second: { propertyKey: 'supportTrend' } - } + second: { propertyKey: 'supportTrend' }, + }; const percentageData = getPercentageData(behaviorsTableData, titles, colorValues, percentageKeys, trendDirectionKeys); - + const anchorButtonClickHandler = (id: BehaviorIdentifier, scrollRef: { current: HTMLDivElement | null }) => { scrollIntoView(scrollRef.current as Element); setCurrentId(id); }; - const onClickConfig = { handler: anchorButtonClickHandler, scrollRef: scrollRef } + const onClickConfig = { handler: anchorButtonClickHandler, scrollRef: scrollRef }; return ( - + {breakpoints.lg ? ( - ) : ( - + )} - - - {annotation} - + + + + + + Verschil met de vorige meting is lager + + + + + + + Verschil met de vorige meting is hoger + + + + + + + {annotation} + + ); } - function useBehaviorTableData(value: NlBehaviorValue) { const behaviorLookupKeys = useBehaviorLookupKeys(); diff --git a/packages/app/src/domain/behavior/components/behavior-trend.tsx b/packages/app/src/domain/behavior/components/behavior-trend.tsx index 3d91b53dd0..eb9080c54d 100644 --- a/packages/app/src/domain/behavior/components/behavior-trend.tsx +++ b/packages/app/src/domain/behavior/components/behavior-trend.tsx @@ -11,14 +11,14 @@ type TrendIcon = { }; interface BehaviorTrendProps { trend: BehaviorTrendType | null; - color?: string; text: string; + hasMarginRight?: boolean; } -export function BehaviorTrend({ trend, text }: BehaviorTrendProps) { +export function BehaviorTrend({ trend, text, hasMarginRight }: BehaviorTrendProps) { if (trend === 'up') { return ( - + {text} @@ -26,7 +26,7 @@ export function BehaviorTrend({ trend, text }: BehaviorTrendProps) { } if (trend === 'down') { return ( - + {text} @@ -40,6 +40,7 @@ export function BehaviorTrend({ trend, text }: BehaviorTrendProps) { interface TrendProps { color: string; + hasMarginRight: boolean; } const Trend = styled.span` @@ -49,7 +50,8 @@ const Trend = styled.span` color: ${({ color }) => color}; svg { - margin-left: ${space[1]}; + margin-left: ${({ hasMarginRight }) => (hasMarginRight ? undefined : space[1])}; + margin-right: ${({ hasMarginRight }) => (hasMarginRight ? space[1] : undefined)}; height: 12px; width: 12px; } diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index 3394eccc2f..3c1d30a983 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -20,7 +20,6 @@ interface Autumn2022ShotCoveragePerAgeGroupProps { } export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata, values, sortingOrder, text }: Autumn2022ShotCoveragePerAgeGroupProps) => { -console.log('values :', values); const breakpoints = useBreakpoints(true); const { formatPercentage } = useIntl(); const componentName = Autumn2022ShotCoveragePerAgeGroup.name; @@ -29,31 +28,26 @@ console.log('values :', values); const colors = { first: COLOR_AUTUMN_2022_SHOT, second: COLOR_FULLY_VACCINATED }; const percentageKeys = { first: { propertyKey: 'autumn_2022_vaccinated_percentage', shouldFormat: true }, - second: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true } - } + second: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true }, + }; const percentageData = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.no_data, formatPercentage); return ( {breakpoints.lg ? ( - ) : ( - + )} ); diff --git a/packages/app/src/pages/landelijk/gedrag.tsx b/packages/app/src/pages/landelijk/gedrag.tsx index 8029d6d1cd..1482a357b3 100644 --- a/packages/app/src/pages/landelijk/gedrag.tsx +++ b/packages/app/src/pages/landelijk/gedrag.tsx @@ -165,15 +165,20 @@ export default function BehaviorPage(props: StaticProps) @@ -198,6 +203,11 @@ export default function BehaviorPage(props: StaticProps) currentId={currentId} setCurrentId={setCurrentId} text={text} + metadata={{ + datumsText: textNl.datums, + date: data.behavior_per_age_group.date_end_unix, + source: textNl.bronnen.rivm, + }} /> )} diff --git a/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx b/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx index af9015f3df..998ff38329 100644 --- a/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx +++ b/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx @@ -56,7 +56,6 @@ export const getStaticProps = createGetStaticProps( export default function BehaviorPageVr(props: StaticProps) { const { pageText, lastGenerated, content, selectedVrData: data, vrName, chartBehaviorOptions } = props; - const { commonTexts, formatDateFromSeconds, formatNumber } = useIntl(); const { text } = useDynamicLokalizeTexts(pageText, selectLokalizeTexts); @@ -115,15 +114,20 @@ export default function BehaviorPageVr(props: StaticProps From 204522ea2de589cf136aa4c883a8d4815a717d76 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Fri, 20 Jan 2023 18:15:30 +0100 Subject: [PATCH 12/23] feat(table-improvements): Delete now unused duplicated components --- .../components/narrow-coverage-table.tsx | 64 ------- .../components/wide-coverage-table.tsx | 112 ------------ .../components/narrow-coverage-table.tsx | 87 --------- .../components/wide-coverage-table.tsx | 173 ------------------ .../components/narrow-coverage-table.tsx | 77 -------- .../components/wide-coverage-table.tsx | 163 ----------------- 6 files changed, 676 deletions(-) delete mode 100644 packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx delete mode 100644 packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx delete mode 100644 packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/narrow-coverage-table.tsx delete mode 100644 packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/wide-coverage-table.tsx delete mode 100644 packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/narrow-coverage-table.tsx delete mode 100644 packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table.tsx diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx deleted file mode 100644 index 13ef6af257..0000000000 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/narrow-coverage-table.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { Bar } from '~/domain/vaccine/components/bar'; -import { BoldText } from '~/components/typography'; -import { Box, Spacer } from '~/components/base'; -import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; -import { fontSizes } from '~/style/theme'; -import { formatAgeGroupString } from '~/utils/format-age-group-string'; -import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { NarrowPercentage } from '~/domain/vaccine/components/narrow-percentage'; -import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; -import { SiteText } from '~/locale'; -import { useIntl } from '~/intl'; -import styled from 'styled-components'; - -interface NarrowCoverageTableProps { - text: SiteText['pages']['vaccinations_page']['nl']['vaccination_coverage']; - values: NlVaccineCoveragePerAgeGroupValue[]; -} - -// TODO:AP - delete before merging branch -export const NarrowCoverageTable = ({ values, text }: NarrowCoverageTableProps) => { - const { commonTexts, formatPercentage } = useIntl(); - - return ( - - - {text.headers.agegroup} - - - {values.map((item, index) => ( - - - - - - - - - - - - - - - - - - ))} - - ); -}; - -const StyledBoldText = styled(BoldText)` - font-size: ${fontSizes[2]}; -`; diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx deleted file mode 100644 index a21d923b26..0000000000 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/components/wide-coverage-table.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { Bar } from '~/domain/vaccine/components/bar'; -import { Box } from '~/components/base'; -import { COLOR_FULLY_VACCINATED, COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; -import { fontWeights, space, fontSizes } from '~/style/theme'; -import { formatAgeGroupString } from '~/utils/format-age-group-string'; -import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { InlineText } from '~/components/typography'; -import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; -import { SiteText } from '~/locale'; -import { useIntl } from '~/intl'; -import { WidePercentage } from '~/domain/vaccine/components/wide-percentage'; -import styled from 'styled-components'; - -interface WideCoverageTableProps { - text: SiteText['pages']['vaccinations_page']['nl']['vaccination_coverage']; - values: NlVaccineCoveragePerAgeGroupValue[]; -} - -// TODO:AP - Delete before merging -export const WideCoverageTable = ({ values, text }: WideCoverageTableProps) => { - const { commonTexts, formatPercentage } = useIntl(); - - return ( - - - - - - {text.headers.agegroup} - - - {text.headers.autumn_2022_shot} - - - {text.headers.fully_vaccinated} - - - - - - - {values.map((item, index) => ( - - - - - - - - - - - - - - - - - - ))} - - - - ); -}; - -const StyledTable = styled.table` - border-collapse: collapse; - width: 100%; -`; - -const Row = styled.tr` - border-bottom: 1px solid silver; -`; -interface HeaderCellProps { - isColumn?: boolean; - hasPaddingRight?: boolean; - width?: string; -} - -const HeaderCell = styled.th` - font-weight: ${({ isColumn }) => (isColumn ? fontWeights.normal : fontWeights.bold)}; - padding-block: ${({ isColumn }) => (isColumn ? space[3] : undefined)}; - padding-bottom: ${({ isColumn }) => (isColumn ? undefined : space[2])}; - padding-right: ${({ hasPaddingRight }) => (hasPaddingRight ? space[3] : undefined)}; - text-align: left; - vertical-align: middle; - width: ${({ width }) => (width ? width : undefined)}; - - > span { - font-size: ${fontSizes[2]}; - } -`; - -const Cell = styled.td` - padding-block: ${space[3]}; - vertical-align: middle; -`; - -const TableHead = styled.thead` - border-bottom: 1px solid silver; -`; diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/narrow-coverage-table.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/narrow-coverage-table.tsx deleted file mode 100644 index c957312395..0000000000 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/narrow-coverage-table.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { Box, Spacer } from '~/components/base'; -import { BoldText } from '~/components/typography'; -import { useIntl } from '~/intl'; -import { formatAgeGroupString } from '~/utils/format-age-group-string'; -import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { useVaccineCoveragePercentageFormatter } from '~/domain/vaccine/logic/use-vaccine-coverage-percentage-formatter'; -import { COLOR_FULLY_VACCINATED, COLOR_FULLY_BOOSTERED } from '~/domain/vaccine/common'; -import { Bar } from '~/domain/vaccine/components/bar'; -import { NarrowPercentage } from '~/domain/vaccine/components/narrow-percentage'; -import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { - NlVaccineCoveragePerAgeGroupArchived_20220908Value, - VrVaccineCoveragePerAgeGroupArchived_20220908Value, - GmVaccineCoveragePerAgeGroupArchived_20220908Value, -} from '@corona-dashboard/common'; -import { SiteText } from '~/locale'; - -// TODO:AP - delete before merging branch -export function NarrowCoverageTable({ - values, - text, -}: { - text: SiteText['pages']['vaccinations_page']['nl']; - values: NlVaccineCoveragePerAgeGroupArchived_20220908Value[] | VrVaccineCoveragePerAgeGroupArchived_20220908Value[] | GmVaccineCoveragePerAgeGroupArchived_20220908Value[]; -}) { - const { commonTexts, formatPercentage } = useIntl(); - const formatCoveragePercentage = useVaccineCoveragePercentageFormatter(); - - return ( - - - {text.vaccination_coverage.headers.agegroup} - - - {values.map((item, index) => ( - - - - - - - - - - - - - - - - - - ))} - - ); -} diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/wide-coverage-table.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/wide-coverage-table.tsx deleted file mode 100644 index 54041c9069..0000000000 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/components/wide-coverage-table.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import { - NlVaccineCoveragePerAgeGroupArchived_20220908Value, - VrVaccineCoveragePerAgeGroupArchived_20220908Value, - GmVaccineCoveragePerAgeGroupArchived_20220908Value, -} from '@corona-dashboard/common'; -import css from '@styled-system/css'; -import styled from 'styled-components'; -import { Box } from '~/components/base'; -import { InlineText } from '~/components/typography'; -import { useIntl } from '~/intl'; -import { asResponsiveArray } from '~/style/utils'; -import { formatAgeGroupString } from '~/utils/format-age-group-string'; -import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { useVaccineCoveragePercentageFormatter } from '~/domain/vaccine/logic/use-vaccine-coverage-percentage-formatter'; -import { COLOR_FULLY_VACCINATED, COLOR_FULLY_BOOSTERED } from '~/domain/vaccine/common'; -import { Bar } from '~/domain/vaccine/components/bar'; -import { WidePercentage } from '~/domain/vaccine/components/wide-percentage'; -import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { SiteText } from '~/locale'; -interface WideCoverageTable { - text: SiteText['pages']['vaccinations_page']['nl']; - values: NlVaccineCoveragePerAgeGroupArchived_20220908Value[] | VrVaccineCoveragePerAgeGroupArchived_20220908Value[] | GmVaccineCoveragePerAgeGroupArchived_20220908Value[]; -} - -// TODO:AP - delete before merging -export function WideCoverageTable({ values, text }: WideCoverageTable) { - const { commonTexts, formatPercentage } = useIntl(); - const formatCoveragePercentage = useVaccineCoveragePercentageFormatter(); - - return ( - - - - - - {text.vaccination_coverage.headers.agegroup} - - - {text.vaccination_coverage.headers.fully_vaccinated} - - - {text.archived.vaccination_coverage.campaign_headers.booster_shot} - - - {text.archived.vaccination_coverage.campaign_headers.difference_booster_shot_and_fully_vaccinated} - - - - - {values.map((item, index) => ( - - - - - - - - - - - - - - - - - - ))} - - - - ); -} - -const StyledTable = styled.table( - css({ - borderCollapse: 'collapse', - width: '100%', - }) -); - -const Row = styled.tr( - css({ - borderBottom: '1px solid', - borderColor: 'gray3', - }) -); - -const HeaderCell = styled.th<{ isColumn?: boolean }>((x) => - css({ - textAlign: 'left', - fontWeight: x.isColumn ? 'normal' : 'bold', - verticalAlign: 'middle', - pb: x.isColumn ? undefined : 2, - py: x.isColumn ? 3 : undefined, - }) -); - -const Cell = styled.td( - css({ - py: 3, - verticalAlign: 'middle', - }) -); diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/narrow-coverage-table.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/narrow-coverage-table.tsx deleted file mode 100644 index 76483292db..0000000000 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/narrow-coverage-table.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { Box, Spacer } from '~/components/base'; -import { BoldText } from '~/components/typography'; -import { useIntl } from '~/intl'; -import { formatAgeGroupString } from '~/utils/format-age-group-string'; -import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { useVaccineCoveragePercentageFormatter } from '~/domain/vaccine/logic/use-vaccine-coverage-percentage-formatter'; -import { ARCHIVED_COLORS } from '~/domain/vaccine/common'; -import { Bar } from '~/domain/vaccine/components/bar'; -import { NarrowPercentage } from '~/domain/vaccine/components/narrow-percentage'; -import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { GmVaccineCoveragePerAgeGroupArchivedValue, NlVaccineCoveragePerAgeGroupArchivedValue, VrVaccineCoveragePerAgeGroupArchivedValue } from '@corona-dashboard/common'; -import { SiteText } from '~/locale'; - -// TODO:AP - delete before merging branch -export function NarrowCoverageTable({ - values, - text, -}: { - text: SiteText['pages']['vaccinations_page']['nl']; - values: NlVaccineCoveragePerAgeGroupArchivedValue[] | VrVaccineCoveragePerAgeGroupArchivedValue[] | GmVaccineCoveragePerAgeGroupArchivedValue[]; -}) { - const { commonTexts, formatPercentage } = useIntl(); - const formatCoveragePercentage = useVaccineCoveragePercentageFormatter(); - - return ( - - - {text.vaccination_coverage.headers.agegroup} - - - {values.map((item, index) => ( - - - - - - - - - - - - - - - - - - ))} - - ); -} diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table.tsx deleted file mode 100644 index b4d80fd1e0..0000000000 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/components/wide-coverage-table.tsx +++ /dev/null @@ -1,163 +0,0 @@ -import { GmVaccineCoveragePerAgeGroupArchivedValue, NlVaccineCoveragePerAgeGroupArchivedValue, VrVaccineCoveragePerAgeGroupArchivedValue } from '@corona-dashboard/common'; -import css from '@styled-system/css'; -import styled from 'styled-components'; -import { Box } from '~/components/base'; -import { InlineText } from '~/components/typography'; -import { useIntl } from '~/intl'; -import { asResponsiveArray } from '~/style/utils'; -import { formatAgeGroupString } from '~/utils/format-age-group-string'; -import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; -import { useVaccineCoveragePercentageFormatter } from '~/domain/vaccine/logic/use-vaccine-coverage-percentage-formatter'; -import { ARCHIVED_COLORS } from '~/domain/vaccine/common'; -import { Bar } from '~/domain/vaccine/components/bar'; -import { WidePercentage } from '~/domain/vaccine/components/wide-percentage'; -import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { SiteText } from '~/locale'; -interface WideCoverageTable { - text: SiteText['pages']['vaccinations_page']['nl']; - values: NlVaccineCoveragePerAgeGroupArchivedValue[] | VrVaccineCoveragePerAgeGroupArchivedValue[] | GmVaccineCoveragePerAgeGroupArchivedValue[]; -} - -// TODO:AP - delete before merging -export function WideCoverageTable({ values, text }: WideCoverageTable) { - const { commonTexts, formatPercentage } = useIntl(); - const formatCoveragePercentage = useVaccineCoveragePercentageFormatter(); - - return ( - - - - - - {text.vaccination_coverage.headers.agegroup} - - - {text.archived.vaccination_coverage.campaign_headers.first_shot} - - - {text.archived.vaccination_coverage.campaign_headers.coverage} - - - {text.archived.vaccination_coverage.campaign_headers.difference} - - - - - {values.map((item, index) => ( - - - - - - - - - - - - - - - - - - ))} - - - - ); -} - -const StyledTable = styled.table( - css({ - borderCollapse: 'collapse', - width: '100%', - }) -); - -const Row = styled.tr( - css({ - borderBottom: '1px solid', - borderColor: 'gray3', - }) -); - -const HeaderCell = styled.th<{ isColumn?: boolean }>((x) => - css({ - textAlign: 'left', - fontWeight: x.isColumn ? 'normal' : 'bold', - verticalAlign: 'middle', - pb: x.isColumn ? undefined : 2, - py: x.isColumn ? 3 : undefined, - }) -); - -const Cell = styled.td( - css({ - py: 3, - verticalAlign: 'middle', - }) -); From 60475b570830ec025a93b08e4e0a0f0cf583e3b7 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Fri, 20 Jan 2023 19:38:45 +0100 Subject: [PATCH 13/23] feat(table-improvements): Final touches - creating sanity keys, typing, refactoring, etc. --- .../components/desktop-percentage-data.tsx | 13 ++--- .../components/mobile-percentage-data.tsx | 32 ++++++------ .../tables/logic/get-percentage-data.ts | 38 +++++++------- .../src/components/tables/narrow-table.tsx | 10 ++-- packages/app/src/components/tables/types.ts | 16 +++++- .../app/src/components/tables/wide-table.tsx | 12 ++--- .../behavior/behavior-per-age-group-tile.tsx | 23 ++++----- .../domain/behavior/behavior-table-tile.tsx | 24 ++++----- .../behavior/components/behavior-trend.tsx | 4 ++ ...utumn-2022-shot-coverage-per-age-group.tsx | 26 ++++++---- .../booster-shot-coverage-per-age-group.tsx | 49 ++++++++++--------- .../vaccine-coverage-per-age-group.tsx | 41 ++++++++-------- packages/cms/src/lokalize/key-mutations.csv | 10 ++++ 13 files changed, 164 insertions(+), 134 deletions(-) diff --git a/packages/app/src/components/tables/components/desktop-percentage-data.tsx b/packages/app/src/components/tables/components/desktop-percentage-data.tsx index c8cab5d8f6..b13e4f555a 100644 --- a/packages/app/src/components/tables/components/desktop-percentage-data.tsx +++ b/packages/app/src/components/tables/components/desktop-percentage-data.tsx @@ -1,4 +1,3 @@ -import { colors } from '@corona-dashboard/common'; import { Box } from '~/components/base'; import { BehaviorTrend } from '~/domain/behavior/components/behavior-trend'; import { WidePercentage } from '~/domain/vaccine/components/wide-percentage'; @@ -20,8 +19,10 @@ export const PercentageData = ({ percentageDataPoints }: PercentageDataProps) => - ) : percentageDataPoint.percentage.value + + ) : ( + percentageDataPoint.percentage.value + ) } color={percentageDataPoint.percentage.color} justifyContent="flex-start" @@ -32,9 +33,9 @@ export const PercentageData = ({ percentageDataPoints }: PercentageDataProps) => {percentageDataPoints.map((percentageDataPoint, index) => ( - diff --git a/packages/app/src/components/tables/components/mobile-percentage-data.tsx b/packages/app/src/components/tables/components/mobile-percentage-data.tsx index 9c793e9dcf..ed053bec77 100644 --- a/packages/app/src/components/tables/components/mobile-percentage-data.tsx +++ b/packages/app/src/components/tables/components/mobile-percentage-data.tsx @@ -1,16 +1,15 @@ -import { colors } from "@corona-dashboard/common" -import { Box } from "~/components/base" -import { BehaviorTrend } from "~/domain/behavior/components/behavior-trend" -import { NarrowPercentage } from "~/domain/vaccine/components/narrow-percentage" -import { space } from "~/style/theme" -import { PercentageDataPoint } from "../types" -import { PercentageBarWithoutNumber } from "./percentage-bar-without-number" +import { Box } from '~/components/base'; +import { BehaviorTrend } from '~/domain/behavior/components/behavior-trend'; +import { NarrowPercentage } from '~/domain/vaccine/components/narrow-percentage'; +import { space } from '~/style/theme'; +import { PercentageDataPoint } from '../types'; +import { PercentageBarWithoutNumber } from './percentage-bar-without-number'; interface PercentageDataProps { percentageDataPoints: PercentageDataPoint[]; } -export const PercentageData = ({percentageDataPoints}: PercentageDataProps) => { +export const PercentageData = ({ percentageDataPoints }: PercentageDataProps) => { return ( <> {percentageDataPoints.map((percentageDataPoint, index) => ( @@ -19,18 +18,23 @@ export const PercentageData = ({percentageDataPoints}: PercentageDataProps) => { - ) : percentageDataPoint.percentage.value + + ) : ( + percentageDataPoint.percentage.value + ) } color={percentageDataPoint.percentage.color} textLabel={percentageDataPoint.title} /> - + {/* In some cases, the percentage value is a string so it needs to be parsed for the progress bar to be filled properly. */} - + ))} - ) -} \ No newline at end of file + ); +}; diff --git a/packages/app/src/components/tables/logic/get-percentage-data.ts b/packages/app/src/components/tables/logic/get-percentage-data.ts index fd1b9918f6..590bb11b4f 100644 --- a/packages/app/src/components/tables/logic/get-percentage-data.ts +++ b/packages/app/src/components/tables/logic/get-percentage-data.ts @@ -1,46 +1,44 @@ -import { createFormatting } from "@corona-dashboard/common"; -import { PercentageDataPoint } from "../types"; +import { createFormatting } from '@corona-dashboard/common'; +import { PercentageDataPoint } from '../types'; -type percentageParam = { propertyKey: string, shouldFormat?: boolean }; -type percentageParams = { first: percentageParam, second: percentageParam }; -type trendDirectionParams = { first: percentageParam, second: percentageParam }; -type colorParam = { first: string, second: string }; -type titleParam = { first: string, second: string }; +type FormatParam = { shouldFormat?: boolean }; +type PercentageFormattingParams = { first: FormatParam; second: FormatParam }; +type TrendDirectionParams = { first: string; second: string }; +type ColorParam = { first: string; second: string }; +type TitleParam = { first: string; second: string }; // Returns an array of objects corresponding to percentage data used by tables on the dashboard export const getPercentageData = ( dataset: any[], // TODO:AP - figure out how to properly type this - title: titleParam, - color: colorParam, - percentageKeys: percentageParams, - trendDirection?: trendDirectionParams, + title: TitleParam, + color: ColorParam, + percentageFormattingRules: PercentageFormattingParams, + trendDirection?: TrendDirectionParams, noDataText?: string, formatPercentage?: ReturnType['formatPercentage'] ): PercentageDataPoint[][] => { - const getPercentageValue = (datasetItem: any, percentageItem: percentageParam) => { + const getFormattedPercentageValue = (percentage: number | null) => { if (formatPercentage === undefined) return; - return typeof percentageItem !== 'number' && datasetItem[percentageItem.propertyKey] !== null - ? `${formatPercentage(datasetItem[percentageItem.propertyKey])}%` - : noDataText; - } + return percentage !== null ? `${formatPercentage(percentage)}%` : noDataText; + }; return dataset.map((datasetItem) => { return [ { title: title.first, - trendDirection: trendDirection?.first.propertyKey !== undefined && trendDirection.first.propertyKey in datasetItem ? datasetItem[trendDirection.first.propertyKey] : null, + trendDirection: trendDirection?.first !== undefined && trendDirection.first in datasetItem ? datasetItem[trendDirection.first] : null, percentage: { color: color.first, - value: percentageKeys.first.shouldFormat ? getPercentageValue(datasetItem, percentageKeys.first) : datasetItem[percentageKeys.first.propertyKey], + value: percentageFormattingRules.first.shouldFormat ? getFormattedPercentageValue(datasetItem.firstPercentage) : datasetItem.firstPercentage, }, }, { title: title.second, - trendDirection: trendDirection?.second.propertyKey !== undefined && trendDirection.second.propertyKey in datasetItem ? datasetItem[trendDirection.second.propertyKey] : null, + trendDirection: trendDirection?.second !== undefined && trendDirection.second in datasetItem ? datasetItem[trendDirection.second] : null, percentage: { color: color.second, - value: percentageKeys.second.shouldFormat ? getPercentageValue(datasetItem, percentageKeys.second) : datasetItem[percentageKeys.second.propertyKey], + value: percentageFormattingRules.second.shouldFormat ? getFormattedPercentageValue(datasetItem.secondPercentage) : datasetItem.secondPercentage, }, }, ]; diff --git a/packages/app/src/components/tables/narrow-table.tsx b/packages/app/src/components/tables/narrow-table.tsx index 385cd5b356..496bde1c30 100644 --- a/packages/app/src/components/tables/narrow-table.tsx +++ b/packages/app/src/components/tables/narrow-table.tsx @@ -12,7 +12,7 @@ import { CommonTableProps } from './types'; interface NarrowTableProps extends CommonTableProps { headerText: string; - tableData: any[]; // TODO:AP - figure out how to properly type this. + tableData: any[]; // TODO:AP - figure out how to properly type this } // Component shown for tables on narrow screens. @@ -52,11 +52,11 @@ export const NarrowTable = ({ tableData, headerText, hasAgeGroups, hasIcon, perc )} - {hasAgeGroups && ( + {hasAgeGroups && item?.ageGroupRange && item?.birthYearRange && ( )} diff --git a/packages/app/src/components/tables/types.ts b/packages/app/src/components/tables/types.ts index d2e2c16bd1..2a2e8ffaa7 100644 --- a/packages/app/src/components/tables/types.ts +++ b/packages/app/src/components/tables/types.ts @@ -1,4 +1,4 @@ -import { BehaviorIdentifier } from "~/domain/behavior/logic/behavior-types"; +import { BehaviorIdentifier, BehaviorTrendType } from '~/domain/behavior/logic/behavior-types'; export type PercentageDataPoint = { title: string; @@ -16,7 +16,19 @@ export interface CommonTableProps { hasAgeGroups?: boolean; hasIcon?: boolean; onClickConfig?: { - handler: (id: BehaviorIdentifier, scrollRef: ScrollRef) => void, + handler: (id: BehaviorIdentifier, scrollRef: ScrollRef) => void; scrollRef: ScrollRef; }; } + +export interface TableData { + id: string; + firstPercentage: number | string; + secondPercentage: number | string; + description?: string; + complianceTrend?: BehaviorTrendType | null; + supportTrend?: BehaviorTrendType | null; + ageGroupTotal?: number; + ageGroupRange?: string; + birthYearRange?: string; +} diff --git a/packages/app/src/components/tables/wide-table.tsx b/packages/app/src/components/tables/wide-table.tsx index bbfe25daa7..7742ffc82c 100644 --- a/packages/app/src/components/tables/wide-table.tsx +++ b/packages/app/src/components/tables/wide-table.tsx @@ -19,8 +19,8 @@ export const tableColumnWidths = { }; interface WideTableProps extends CommonTableProps { - headerText: { [key: string]: string }; // Covert this to an object - tableData: any[]; // TODO:AP - figure out how to properly type this. Create an interface for it which requires only the data actually used in this component. + headerText: { [key: string]: string }; + tableData: any[]; // TODO:AP - figure out how to properly type this } // Component shown for tables on wide screens. @@ -63,12 +63,12 @@ export const WideTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percen )} - {hasAgeGroups && ( + {hasAgeGroups && item?.ageGroupRange && item?.birthYearRange && ( )} diff --git a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx index 335ac307b8..067c187440 100644 --- a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx @@ -49,21 +49,18 @@ export function BehaviorPerAgeGroup({ title, description, data, currentId, setCu const requiredData = AGE_KEYS_NEW.map((age, index) => { return { id: `${age.ageGroup}-${index}`, - compliancePercentage: complianceValue?.[age.ageGroup], - supportPercentage: supportValue?.[age.ageGroup], - age_group_total: null, // Passing null as the dataset does not contain information about the total number of people in an age group. - age_group_range: text.shared.leeftijden.tabel[age.ageGroup], - birthyear_range: age.birthYearRange, + firstPercentage: complianceValue?.[age.ageGroup], + secondPercentage: supportValue?.[age.ageGroup], + ageGroupTotal: null, // Passing null as the dataset does not contain information about the total number of people in an age group. + ageGroupRange: text.shared.leeftijden.tabel[age.ageGroup], + birthYearRange: age.birthYearRange, }; }); - const titles = { first: 'Coronaregel volgen', second: 'Coronaregel steunen' }; + const titles = { first: text.shared.basisregels.rules_followed, second: text.shared.basisregels.rules_supported }; const colorValues = { first: colors.blue6, second: colors.yellow3 }; - const percentageKeys = { - first: { propertyKey: 'compliancePercentage', shouldFormat: true }, - second: { propertyKey: 'supportPercentage', shouldFormat: true }, - }; - const percentageData = getPercentageData(requiredData, titles, colorValues, percentageKeys, undefined, commonTexts.common.no_data, formatPercentage); + const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; + const percentageData = getPercentageData(requiredData, titles, colorValues, percentageFormattingRules, undefined, commonTexts.common.no_data, formatPercentage); return ( @@ -76,8 +73,8 @@ export function BehaviorPerAgeGroup({ title, description, data, currentId, setCu { scrollIntoView(scrollRef.current as Element); @@ -56,8 +50,8 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu (b.compliancePercentage ?? 0) - (a.compliancePercentage ?? 0)); + .sort((a, b) => (b.firstPercentage ?? 0) - (a.firstPercentage ?? 0)); }, [value, behaviorLookupKeys]); } diff --git a/packages/app/src/domain/behavior/components/behavior-trend.tsx b/packages/app/src/domain/behavior/components/behavior-trend.tsx index eb9080c54d..a5b9d213a6 100644 --- a/packages/app/src/domain/behavior/components/behavior-trend.tsx +++ b/packages/app/src/domain/behavior/components/behavior-trend.tsx @@ -9,6 +9,7 @@ type TrendIcon = { direction: 'UP' | 'DOWN' | ' NEUTRAL'; color: string; }; + interface BehaviorTrendProps { trend: BehaviorTrendType | null; text: string; @@ -24,6 +25,7 @@ export function BehaviorTrend({ trend, text, hasMarginRight }: BehaviorTrendProp ); } + if (trend === 'down') { return ( @@ -32,9 +34,11 @@ export function BehaviorTrend({ trend, text, hasMarginRight }: BehaviorTrendProp ); } + if (trend === 'equal') { return {text}; } + return ; } diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index 3c1d30a983..6b04c19749 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -21,16 +21,24 @@ interface Autumn2022ShotCoveragePerAgeGroupProps { export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata, values, sortingOrder, text }: Autumn2022ShotCoveragePerAgeGroupProps) => { const breakpoints = useBreakpoints(true); - const { formatPercentage } = useIntl(); + const { commonTexts, formatPercentage } = useIntl(); const componentName = Autumn2022ShotCoveragePerAgeGroup.name; - const sortedValues = values.sort((a, b) => getSortingOrder(a.age_group_range, sortingOrder, componentName) - getSortingOrder(b.age_group_range, sortingOrder, componentName)); + const requiredData = values.map((value) => { + return { + id: value.age_group_range, + ageGroupTotal: 'age_group_total' in value ? value.age_group_total : undefined, + ageGroupRange: value.age_group_range, + birthYearRange: value.birthyear_range, + firstPercentage: value.autumn_2022_vaccinated_percentage, + secondPercentage: value.fully_vaccinated_percentage, + }; + }); + + const sortedData = requiredData.sort((a, b) => getSortingOrder(a.ageGroupRange, sortingOrder, componentName) - getSortingOrder(b.ageGroupRange, sortingOrder, componentName)); const titles = { first: text.headers.autumn_2022_shot, second: text.headers.fully_vaccinated }; const colors = { first: COLOR_AUTUMN_2022_SHOT, second: COLOR_FULLY_VACCINATED }; - const percentageKeys = { - first: { propertyKey: 'autumn_2022_vaccinated_percentage', shouldFormat: true }, - second: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true }, - }; - const percentageData = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.no_data, formatPercentage); + const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; + const percentageData = getPercentageData(sortedData, titles, colors, percentageFormattingRules, undefined, commonTexts.common.no_data, formatPercentage); return ( @@ -42,12 +50,12 @@ export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata thirdColumn: text.headers.fully_vaccinated, fourthColumn: '', }} - tableData={sortedValues} + tableData={sortedData} percentageData={percentageData} hasAgeGroups /> ) : ( - + )} ); diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx index e76ee2be81..db71bc4cae 100644 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx @@ -1,4 +1,8 @@ -import { GmVaccineCoveragePerAgeGroupArchived_20220908Value, NlVaccineCoveragePerAgeGroupArchived_20220908Value, VrVaccineCoveragePerAgeGroupArchived_20220908Value } from '@corona-dashboard/common'; +import { + GmVaccineCoveragePerAgeGroupArchived_20220908Value, + NlVaccineCoveragePerAgeGroupArchived_20220908Value, + VrVaccineCoveragePerAgeGroupArchived_20220908Value, +} from '@corona-dashboard/common'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; @@ -15,47 +19,46 @@ interface BoosterCoveragePerAgeGroupProps { description: string; metadata: MetadataProps; sortingOrder: string[]; - values: - | NlVaccineCoveragePerAgeGroupArchived_20220908Value[] - | VrVaccineCoveragePerAgeGroupArchived_20220908Value[] - | GmVaccineCoveragePerAgeGroupArchived_20220908Value[]; + values: NlVaccineCoveragePerAgeGroupArchived_20220908Value[] | VrVaccineCoveragePerAgeGroupArchived_20220908Value[] | GmVaccineCoveragePerAgeGroupArchived_20220908Value[]; text: SiteText['pages']['vaccinations_page']['nl']; } -export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text}: BoosterCoveragePerAgeGroupProps) { +export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text }: BoosterCoveragePerAgeGroupProps) { const breakpoints = useBreakpoints(true); - const { formatPercentage } = useIntl(); + const { commonTexts, formatPercentage } = useIntl(); const componentName = BoosterShotCoveragePerAgeGroup.name; - const sortedValues = values.sort((a, b) => getSortingOrder(a.age_group_range, sortingOrder, componentName) - getSortingOrder(b.age_group_range, sortingOrder, componentName)); + const requiredData = values.map((value) => { + return { + id: value.age_group_range, + ageGroupTotal: 'age_group_total' in value ? value.age_group_total : undefined, + ageGroupRange: value.age_group_range, + birthYearRange: value.birthyear_range, + firstPercentage: value.fully_vaccinated_percentage, + secondPercentage: value.booster_shot_percentage, + }; + }); + const sortedData = requiredData.sort((a, b) => getSortingOrder(a.ageGroupRange, sortingOrder, componentName) - getSortingOrder(b.ageGroupRange, sortingOrder, componentName)); const titles = { first: text.vaccination_coverage.headers.fully_vaccinated, second: text.archived.vaccination_coverage.campaign_headers.booster_shot }; - const colors = { first: COLOR_FULLY_VACCINATED, second: COLOR_FULLY_BOOSTERED}; - const percentageKeys = { - first: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true}, - second: { propertyKey: 'booster_shot_percentage', shouldFormat: true} - }; - const percentageData = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.vaccination_coverage.no_data, formatPercentage); + const colors = { first: COLOR_FULLY_VACCINATED, second: COLOR_FULLY_BOOSTERED }; + const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; + const percentageData = getPercentageData(sortedData, titles, colors, percentageFormattingRules, undefined, commonTexts.common.no_data, formatPercentage); return ( {breakpoints.lg ? ( - ) : ( - + )} ); diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx index 8670f57e27..6d7d3da014 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx @@ -15,47 +15,46 @@ interface VaccineCoveragePerAgeGroupProps { description: string; metadata: MetadataProps; sortingOrder: string[]; - values: - | NlVaccineCoveragePerAgeGroupArchivedValue[] - | VrVaccineCoveragePerAgeGroupArchivedValue[] - | GmVaccineCoveragePerAgeGroupArchivedValue[]; + values: NlVaccineCoveragePerAgeGroupArchivedValue[] | VrVaccineCoveragePerAgeGroupArchivedValue[] | GmVaccineCoveragePerAgeGroupArchivedValue[]; text: SiteText['pages']['vaccinations_page']['nl']; } -export function VaccineCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text}: VaccineCoveragePerAgeGroupProps) { +export function VaccineCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text }: VaccineCoveragePerAgeGroupProps) { const breakpoints = useBreakpoints(true); - const { formatPercentage } = useIntl(); + const { commonTexts, formatPercentage } = useIntl(); const componentName = VaccineCoveragePerAgeGroup.name; - const sortedValues = values.sort((a, b) => getSortingOrder(a.age_group_range, sortingOrder, componentName) - getSortingOrder(b.age_group_range, sortingOrder, componentName)); + const requiredData = values.map((value) => { + return { + id: value.age_group_range, + ageGroupTotal: 'age_group_total' in value ? value.age_group_total : undefined, + ageGroupRange: value.age_group_range, + birthYearRange: value.birthyear_range, + firstPercentage: value.has_one_shot_percentage, + secondPercentage: value.fully_vaccinated_percentage, + }; + }); + const sortedData = requiredData.sort((a, b) => getSortingOrder(a.ageGroupRange, sortingOrder, componentName) - getSortingOrder(b.ageGroupRange, sortingOrder, componentName)); const titles = { first: text.archived.vaccination_coverage.campaign_headers.first_shot, second: text.archived.vaccination_coverage.campaign_headers.coverage }; const colors = { first: ARCHIVED_COLORS.COLOR_HAS_ONE_SHOT, second: ARCHIVED_COLORS.COLOR_FULLY_VACCINATED }; - const percentageKeys = { - first: { propertyKey: 'has_one_shot_percentage', shouldFormat: true }, - second: { propertyKey: 'fully_vaccinated_percentage', shouldFormat: true } - } - const percentageData = getPercentageData(sortedValues, titles, colors, percentageKeys, undefined, text.vaccination_coverage.no_data, formatPercentage); + const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; + const percentageData = getPercentageData(sortedData, titles, colors, percentageFormattingRules, undefined, commonTexts.common.no_data, formatPercentage); return ( {breakpoints.lg ? ( - ) : ( - + )} ); diff --git a/packages/cms/src/lokalize/key-mutations.csv b/packages/cms/src/lokalize/key-mutations.csv index a7c6419a8a..4b84e86b26 100644 --- a/packages/cms/src/lokalize/key-mutations.csv +++ b/packages/cms/src/lokalize/key-mutations.csv @@ -1 +1,11 @@ timestamp,action,key,document_id,move_to +2023-01-20T11:18:51.430Z,add,common.common.no_data,say0BNKaNSuhganBi4t19E,__ +2023-01-20T15:21:49.589Z,delete,pages.behavior_page.nl.basisregels.annotatie,sNNH6WARQASU7sDHsCGsgD,__ +2023-01-20T15:21:49.590Z,delete,pages.behavior_page.vr.basisregels.annotatie,7wdlutZNkP0LZIK1UVt4fP,__ +2023-01-20T15:22:47.686Z,add,pages.behavior_page.shared.basisregels.annotation,AE5jpq5sZWNgXeEUcIj5Tz,__ +2023-01-20T15:58:15.143Z,add,pages.behavior_page.shared.basisregels.title,AE5jpq5sZWNgXeEUcIwuRL,__ +2023-01-20T16:15:30.973Z,delete,pages.behavior_page.shared.leeftijden.tabel.compliance_no_data,A5Y41hFe5J3wNnB7Np5dWd,__ +2023-01-20T16:15:30.974Z,delete,pages.behavior_page.shared.leeftijden.tabel.support_no_data,X8Z1HTDxqJ9pM59361JkzO,__ +2023-01-20T16:15:30.976Z,delete,pages.vaccinations_page.nl.vaccination_coverage.no_data,hqivmGf8UPzCLjKFjLpCSD,__ +2023-01-20T16:16:02.980Z,add,pages.behavior_page.shared.basisregels.rules_followed,JaNe91xDWEANMVTM14jkIY,__ +2023-01-20T16:16:04.215Z,add,pages.behavior_page.shared.basisregels.rules_supported,AE5jpq5sZWNgXeEUcJ13cd,__ From 969306e9d5061f789e82609248d16b5d4407b559 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 23 Jan 2023 17:24:54 +0100 Subject: [PATCH 14/23] feat(table-improvements): Make optimizations based on discussions - Correct typing and some abstraction. --- .../src/components/age-groups/age-group.tsx | 29 ++++++++++ .../components/shared-styled-components.tsx | 7 --- .../tables/logic/get-percentage-data.ts | 6 +- .../src/components/tables/narrow-table.tsx | 46 ++------------- packages/app/src/components/tables/types.ts | 35 +++++------- .../app/src/components/tables/wide-table.tsx | 43 ++------------ .../behavior/behavior-per-age-group-tile.tsx | 25 ++++----- .../domain/behavior/behavior-table-tile.tsx | 45 +++++++-------- .../components/behavior-icon-with-label.tsx | 56 +++++++++++++++++++ ...utumn-2022-shot-coverage-per-age-group.tsx | 22 ++++---- .../booster-shot-coverage-per-age-group.tsx | 23 ++++---- .../domain/vaccine/components/age-group.tsx | 27 --------- .../domain/vaccine/logic/get-sorting-order.ts | 4 +- .../vaccine-coverage-per-age-group.tsx | 23 ++++---- packages/cms/src/lokalize/key-mutations.csv | 2 + 15 files changed, 183 insertions(+), 210 deletions(-) create mode 100644 packages/app/src/components/age-groups/age-group.tsx create mode 100644 packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx delete mode 100644 packages/app/src/domain/vaccine/components/age-group.tsx diff --git a/packages/app/src/components/age-groups/age-group.tsx b/packages/app/src/components/age-groups/age-group.tsx new file mode 100644 index 0000000000..c863ec61dc --- /dev/null +++ b/packages/app/src/components/age-groups/age-group.tsx @@ -0,0 +1,29 @@ +import { Box } from '~/components/base'; +import { BoldText, InlineText } from '~/components/typography'; +import { useIntl } from '~/intl'; +import { formatAgeGroupString } from '~/utils/format-age-group-string'; +import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; +import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; + +interface AgeGroupProps { + range: string; + peopleInAgeGroup?: number; + birthYearRange: string; +} + +export function AgeGroup({ range, peopleInAgeGroup, birthYearRange }: AgeGroupProps) { + const { commonTexts, formatNumber } = useIntl(); + const ageRange = formatAgeGroupString(range, commonTexts.common.agegroup); + const yearOfBirthRange = formatBirthyearRangeString(birthYearRange, commonTexts.common.birthyears); + + const totalText = replaceVariablesInText(commonTexts.common.agegroup.total_people, { + total: formatNumber(peopleInAgeGroup), + }); + + return ( + + {ageRange} + {`${yearOfBirthRange}${peopleInAgeGroup ? `: ${totalText}` : ''}`} + + ); +} diff --git a/packages/app/src/components/tables/components/shared-styled-components.tsx b/packages/app/src/components/tables/components/shared-styled-components.tsx index 5a974b0989..9dbe34f907 100644 --- a/packages/app/src/components/tables/components/shared-styled-components.tsx +++ b/packages/app/src/components/tables/components/shared-styled-components.tsx @@ -1,7 +1,6 @@ import { colors } from '@corona-dashboard/common'; import styled from 'styled-components'; import { border, BorderProps, compose, display, DisplayProps, minWidth, MinWidthProps, width, WidthProps } from 'styled-system'; -import { Anchor } from '~/components/typography'; import { fontWeights, mediaQueries, space } from '~/style/theme'; export const Table = styled.table` @@ -44,9 +43,3 @@ export const Cell = styled.td` vertical-align: middle; ${compose(border, minWidth)}; `; - -export const BehaviorAnchor = styled(Anchor)` - &:hover { - color: ${colors.blue8}; - } -`; diff --git a/packages/app/src/components/tables/logic/get-percentage-data.ts b/packages/app/src/components/tables/logic/get-percentage-data.ts index 590bb11b4f..c80bf0ff69 100644 --- a/packages/app/src/components/tables/logic/get-percentage-data.ts +++ b/packages/app/src/components/tables/logic/get-percentage-data.ts @@ -3,7 +3,6 @@ import { PercentageDataPoint } from '../types'; type FormatParam = { shouldFormat?: boolean }; type PercentageFormattingParams = { first: FormatParam; second: FormatParam }; -type TrendDirectionParams = { first: string; second: string }; type ColorParam = { first: string; second: string }; type TitleParam = { first: string; second: string }; @@ -13,7 +12,6 @@ export const getPercentageData = ( title: TitleParam, color: ColorParam, percentageFormattingRules: PercentageFormattingParams, - trendDirection?: TrendDirectionParams, noDataText?: string, formatPercentage?: ReturnType['formatPercentage'] ): PercentageDataPoint[][] => { @@ -27,7 +25,7 @@ export const getPercentageData = ( return [ { title: title.first, - trendDirection: trendDirection?.first !== undefined && trendDirection.first in datasetItem ? datasetItem[trendDirection.first] : null, + trendDirection: 'firstPercentageTrend' in datasetItem ? datasetItem['firstPercentageTrend'] : null, percentage: { color: color.first, value: percentageFormattingRules.first.shouldFormat ? getFormattedPercentageValue(datasetItem.firstPercentage) : datasetItem.firstPercentage, @@ -35,7 +33,7 @@ export const getPercentageData = ( }, { title: title.second, - trendDirection: trendDirection?.second !== undefined && trendDirection.second in datasetItem ? datasetItem[trendDirection.second] : null, + trendDirection: 'secondPercentageTrend' in datasetItem ? datasetItem['secondPercentageTrend'] : null, percentage: { color: color.second, value: percentageFormattingRules.second.shouldFormat ? getFormattedPercentageValue(datasetItem.secondPercentage) : datasetItem.secondPercentage, diff --git a/packages/app/src/components/tables/narrow-table.tsx b/packages/app/src/components/tables/narrow-table.tsx index 496bde1c30..258595e82a 100644 --- a/packages/app/src/components/tables/narrow-table.tsx +++ b/packages/app/src/components/tables/narrow-table.tsx @@ -1,24 +1,15 @@ import { Box } from '~/components/base'; -import { BoldText } from '~/components/typography'; -import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; -import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { useIntl } from '~/intl'; import { space } from '~/style/theme'; -import { formatAgeGroupString } from '~/utils/format-age-group-string'; -import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; import { PercentageData } from './components/mobile-percentage-data'; -import { BehaviorAnchor, Cell, HeaderCell, Row, Table } from './components/shared-styled-components'; +import { Cell, HeaderCell, Row, Table } from './components/shared-styled-components'; import { CommonTableProps } from './types'; interface NarrowTableProps extends CommonTableProps { headerText: string; - tableData: any[]; // TODO:AP - figure out how to properly type this } // Component shown for tables on narrow screens. -export const NarrowTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percentageData, onClickConfig }: NarrowTableProps) => { - const { commonTexts } = useIntl(); - +export const NarrowTable = ({ tableData, headerText, percentageData }: NarrowTableProps) => { return (
@@ -33,40 +24,11 @@ export const NarrowTable = ({ tableData, headerText, hasAgeGroups, hasIcon, perc - {hasIcon && ( - <> - - - - - onClickConfig.handler(item.id, onClickConfig.scrollRef) : undefined} - > - - {item.description} - - - - )} - - {hasAgeGroups && item?.ageGroupRange && item?.birthYearRange && ( - - )} + {item.firstColumnLabel} - {percentageData.map( - (percentageDataPoints, percentageDataIndex) => - percentageDataIndex === tableDataIndex && - )} + diff --git a/packages/app/src/components/tables/types.ts b/packages/app/src/components/tables/types.ts index 2a2e8ffaa7..da8cd005eb 100644 --- a/packages/app/src/components/tables/types.ts +++ b/packages/app/src/components/tables/types.ts @@ -1,34 +1,29 @@ -import { BehaviorIdentifier, BehaviorTrendType } from '~/domain/behavior/logic/behavior-types'; +import React from 'react'; +import { BehaviorTrendType } from '~/domain/behavior/logic/behavior-types'; + +type TrendDirection = BehaviorTrendType | null; export type PercentageDataPoint = { title: string; - trendDirection?: 'up' | 'down' | 'equal' | null; + trendDirection?: TrendDirection; percentage: { color: string; value: number | string; }; }; -type ScrollRef = { current: HTMLDivElement | null }; - -export interface CommonTableProps { - percentageData: PercentageDataPoint[][]; - hasAgeGroups?: boolean; - hasIcon?: boolean; - onClickConfig?: { - handler: (id: BehaviorIdentifier, scrollRef: ScrollRef) => void; - scrollRef: ScrollRef; - }; -} - export interface TableData { id: string; - firstPercentage: number | string; - secondPercentage: number | string; + firstColumnLabel: React.ReactNode; + firstPercentage: number | null; + secondPercentage: number | null; + firstPercentageTrend?: TrendDirection; + secondPercentageTrend?: TrendDirection; description?: string; - complianceTrend?: BehaviorTrendType | null; - supportTrend?: BehaviorTrendType | null; - ageGroupTotal?: number; ageGroupRange?: string; - birthYearRange?: string; +} + +export interface CommonTableProps { + tableData: TableData[]; + percentageData: PercentageDataPoint[][]; } diff --git a/packages/app/src/components/tables/wide-table.tsx b/packages/app/src/components/tables/wide-table.tsx index 7742ffc82c..273137e5bf 100644 --- a/packages/app/src/components/tables/wide-table.tsx +++ b/packages/app/src/components/tables/wide-table.tsx @@ -1,15 +1,8 @@ import { colors } from '@corona-dashboard/common'; import styled from 'styled-components'; import { Box } from '~/components/base'; -import { InlineText } from '~/components/typography'; -import { BehaviorIcon } from '~/domain/behavior/components/behavior-icon'; -import { AgeGroup } from '~/domain/vaccine/components/age-group'; -import { useIntl } from '~/intl'; -import { space } from '~/style/theme'; -import { formatAgeGroupString } from '~/utils/format-age-group-string'; -import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-string'; import { PercentageData } from './components/desktop-percentage-data'; -import { BehaviorAnchor, Cell, HeaderCell, Table, TableHead } from './components/shared-styled-components'; +import { Cell, HeaderCell, Table, TableHead } from './components/shared-styled-components'; import { CommonTableProps } from './types'; export const tableColumnWidths = { @@ -20,13 +13,10 @@ export const tableColumnWidths = { interface WideTableProps extends CommonTableProps { headerText: { [key: string]: string }; - tableData: any[]; // TODO:AP - figure out how to properly type this } // Component shown for tables on wide screens. -export const WideTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percentageData, onClickConfig }: WideTableProps) => { - const { commonTexts } = useIntl(); - +export const WideTable = ({ tableData, headerText, percentageData }: WideTableProps) => { return (
@@ -49,34 +39,9 @@ export const WideTable = ({ tableData, headerText, hasAgeGroups, hasIcon, percen {tableData.map((item, tableDataIndex) => ( - {hasIcon && ( - - - - - - onClickConfig.handler(item.id, onClickConfig.scrollRef) : undefined}> - - {item.description} - - - - )} - - {hasAgeGroups && item?.ageGroupRange && item?.birthYearRange && ( - - )} + {item.firstColumnLabel} - - {percentageData.map( - (percentageDataPoints, percentageDataIndex) => - percentageDataIndex === tableDataIndex && - )} + ))} diff --git a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx index 067c187440..5666dbe4d2 100644 --- a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx @@ -1,10 +1,12 @@ import { colors, NlBehaviorPerAgeGroup } from '@corona-dashboard/common'; import React from 'react'; +import { AgeGroup } from '~/components/age-groups/age-group'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; +import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; import { Text } from '~/components/typography'; import { useIntl } from '~/intl'; @@ -37,8 +39,8 @@ interface BehaviorPerAgeGroupProps { export function BehaviorPerAgeGroup({ title, description, data, currentId, setCurrentId, text, metadata }: BehaviorPerAgeGroupProps) { const breakpoints = useBreakpoints(); const { commonTexts, formatPercentage } = useIntl(); - const complianceValue = data[`${currentId}_compliance` as keyof typeof data] || undefined; - const supportValue = data[`${currentId}_support` as keyof typeof data] || undefined; + const complianceValue = data[`${currentId}_compliance` as keyof typeof data]; + const supportValue = data[`${currentId}_support` as keyof typeof data]; assert(typeof complianceValue !== 'number', `[${BehaviorPerAgeGroup.name}] There is a problem by filtering the numbers out (complianceValue)`); assert(typeof supportValue !== 'number', `[${BehaviorPerAgeGroup.name}] There is a problem by filtering the numbers out (supportValue)`); @@ -46,21 +48,19 @@ export function BehaviorPerAgeGroup({ title, description, data, currentId, setCu const hasComplianceValues = complianceValue && keys(complianceValue).every((key) => complianceValue[key] === null) === false; const hasSupportValues = supportValue && keys(supportValue).every((key) => supportValue[key] === null) === false; const dataAvailable = hasComplianceValues || hasSupportValues; - const requiredData = AGE_KEYS_NEW.map((age, index) => { + const requiredData: TableData[] = AGE_KEYS_NEW.map((age, index) => { return { id: `${age.ageGroup}-${index}`, - firstPercentage: complianceValue?.[age.ageGroup], - secondPercentage: supportValue?.[age.ageGroup], - ageGroupTotal: null, // Passing null as the dataset does not contain information about the total number of people in an age group. - ageGroupRange: text.shared.leeftijden.tabel[age.ageGroup], - birthYearRange: age.birthYearRange, + firstPercentage: complianceValue?.[age.ageGroup] ?? null, + secondPercentage: supportValue?.[age.ageGroup] ?? null, + firstColumnLabel: , }; }); - const titles = { first: text.shared.basisregels.rules_followed, second: text.shared.basisregels.rules_supported }; - const colorValues = { first: colors.blue6, second: colors.yellow3 }; + const percentageTitles = { first: text.shared.basisregels.rules_followed, second: text.shared.basisregels.rules_supported }; + const percentageColors = { first: colors.blue6, second: colors.yellow3 }; const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; - const percentageData = getPercentageData(requiredData, titles, colorValues, percentageFormattingRules, undefined, commonTexts.common.no_data, formatPercentage); + const percentageData = getPercentageData(requiredData, percentageTitles, percentageColors, percentageFormattingRules, commonTexts.common.no_data, formatPercentage); return ( @@ -79,10 +79,9 @@ export function BehaviorPerAgeGroup({ title, description, data, currentId, setCu }} tableData={requiredData} percentageData={percentageData} - hasAgeGroups /> ) : ( - + ) ) : ( diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index 13b543ace0..79b624c8aa 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -1,17 +1,18 @@ import { colors, NlBehaviorValue, VrBehaviorArchived_20221019Value } from '@corona-dashboard/common'; import React, { useMemo } from 'react'; -import scrollIntoView from 'scroll-into-view-if-needed'; import { isDefined, isPresent } from 'ts-is-present'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; +import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; import { Text } from '~/components/typography'; import { SiteText } from '~/locale'; import { space } from '~/style/theme'; import { useBreakpoints } from '~/utils/use-breakpoints'; +import { BehaviorIconWithLabel, OnClickConfig } from './components/behavior-icon-with-label'; import { BehaviorTrend } from './components/behavior-trend'; import { BehaviorIdentifier } from './logic/behavior-types'; import { useBehaviorLookupKeys } from './logic/use-behavior-lookup-keys'; @@ -31,18 +32,11 @@ interface BehaviorTableTileProps { export function BehaviorTableTile({ title, description, value, annotation, setCurrentId, scrollRef, text, metadata }: BehaviorTableTileProps) { const breakpoints = useBreakpoints(true); - const behaviorsTableData = useBehaviorTableData(value as NlBehaviorValue); + const behaviorsTableData: TableData[] = useBehaviorTableData(value as NlBehaviorValue, { scrollRef, setCurrentId }); const titles = { first: text.basisregels.rules_followed, second: text.basisregels.rules_supported }; const colorValues = { first: colors.blue6, second: colors.yellow3 }; const percentageFormattingRules = { first: { shouldFormat: false }, second: { shouldFormat: false } }; - const trendDirectionKeys = { first: 'complianceTrend', second: 'supportTrend' }; - const percentageData = getPercentageData(behaviorsTableData, titles, colorValues, percentageFormattingRules, trendDirectionKeys); - - const anchorButtonClickHandler = (id: BehaviorIdentifier, scrollRef: { current: HTMLDivElement | null }) => { - scrollIntoView(scrollRef.current as Element); - setCurrentId(id); - }; - const onClickConfig = { handler: anchorButtonClickHandler, scrollRef: scrollRef }; + const percentageData = getPercentageData(behaviorsTableData, titles, colorValues, percentageFormattingRules); return ( @@ -56,11 +50,9 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu }} tableData={behaviorsTableData} percentageData={percentageData} - onClickConfig={onClickConfig} - hasIcon /> ) : ( - + )} @@ -68,14 +60,14 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu - Verschil met de vorige meting is lager + {text.basisregels.footer_trend_down_annotation} - Verschil met de vorige meting is hoger + {text.basisregels.footer_trend_up_annotation} @@ -90,30 +82,31 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu ); } -function useBehaviorTableData(value: NlBehaviorValue) { +function useBehaviorTableData(value: NlBehaviorValue, onClickConfig: OnClickConfig) { const behaviorLookupKeys = useBehaviorLookupKeys(); return useMemo(() => { return behaviorLookupKeys - .map((x) => { - const compliancePercentage = value[x.complianceKey]; - const complianceTrend = value[`${x.complianceKey}_trend` as const]; + .map((lookupKey) => { + const compliancePercentage = value[lookupKey.complianceKey]; + const complianceTrend = value[`${lookupKey.complianceKey}_trend` as const]; - const supportPercentage = value[x.supportKey]; - const supportTrend = value[`${x.supportKey}_trend` as const]; + const supportPercentage = value[lookupKey.supportKey]; + const supportTrend = value[`${lookupKey.supportKey}_trend` as const]; if (isPresent(supportPercentage) && isDefined(supportTrend) && isPresent(compliancePercentage) && isDefined(complianceTrend)) { return { - id: x.key, - description: x.description, + id: lookupKey.key, + description: lookupKey.description, firstPercentage: compliancePercentage, - complianceTrend, + firstPercentageTrend: complianceTrend, secondPercentage: supportPercentage, - supportTrend, + secondPercentageTrend: supportTrend, + firstColumnLabel: , }; } }) .filter(isDefined) .sort((a, b) => (b.firstPercentage ?? 0) - (a.firstPercentage ?? 0)); - }, [value, behaviorLookupKeys]); + }, [value, behaviorLookupKeys, onClickConfig]); } diff --git a/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx b/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx new file mode 100644 index 0000000000..4735a03384 --- /dev/null +++ b/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx @@ -0,0 +1,56 @@ +import { colors } from '@corona-dashboard/common'; +import scrollIntoView from 'scroll-into-view-if-needed'; +import styled from 'styled-components'; +import { Box } from '~/components/base'; +import { Anchor } from '~/components/typography'; +import { fontWeights, mediaQueries, space } from '~/style/theme'; +import { BehaviorIdentifier } from '../logic/behavior-types'; +import { BehaviorIcon } from './behavior-icon'; + +type ScrollRef = { current: HTMLDivElement | null }; + +export type OnClickConfig = { + setCurrentId: React.Dispatch>; + scrollRef: ScrollRef; +}; + +interface BehaviorIconWithLabelProps { + id: BehaviorIdentifier; + description: string; + onClickConfig: OnClickConfig; +} + +export const BehaviorIconWithLabel = ({ id, description, onClickConfig }: BehaviorIconWithLabelProps) => { + const anchorButtonClickHandler = (id: BehaviorIdentifier, scrollRef: ScrollRef) => { + scrollIntoView(scrollRef.current as Element); + onClickConfig.setCurrentId(id); + }; + + return ( + + + + + + anchorButtonClickHandler(id, onClickConfig.scrollRef)}> + + {description} + + + + ); +}; + +const BehaviorAnchor = styled(Anchor)` + span { + font-weight: ${fontWeights.bold}; + + @media ${mediaQueries.lg} { + font-weight: ${fontWeights.normal}; + } + } + + &:hover { + color: ${colors.blue8}; + } +`; diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index 6b04c19749..c18309a740 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -1,8 +1,10 @@ import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; +import { AgeGroup } from '~/components/age-groups/age-group'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; +import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; import { COLOR_AUTUMN_2022_SHOT, COLOR_FULLY_VACCINATED } from '~/domain/vaccine/common'; import { useIntl } from '~/intl'; @@ -23,22 +25,23 @@ export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata const breakpoints = useBreakpoints(true); const { commonTexts, formatPercentage } = useIntl(); const componentName = Autumn2022ShotCoveragePerAgeGroup.name; - const requiredData = values.map((value) => { + const requiredData: TableData[] = values.map((value) => { return { - id: value.age_group_range, - ageGroupTotal: 'age_group_total' in value ? value.age_group_total : undefined, - ageGroupRange: value.age_group_range, - birthYearRange: value.birthyear_range, + id: `${componentName}-${value.age_group_range}`, firstPercentage: value.autumn_2022_vaccinated_percentage, secondPercentage: value.fully_vaccinated_percentage, + ageGroupRange: value.age_group_range, + firstColumnLabel: ( + + ), }; }); const sortedData = requiredData.sort((a, b) => getSortingOrder(a.ageGroupRange, sortingOrder, componentName) - getSortingOrder(b.ageGroupRange, sortingOrder, componentName)); - const titles = { first: text.headers.autumn_2022_shot, second: text.headers.fully_vaccinated }; - const colors = { first: COLOR_AUTUMN_2022_SHOT, second: COLOR_FULLY_VACCINATED }; + const percentageTitles = { first: text.headers.autumn_2022_shot, second: text.headers.fully_vaccinated }; + const percentageColors = { first: COLOR_AUTUMN_2022_SHOT, second: COLOR_FULLY_VACCINATED }; const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; - const percentageData = getPercentageData(sortedData, titles, colors, percentageFormattingRules, undefined, commonTexts.common.no_data, formatPercentage); + const percentageData = getPercentageData(sortedData, percentageTitles, percentageColors, percentageFormattingRules, commonTexts.common.no_data, formatPercentage); return ( @@ -52,10 +55,9 @@ export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata }} tableData={sortedData} percentageData={percentageData} - hasAgeGroups /> ) : ( - + )} ); diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx index db71bc4cae..3cf093edde 100644 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx @@ -3,10 +3,12 @@ import { NlVaccineCoveragePerAgeGroupArchived_20220908Value, VrVaccineCoveragePerAgeGroupArchived_20220908Value, } from '@corona-dashboard/common'; +import { AgeGroup } from '~/components/age-groups/age-group'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; +import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; @@ -27,21 +29,23 @@ export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, v const breakpoints = useBreakpoints(true); const { commonTexts, formatPercentage } = useIntl(); const componentName = BoosterShotCoveragePerAgeGroup.name; - const requiredData = values.map((value) => { + const requiredData: TableData[] = values.map((value) => { return { - id: value.age_group_range, - ageGroupTotal: 'age_group_total' in value ? value.age_group_total : undefined, - ageGroupRange: value.age_group_range, - birthYearRange: value.birthyear_range, + id: `${componentName}-${value.age_group_range}`, firstPercentage: value.fully_vaccinated_percentage, secondPercentage: value.booster_shot_percentage, + ageGroupRange: value.age_group_range, + firstColumnLabel: ( + + ), }; }); + const sortedData = requiredData.sort((a, b) => getSortingOrder(a.ageGroupRange, sortingOrder, componentName) - getSortingOrder(b.ageGroupRange, sortingOrder, componentName)); - const titles = { first: text.vaccination_coverage.headers.fully_vaccinated, second: text.archived.vaccination_coverage.campaign_headers.booster_shot }; - const colors = { first: COLOR_FULLY_VACCINATED, second: COLOR_FULLY_BOOSTERED }; + const percentageTitles = { first: text.vaccination_coverage.headers.fully_vaccinated, second: text.archived.vaccination_coverage.campaign_headers.booster_shot }; + const percentageColors = { first: COLOR_FULLY_VACCINATED, second: COLOR_FULLY_BOOSTERED }; const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; - const percentageData = getPercentageData(sortedData, titles, colors, percentageFormattingRules, undefined, commonTexts.common.no_data, formatPercentage); + const percentageData = getPercentageData(sortedData, percentageTitles, percentageColors, percentageFormattingRules, commonTexts.common.no_data, formatPercentage); return ( @@ -55,10 +59,9 @@ export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, v }} tableData={sortedData} percentageData={percentageData} - hasAgeGroups /> ) : ( - + )} ); diff --git a/packages/app/src/domain/vaccine/components/age-group.tsx b/packages/app/src/domain/vaccine/components/age-group.tsx deleted file mode 100644 index 3fa3fcee0f..0000000000 --- a/packages/app/src/domain/vaccine/components/age-group.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Box } from '~/components/base'; -import { InlineText, BoldText } from '~/components/typography'; -import { useIntl } from '~/intl'; -import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; -interface AgeGroupProps { - range: string; - ageGroupTotal?: number; - birthyear_range: string; - text: string; -} - -export function AgeGroup({ range, ageGroupTotal, birthyear_range, text }: AgeGroupProps) { - const { formatNumber } = useIntl(); - - const totalText = replaceVariablesInText(text, { - total: formatNumber(ageGroupTotal), - }); - - return ( - - {range} - - {`${birthyear_range}${ageGroupTotal ? `: ${totalText}` : ''}`} - - - ); -} diff --git a/packages/app/src/domain/vaccine/logic/get-sorting-order.ts b/packages/app/src/domain/vaccine/logic/get-sorting-order.ts index e38388e9c7..040a2d9cc8 100644 --- a/packages/app/src/domain/vaccine/logic/get-sorting-order.ts +++ b/packages/app/src/domain/vaccine/logic/get-sorting-order.ts @@ -1,7 +1,7 @@ -import { assert } from "@corona-dashboard/common"; +import { assert } from '@corona-dashboard/common'; // Determines the sorting order for a ordered data -export const getSortingOrder = (ageGroup: string, sortingOrder: string[], componentName: string) => { +export const getSortingOrder = (ageGroup: string | undefined, sortingOrder: string[], componentName: string) => { const index = sortingOrder.findIndex((sortingIndex) => sortingIndex === ageGroup); assert(index >= 0, `[${componentName}] No sorting order defined for age group ${ageGroup}`); return index; diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx index 6d7d3da014..a759fc1fa3 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx @@ -1,8 +1,10 @@ import { GmVaccineCoveragePerAgeGroupArchivedValue, NlVaccineCoveragePerAgeGroupArchivedValue, VrVaccineCoveragePerAgeGroupArchivedValue } from '@corona-dashboard/common'; +import { AgeGroup } from '~/components/age-groups/age-group'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; +import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; @@ -23,21 +25,23 @@ export function VaccineCoveragePerAgeGroup({ title, description, metadata, value const breakpoints = useBreakpoints(true); const { commonTexts, formatPercentage } = useIntl(); const componentName = VaccineCoveragePerAgeGroup.name; - const requiredData = values.map((value) => { + const requiredData: TableData[] = values.map((value) => { return { - id: value.age_group_range, - ageGroupTotal: 'age_group_total' in value ? value.age_group_total : undefined, - ageGroupRange: value.age_group_range, - birthYearRange: value.birthyear_range, + id: `${componentName}-${value.age_group_range}`, firstPercentage: value.has_one_shot_percentage, secondPercentage: value.fully_vaccinated_percentage, + ageGroupRange: value.age_group_range, + firstColumnLabel: ( + + ), }; }); + const sortedData = requiredData.sort((a, b) => getSortingOrder(a.ageGroupRange, sortingOrder, componentName) - getSortingOrder(b.ageGroupRange, sortingOrder, componentName)); - const titles = { first: text.archived.vaccination_coverage.campaign_headers.first_shot, second: text.archived.vaccination_coverage.campaign_headers.coverage }; - const colors = { first: ARCHIVED_COLORS.COLOR_HAS_ONE_SHOT, second: ARCHIVED_COLORS.COLOR_FULLY_VACCINATED }; + const percentageTitles = { first: text.archived.vaccination_coverage.campaign_headers.first_shot, second: text.archived.vaccination_coverage.campaign_headers.coverage }; + const percentageColors = { first: ARCHIVED_COLORS.COLOR_HAS_ONE_SHOT, second: ARCHIVED_COLORS.COLOR_FULLY_VACCINATED }; const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; - const percentageData = getPercentageData(sortedData, titles, colors, percentageFormattingRules, undefined, commonTexts.common.no_data, formatPercentage); + const percentageData = getPercentageData(sortedData, percentageTitles, percentageColors, percentageFormattingRules, commonTexts.common.no_data, formatPercentage); return ( @@ -51,10 +55,9 @@ export function VaccineCoveragePerAgeGroup({ title, description, metadata, value }} tableData={sortedData} percentageData={percentageData} - hasAgeGroups /> ) : ( - + )} ); diff --git a/packages/cms/src/lokalize/key-mutations.csv b/packages/cms/src/lokalize/key-mutations.csv index 4b84e86b26..a1d7be1ba1 100644 --- a/packages/cms/src/lokalize/key-mutations.csv +++ b/packages/cms/src/lokalize/key-mutations.csv @@ -9,3 +9,5 @@ timestamp,action,key,document_id,move_to 2023-01-20T16:15:30.976Z,delete,pages.vaccinations_page.nl.vaccination_coverage.no_data,hqivmGf8UPzCLjKFjLpCSD,__ 2023-01-20T16:16:02.980Z,add,pages.behavior_page.shared.basisregels.rules_followed,JaNe91xDWEANMVTM14jkIY,__ 2023-01-20T16:16:04.215Z,add,pages.behavior_page.shared.basisregels.rules_supported,AE5jpq5sZWNgXeEUcJ13cd,__ +2023-01-23T15:40:31.128Z,add,pages.behavior_page.shared.basisregels.footer_trend_up_annotation,say0BNKaNSuhganBiTKhoE,__ +2023-01-23T15:40:32.050Z,add,pages.behavior_page.shared.basisregels.footer_trend_down_annotation,gwBtgw3hhC8JAGy8EpyiE9,__ From 55be6897e6f737cb5fbf68fb0c2cbf8aaef3207b Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Mon, 23 Jan 2023 17:41:56 +0100 Subject: [PATCH 15/23] feat(table-improvements): Moves some files around. --- ...-percentage-data.tsx => narrow-percentage-data.tsx} | 3 ++- .../tables}/components/narrow-percentage.tsx | 10 +--------- ...op-percentage-data.tsx => wide-percentage-data.tsx} | 3 ++- .../tables}/components/wide-percentage.tsx | 7 +++---- packages/app/src/components/tables/narrow-table.tsx | 2 +- packages/app/src/components/tables/wide-table.tsx | 2 +- .../app/src/domain/behavior/behavior-table-tile.tsx | 2 +- 7 files changed, 11 insertions(+), 18 deletions(-) rename packages/app/src/components/tables/components/{mobile-percentage-data.tsx => narrow-percentage-data.tsx} (91%) rename packages/app/src/{domain/vaccine => components/tables}/components/narrow-percentage.tsx (75%) rename packages/app/src/components/tables/components/{desktop-percentage-data.tsx => wide-percentage-data.tsx} (93%) rename packages/app/src/{domain/vaccine => components/tables}/components/wide-percentage.tsx (87%) diff --git a/packages/app/src/components/tables/components/mobile-percentage-data.tsx b/packages/app/src/components/tables/components/narrow-percentage-data.tsx similarity index 91% rename from packages/app/src/components/tables/components/mobile-percentage-data.tsx rename to packages/app/src/components/tables/components/narrow-percentage-data.tsx index ed053bec77..4883cf23f8 100644 --- a/packages/app/src/components/tables/components/mobile-percentage-data.tsx +++ b/packages/app/src/components/tables/components/narrow-percentage-data.tsx @@ -1,6 +1,6 @@ import { Box } from '~/components/base'; import { BehaviorTrend } from '~/domain/behavior/components/behavior-trend'; -import { NarrowPercentage } from '~/domain/vaccine/components/narrow-percentage'; +import { NarrowPercentage } from '~/components/tables/components/narrow-percentage'; import { space } from '~/style/theme'; import { PercentageDataPoint } from '../types'; import { PercentageBarWithoutNumber } from './percentage-bar-without-number'; @@ -9,6 +9,7 @@ interface PercentageDataProps { percentageDataPoints: PercentageDataPoint[]; } +// Component used to show percentage data on narrow screens. export const PercentageData = ({ percentageDataPoints }: PercentageDataProps) => { return ( <> diff --git a/packages/app/src/domain/vaccine/components/narrow-percentage.tsx b/packages/app/src/components/tables/components/narrow-percentage.tsx similarity index 75% rename from packages/app/src/domain/vaccine/components/narrow-percentage.tsx rename to packages/app/src/components/tables/components/narrow-percentage.tsx index ffdca97952..d05bd2ff6c 100644 --- a/packages/app/src/domain/vaccine/components/narrow-percentage.tsx +++ b/packages/app/src/components/tables/components/narrow-percentage.tsx @@ -2,14 +2,12 @@ import { Box } from '~/components/base'; import { InlineText } from '~/components/typography'; import { space } from '~/style/theme'; - interface NarrowPercentageProps { value: number | React.ReactNode; color: string; textLabel: string; } -// TODO: AP: Move to tables directory export function NarrowPercentage({ value, color, textLabel }: NarrowPercentageProps) { return ( @@ -18,13 +16,7 @@ export function NarrowPercentage({ value, color, textLabel }: NarrowPercentagePr - + {value} diff --git a/packages/app/src/components/tables/components/desktop-percentage-data.tsx b/packages/app/src/components/tables/components/wide-percentage-data.tsx similarity index 93% rename from packages/app/src/components/tables/components/desktop-percentage-data.tsx rename to packages/app/src/components/tables/components/wide-percentage-data.tsx index b13e4f555a..c77cd873f4 100644 --- a/packages/app/src/components/tables/components/desktop-percentage-data.tsx +++ b/packages/app/src/components/tables/components/wide-percentage-data.tsx @@ -1,6 +1,6 @@ import { Box } from '~/components/base'; import { BehaviorTrend } from '~/domain/behavior/components/behavior-trend'; -import { WidePercentage } from '~/domain/vaccine/components/wide-percentage'; +import { WidePercentage } from '~/components/tables/components/wide-percentage'; import { space } from '~/style/theme'; import { PercentageDataPoint } from '../types'; import { tableColumnWidths } from '../wide-table'; @@ -11,6 +11,7 @@ interface PercentageDataProps { percentageDataPoints: PercentageDataPoint[]; } +// Component used to show percentages on wide screens. export const PercentageData = ({ percentageDataPoints }: PercentageDataProps) => { return ( <> diff --git a/packages/app/src/domain/vaccine/components/wide-percentage.tsx b/packages/app/src/components/tables/components/wide-percentage.tsx similarity index 87% rename from packages/app/src/domain/vaccine/components/wide-percentage.tsx rename to packages/app/src/components/tables/components/wide-percentage.tsx index 582666b1dc..d115355a0c 100644 --- a/packages/app/src/domain/vaccine/components/wide-percentage.tsx +++ b/packages/app/src/components/tables/components/wide-percentage.tsx @@ -9,7 +9,6 @@ interface PercentageWideNumberProps { justifyContent: string; } -// TODO: AP: Move to tables directory export function WidePercentage({ value, color, justifyContent }: PercentageWideNumberProps) { return ( @@ -20,15 +19,15 @@ export function WidePercentage({ value, color, justifyContent }: PercentageWideN } interface StyledInlineTextProps { - justifyContent: string + justifyContent: string; } const StyledInlineText = styled(InlineText)` align-items: center; display: flex; font-size: ${fontSizes[2]}; - justify-content: ${({justifyContent}) => justifyContent}; + justify-content: ${({ justifyContent }) => justifyContent}; line-height: ${lineHeights[2]}; padding-right: ${space[4]}; text-align: left; -` +`; diff --git a/packages/app/src/components/tables/narrow-table.tsx b/packages/app/src/components/tables/narrow-table.tsx index 258595e82a..26b6f6014f 100644 --- a/packages/app/src/components/tables/narrow-table.tsx +++ b/packages/app/src/components/tables/narrow-table.tsx @@ -1,6 +1,6 @@ import { Box } from '~/components/base'; import { space } from '~/style/theme'; -import { PercentageData } from './components/mobile-percentage-data'; +import { PercentageData } from './components/narrow-percentage-data'; import { Cell, HeaderCell, Row, Table } from './components/shared-styled-components'; import { CommonTableProps } from './types'; diff --git a/packages/app/src/components/tables/wide-table.tsx b/packages/app/src/components/tables/wide-table.tsx index 273137e5bf..d0d1b2ab31 100644 --- a/packages/app/src/components/tables/wide-table.tsx +++ b/packages/app/src/components/tables/wide-table.tsx @@ -1,7 +1,7 @@ import { colors } from '@corona-dashboard/common'; import styled from 'styled-components'; import { Box } from '~/components/base'; -import { PercentageData } from './components/desktop-percentage-data'; +import { PercentageData } from './components/wide-percentage-data'; import { Cell, HeaderCell, Table, TableHead } from './components/shared-styled-components'; import { CommonTableProps } from './types'; diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index 79b624c8aa..e9cedf738f 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -55,7 +55,7 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu )} - + From 689a52ffec269c61fdfd7acedb0779e2e66d48a7 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 26 Jan 2023 11:44:11 +0100 Subject: [PATCH 16/23] feat(table-consistency): Optimisations and PR feedback about dropdown width. --- .../tables/logic/get-birth-year-range.ts | 11 ++++++++ ...age-data.ts => use-get-percentage-data.ts} | 24 ++++++++---------- .../behavior/behavior-per-age-group-tile.tsx | 25 ++++++++----------- .../domain/behavior/behavior-table-tile.tsx | 5 ++-- ...utumn-2022-shot-coverage-per-age-group.tsx | 6 ++--- .../booster-shot-coverage-per-age-group.tsx | 6 ++--- .../vaccine-coverage-per-age-group.tsx | 6 ++--- 7 files changed, 41 insertions(+), 42 deletions(-) create mode 100644 packages/app/src/components/tables/logic/get-birth-year-range.ts rename packages/app/src/components/tables/logic/{get-percentage-data.ts => use-get-percentage-data.ts} (52%) diff --git a/packages/app/src/components/tables/logic/get-birth-year-range.ts b/packages/app/src/components/tables/logic/get-birth-year-range.ts new file mode 100644 index 0000000000..f0f592f42f --- /dev/null +++ b/packages/app/src/components/tables/logic/get-birth-year-range.ts @@ -0,0 +1,11 @@ +/** + * Takes an age(group) string as an argument and returns a string of the birth year (range) for a give age(group). + */ +export const getBirthYearRange = (ageGroup: string): string => { + const currentYear = new Date().getFullYear(); + const hasPlus = ageGroup.includes('_plus'); + const splitAgeKey = ageGroup.split(hasPlus ? ' ' : '_'); + const birthYearRange = splitAgeKey.map((key) => currentYear - parseInt(key, 10)).sort((a, b) => a - b); + + return hasPlus ? `-${birthYearRange}` : `${birthYearRange.at(0)}-${birthYearRange.at(1)}`; +}; diff --git a/packages/app/src/components/tables/logic/get-percentage-data.ts b/packages/app/src/components/tables/logic/use-get-percentage-data.ts similarity index 52% rename from packages/app/src/components/tables/logic/get-percentage-data.ts rename to packages/app/src/components/tables/logic/use-get-percentage-data.ts index c80bf0ff69..291139e8ba 100644 --- a/packages/app/src/components/tables/logic/get-percentage-data.ts +++ b/packages/app/src/components/tables/logic/use-get-percentage-data.ts @@ -1,24 +1,22 @@ -import { createFormatting } from '@corona-dashboard/common'; -import { PercentageDataPoint } from '../types'; +import { useIntl } from '~/intl'; +import { PercentageDataPoint, TableData } from '../types'; -type FormatParam = { shouldFormat?: boolean }; +type FormatParam = { shouldFormat: boolean }; type PercentageFormattingParams = { first: FormatParam; second: FormatParam }; type ColorParam = { first: string; second: string }; type TitleParam = { first: string; second: string }; // Returns an array of objects corresponding to percentage data used by tables on the dashboard -export const getPercentageData = ( - dataset: any[], // TODO:AP - figure out how to properly type this +export const useGetPercentageData = ( + dataset: TableData[], title: TitleParam, color: ColorParam, - percentageFormattingRules: PercentageFormattingParams, - noDataText?: string, - formatPercentage?: ReturnType['formatPercentage'] + percentageFormattingRules?: PercentageFormattingParams ): PercentageDataPoint[][] => { - const getFormattedPercentageValue = (percentage: number | null) => { - if (formatPercentage === undefined) return; + const { commonTexts, formatPercentage } = useIntl(); - return percentage !== null ? `${formatPercentage(percentage)}%` : noDataText; + const getFormattedPercentageValue = (percentage: number | null, shouldFormat: boolean) => { + return percentage === null ? commonTexts.common.no_data : shouldFormat ? `${formatPercentage(percentage)}%` : percentage; }; return dataset.map((datasetItem) => { @@ -28,7 +26,7 @@ export const getPercentageData = ( trendDirection: 'firstPercentageTrend' in datasetItem ? datasetItem['firstPercentageTrend'] : null, percentage: { color: color.first, - value: percentageFormattingRules.first.shouldFormat ? getFormattedPercentageValue(datasetItem.firstPercentage) : datasetItem.firstPercentage, + value: getFormattedPercentageValue(datasetItem.firstPercentage, percentageFormattingRules?.first.shouldFormat ?? false), }, }, { @@ -36,7 +34,7 @@ export const getPercentageData = ( trendDirection: 'secondPercentageTrend' in datasetItem ? datasetItem['secondPercentageTrend'] : null, percentage: { color: color.second, - value: percentageFormattingRules.second.shouldFormat ? getFormattedPercentageValue(datasetItem.secondPercentage) : datasetItem.secondPercentage, + value: getFormattedPercentageValue(datasetItem.secondPercentage, percentageFormattingRules?.second.shouldFormat ?? false), }, }, ]; diff --git a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx index 5666dbe4d2..acf8b6f663 100644 --- a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx @@ -4,27 +4,21 @@ import { AgeGroup } from '~/components/age-groups/age-group'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; -import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; +import { getBirthYearRange } from '~/components/tables/logic/get-birth-year-range'; +import { useGetPercentageData } from '~/components/tables/logic/use-get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; import { Text } from '~/components/typography'; -import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; +import { space } from '~/style/theme'; import { keys } from '~/utils'; import { assert } from '~/utils/assert'; import { useBreakpoints } from '~/utils/use-breakpoints'; import { SelectBehavior } from './components/select-behavior'; import { BehaviorIdentifier } from './logic/behavior-types'; -// The data for behaviour age groups does not include birth year ranges, so this has been added manually -const AGE_KEYS_NEW = [ - { ageGroup: '70_plus', birthYearRange: '-1952' }, - { ageGroup: '55_69', birthYearRange: '1953-1967' }, - { ageGroup: '40_54', birthYearRange: '1968-1983' }, - { ageGroup: '25_39', birthYearRange: '1983-1998' }, - { ageGroup: '16_24', birthYearRange: '1998-2007' }, -] as const; +const AGE_GROUPS_KEYS = ['70_plus', '55_69', '40_54', '25_39', '16_24'] as const; interface BehaviorPerAgeGroupProps { title: string; @@ -38,7 +32,6 @@ interface BehaviorPerAgeGroupProps { export function BehaviorPerAgeGroup({ title, description, data, currentId, setCurrentId, text, metadata }: BehaviorPerAgeGroupProps) { const breakpoints = useBreakpoints(); - const { commonTexts, formatPercentage } = useIntl(); const complianceValue = data[`${currentId}_compliance` as keyof typeof data]; const supportValue = data[`${currentId}_support` as keyof typeof data]; @@ -48,7 +41,9 @@ export function BehaviorPerAgeGroup({ title, description, data, currentId, setCu const hasComplianceValues = complianceValue && keys(complianceValue).every((key) => complianceValue[key] === null) === false; const hasSupportValues = supportValue && keys(supportValue).every((key) => supportValue[key] === null) === false; const dataAvailable = hasComplianceValues || hasSupportValues; - const requiredData: TableData[] = AGE_KEYS_NEW.map((age, index) => { + const AGE_GROUPS_BIRTH_RANGES = AGE_GROUPS_KEYS.map((ageGroup) => ({ ageGroup, birthYearRange: getBirthYearRange(ageGroup) })); + + const requiredData: TableData[] = AGE_GROUPS_BIRTH_RANGES.map((age, index) => { return { id: `${age.ageGroup}-${index}`, firstPercentage: complianceValue?.[age.ageGroup] ?? null, @@ -60,12 +55,14 @@ export function BehaviorPerAgeGroup({ title, description, data, currentId, setCu const percentageTitles = { first: text.shared.basisregels.rules_followed, second: text.shared.basisregels.rules_supported }; const percentageColors = { first: colors.blue6, second: colors.yellow3 }; const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; - const percentageData = getPercentageData(requiredData, percentageTitles, percentageColors, percentageFormattingRules, commonTexts.common.no_data, formatPercentage); + const percentageData = useGetPercentageData(requiredData, percentageTitles, percentageColors, percentageFormattingRules); return ( - + + + {dataAvailable ? ( diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index e9cedf738f..eec1c925ae 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -4,7 +4,7 @@ import { isDefined, isPresent } from 'ts-is-present'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; -import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; +import { useGetPercentageData } from '~/components/tables/logic/use-get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; @@ -35,8 +35,7 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu const behaviorsTableData: TableData[] = useBehaviorTableData(value as NlBehaviorValue, { scrollRef, setCurrentId }); const titles = { first: text.basisregels.rules_followed, second: text.basisregels.rules_supported }; const colorValues = { first: colors.blue6, second: colors.yellow3 }; - const percentageFormattingRules = { first: { shouldFormat: false }, second: { shouldFormat: false } }; - const percentageData = getPercentageData(behaviorsTableData, titles, colorValues, percentageFormattingRules); + const percentageData = useGetPercentageData(behaviorsTableData, titles, colorValues); return ( diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index c18309a740..83c649ad3a 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -2,12 +2,11 @@ import { NlVaccineCoveragePerAgeGroupValue } from '@corona-dashboard/common'; import { AgeGroup } from '~/components/age-groups/age-group'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; -import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; +import { useGetPercentageData } from '~/components/tables/logic/use-get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; import { COLOR_AUTUMN_2022_SHOT, COLOR_FULLY_VACCINATED } from '~/domain/vaccine/common'; -import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; import { getSortingOrder } from '../logic/get-sorting-order'; @@ -23,7 +22,6 @@ interface Autumn2022ShotCoveragePerAgeGroupProps { export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata, values, sortingOrder, text }: Autumn2022ShotCoveragePerAgeGroupProps) => { const breakpoints = useBreakpoints(true); - const { commonTexts, formatPercentage } = useIntl(); const componentName = Autumn2022ShotCoveragePerAgeGroup.name; const requiredData: TableData[] = values.map((value) => { return { @@ -41,7 +39,7 @@ export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata const percentageTitles = { first: text.headers.autumn_2022_shot, second: text.headers.fully_vaccinated }; const percentageColors = { first: COLOR_AUTUMN_2022_SHOT, second: COLOR_FULLY_VACCINATED }; const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; - const percentageData = getPercentageData(sortedData, percentageTitles, percentageColors, percentageFormattingRules, commonTexts.common.no_data, formatPercentage); + const percentageData = useGetPercentageData(sortedData, percentageTitles, percentageColors, percentageFormattingRules); return ( diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx index 3cf093edde..c05cac2019 100644 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx @@ -6,11 +6,10 @@ import { import { AgeGroup } from '~/components/age-groups/age-group'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; -import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; +import { useGetPercentageData } from '~/components/tables/logic/use-get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; -import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; import { COLOR_FULLY_BOOSTERED, COLOR_FULLY_VACCINATED } from '../common'; @@ -27,7 +26,6 @@ interface BoosterCoveragePerAgeGroupProps { export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text }: BoosterCoveragePerAgeGroupProps) { const breakpoints = useBreakpoints(true); - const { commonTexts, formatPercentage } = useIntl(); const componentName = BoosterShotCoveragePerAgeGroup.name; const requiredData: TableData[] = values.map((value) => { return { @@ -45,7 +43,7 @@ export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, v const percentageTitles = { first: text.vaccination_coverage.headers.fully_vaccinated, second: text.archived.vaccination_coverage.campaign_headers.booster_shot }; const percentageColors = { first: COLOR_FULLY_VACCINATED, second: COLOR_FULLY_BOOSTERED }; const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; - const percentageData = getPercentageData(sortedData, percentageTitles, percentageColors, percentageFormattingRules, commonTexts.common.no_data, formatPercentage); + const percentageData = useGetPercentageData(sortedData, percentageTitles, percentageColors, percentageFormattingRules); return ( diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx index a759fc1fa3..e91fe8fc52 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx @@ -2,11 +2,10 @@ import { GmVaccineCoveragePerAgeGroupArchivedValue, NlVaccineCoveragePerAgeGroup import { AgeGroup } from '~/components/age-groups/age-group'; import { ChartTile } from '~/components/chart-tile'; import { MetadataProps } from '~/components/metadata'; -import { getPercentageData } from '~/components/tables/logic/get-percentage-data'; +import { useGetPercentageData } from '~/components/tables/logic/use-get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; import { TableData } from '~/components/tables/types'; import { WideTable } from '~/components/tables/wide-table'; -import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; import { ARCHIVED_COLORS } from '../common'; @@ -23,7 +22,6 @@ interface VaccineCoveragePerAgeGroupProps { export function VaccineCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text }: VaccineCoveragePerAgeGroupProps) { const breakpoints = useBreakpoints(true); - const { commonTexts, formatPercentage } = useIntl(); const componentName = VaccineCoveragePerAgeGroup.name; const requiredData: TableData[] = values.map((value) => { return { @@ -41,7 +39,7 @@ export function VaccineCoveragePerAgeGroup({ title, description, metadata, value const percentageTitles = { first: text.archived.vaccination_coverage.campaign_headers.first_shot, second: text.archived.vaccination_coverage.campaign_headers.coverage }; const percentageColors = { first: ARCHIVED_COLORS.COLOR_HAS_ONE_SHOT, second: ARCHIVED_COLORS.COLOR_FULLY_VACCINATED }; const percentageFormattingRules = { first: { shouldFormat: true }, second: { shouldFormat: true } }; - const percentageData = getPercentageData(sortedData, percentageTitles, percentageColors, percentageFormattingRules, commonTexts.common.no_data, formatPercentage); + const percentageData = useGetPercentageData(sortedData, percentageTitles, percentageColors, percentageFormattingRules); return ( From 9611cc231991d17c8f55eee21f7045b69f041603 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 26 Jan 2023 12:10:25 +0100 Subject: [PATCH 17/23] feat(table-improvements): Convert all functions to arrow functions. --- .../src/components/age-groups/age-group.tsx | 4 +-- .../app/src/components/percentage-bar.tsx | 27 ++++++++++--------- .../tables/components/narrow-percentage.tsx | 4 +-- .../tables/components/wide-percentage.tsx | 4 +-- .../behavior/behavior-per-age-group-tile.tsx | 4 +-- .../domain/behavior/behavior-table-tile.tsx | 4 +-- .../behavior/components/behavior-trend.tsx | 4 +-- .../booster-shot-coverage-per-age-group.tsx | 4 +-- .../vaccine-coverage-per-age-group.tsx | 4 +-- .../components/narrow-variants-table.tsx | 4 +-- .../components/percentage-bar-with-number.tsx | 4 +-- .../components/variant-difference.tsx | 4 +-- .../components/wide-variants-table.tsx | 4 +-- .../pages/veiligheidsregio/[code]/gedrag.tsx | 6 +++-- .../app/src/utils/format-age-group-string.ts | 4 +-- 15 files changed, 45 insertions(+), 40 deletions(-) diff --git a/packages/app/src/components/age-groups/age-group.tsx b/packages/app/src/components/age-groups/age-group.tsx index c863ec61dc..600fae7b5b 100644 --- a/packages/app/src/components/age-groups/age-group.tsx +++ b/packages/app/src/components/age-groups/age-group.tsx @@ -11,7 +11,7 @@ interface AgeGroupProps { birthYearRange: string; } -export function AgeGroup({ range, peopleInAgeGroup, birthYearRange }: AgeGroupProps) { +export const AgeGroup = ({ range, peopleInAgeGroup, birthYearRange }: AgeGroupProps) => { const { commonTexts, formatNumber } = useIntl(); const ageRange = formatAgeGroupString(range, commonTexts.common.agegroup); const yearOfBirthRange = formatBirthyearRangeString(birthYearRange, commonTexts.common.birthyears); @@ -26,4 +26,4 @@ export function AgeGroup({ range, peopleInAgeGroup, birthYearRange }: AgeGroupPr {`${yearOfBirthRange}${peopleInAgeGroup ? `: ${totalText}` : ''}`} ); -} +}; diff --git a/packages/app/src/components/percentage-bar.tsx b/packages/app/src/components/percentage-bar.tsx index b5f8e5639a..adee713aae 100644 --- a/packages/app/src/components/percentage-bar.tsx +++ b/packages/app/src/components/percentage-bar.tsx @@ -11,9 +11,9 @@ interface PercentageProps { backgroundColor?: string; } -export function PercentageBar({ percentage, height, color, backgroundColor = colors.gray2, backgroundStyle = 'normal' }: PercentageProps) { +export const PercentageBar = ({ percentage, height, color, backgroundColor = colors.gray2, backgroundStyle = 'normal' }: PercentageProps) => { const minWidth = percentage > 0 ? '2px' : undefined; - backgroundColor = backgroundStyle === 'normal' ? backgroundColor ? backgroundColor : 'gray2' : backgroundColor; + backgroundColor = backgroundStyle === 'normal' ? (backgroundColor ? backgroundColor : colors.gray2) : backgroundColor; return ( @@ -21,7 +21,7 @@ export function PercentageBar({ percentage, height, color, backgroundColor = col ); -} +}; interface StyledDivProps { backgroundStyle: string; @@ -31,11 +31,14 @@ interface StyledDivProps { const StyledDiv = styled.div` /* Created by https://stripesgenerator.com/ */ - background-color: ${({backgroundStyle, backgroundColor}) => backgroundStyle !== 'hatched' ? backgroundColor : undefined }; - background-image: ${({backgroundStyle, backgroundColor}) => backgroundStyle === 'hatched' ? `linear-gradient(45deg, ${backgroundColor} 30%, #ffffff 30%, #ffffff 50%, ${backgroundColor} 50%, ${backgroundColor} 80%, #ffffff 80%, #ffffff 100%)` : undefined }; - background-size: ${({backgroundStyle}) => backgroundStyle === 'hatched' ? '7.07px 7.07px' : undefined }; + background-color: ${({ backgroundStyle, backgroundColor }) => (backgroundStyle !== 'hatched' ? backgroundColor : undefined)}; + background-image: ${({ backgroundStyle, backgroundColor }) => + backgroundStyle === 'hatched' + ? `linear-gradient(45deg, ${backgroundColor} 30%, #ffffff 30%, #ffffff 50%, ${backgroundColor} 50%, ${backgroundColor} 80%, #ffffff 80%, #ffffff 100%)` + : undefined}; + background-size: ${({ backgroundStyle }) => (backgroundStyle === 'hatched' ? '7.07px 7.07px' : undefined)}; flex: 1; - height: ${({height}) => height ? height : undefined}; + height: ${({ height }) => (height ? height : undefined)}; left: ${space[0]}; top: ${space[0]}; `; @@ -47,9 +50,9 @@ interface BarProps { } const Bar = styled.div` - background-color: ${({color}) => color ? color : 'currentcolor'}; - height: ${({height}) => height ?? '0.8em'}; - min-width: ${({minWidth}) => minWidth}; - transition: width .3s; + background-color: ${({ color }) => (color ? color : 'currentcolor')}; + height: ${({ height }) => height ?? '0.8em'}; + min-width: ${({ minWidth }) => minWidth}; + transition: width 0.3s; z-index: 3; -` +`; diff --git a/packages/app/src/components/tables/components/narrow-percentage.tsx b/packages/app/src/components/tables/components/narrow-percentage.tsx index d05bd2ff6c..83691cdec7 100644 --- a/packages/app/src/components/tables/components/narrow-percentage.tsx +++ b/packages/app/src/components/tables/components/narrow-percentage.tsx @@ -8,7 +8,7 @@ interface NarrowPercentageProps { textLabel: string; } -export function NarrowPercentage({ value, color, textLabel }: NarrowPercentageProps) { +export const NarrowPercentage = ({ value, color, textLabel }: NarrowPercentageProps) => { return ( @@ -21,4 +21,4 @@ export function NarrowPercentage({ value, color, textLabel }: NarrowPercentagePr ); -} +}; diff --git a/packages/app/src/components/tables/components/wide-percentage.tsx b/packages/app/src/components/tables/components/wide-percentage.tsx index d115355a0c..710c8c5233 100644 --- a/packages/app/src/components/tables/components/wide-percentage.tsx +++ b/packages/app/src/components/tables/components/wide-percentage.tsx @@ -9,14 +9,14 @@ interface PercentageWideNumberProps { justifyContent: string; } -export function WidePercentage({ value, color, justifyContent }: PercentageWideNumberProps) { +export const WidePercentage = ({ value, color, justifyContent }: PercentageWideNumberProps) => { return ( {value} ); -} +}; interface StyledInlineTextProps { justifyContent: string; diff --git a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx index acf8b6f663..0d2e4100c9 100644 --- a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx @@ -30,7 +30,7 @@ interface BehaviorPerAgeGroupProps { metadata: MetadataProps; } -export function BehaviorPerAgeGroup({ title, description, data, currentId, setCurrentId, text, metadata }: BehaviorPerAgeGroupProps) { +export const BehaviorPerAgeGroup = ({ title, description, data, currentId, setCurrentId, text, metadata }: BehaviorPerAgeGroupProps) => { const breakpoints = useBreakpoints(); const complianceValue = data[`${currentId}_compliance` as keyof typeof data]; const supportValue = data[`${currentId}_support` as keyof typeof data]; @@ -89,4 +89,4 @@ export function BehaviorPerAgeGroup({ title, description, data, currentId, setCu ); -} +}; diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index eec1c925ae..a646ee5581 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -30,7 +30,7 @@ interface BehaviorTableTileProps { metadata: MetadataProps; } -export function BehaviorTableTile({ title, description, value, annotation, setCurrentId, scrollRef, text, metadata }: BehaviorTableTileProps) { +export const BehaviorTableTile = ({ title, description, value, annotation, setCurrentId, scrollRef, text, metadata }: BehaviorTableTileProps) => { const breakpoints = useBreakpoints(true); const behaviorsTableData: TableData[] = useBehaviorTableData(value as NlBehaviorValue, { scrollRef, setCurrentId }); const titles = { first: text.basisregels.rules_followed, second: text.basisregels.rules_supported }; @@ -79,7 +79,7 @@ export function BehaviorTableTile({ title, description, value, annotation, setCu ); -} +}; function useBehaviorTableData(value: NlBehaviorValue, onClickConfig: OnClickConfig) { const behaviorLookupKeys = useBehaviorLookupKeys(); diff --git a/packages/app/src/domain/behavior/components/behavior-trend.tsx b/packages/app/src/domain/behavior/components/behavior-trend.tsx index a5b9d213a6..33f783b12d 100644 --- a/packages/app/src/domain/behavior/components/behavior-trend.tsx +++ b/packages/app/src/domain/behavior/components/behavior-trend.tsx @@ -16,7 +16,7 @@ interface BehaviorTrendProps { hasMarginRight?: boolean; } -export function BehaviorTrend({ trend, text, hasMarginRight }: BehaviorTrendProps) { +export const BehaviorTrend = ({ trend, text, hasMarginRight }: BehaviorTrendProps) => { if (trend === 'up') { return ( @@ -40,7 +40,7 @@ export function BehaviorTrend({ trend, text, hasMarginRight }: BehaviorTrendProp } return ; -} +}; interface TrendProps { color: string; diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx index c05cac2019..a7fdc94c7e 100644 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx @@ -24,7 +24,7 @@ interface BoosterCoveragePerAgeGroupProps { text: SiteText['pages']['vaccinations_page']['nl']; } -export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text }: BoosterCoveragePerAgeGroupProps) { +export const BoosterShotCoveragePerAgeGroup = ({ title, description, metadata, values, sortingOrder, text }: BoosterCoveragePerAgeGroupProps) => { const breakpoints = useBreakpoints(true); const componentName = BoosterShotCoveragePerAgeGroup.name; const requiredData: TableData[] = values.map((value) => { @@ -63,4 +63,4 @@ export function BoosterShotCoveragePerAgeGroup({ title, description, metadata, v )} ); -} +}; diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx index e91fe8fc52..008da2c881 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx @@ -20,7 +20,7 @@ interface VaccineCoveragePerAgeGroupProps { text: SiteText['pages']['vaccinations_page']['nl']; } -export function VaccineCoveragePerAgeGroup({ title, description, metadata, values, sortingOrder, text }: VaccineCoveragePerAgeGroupProps) { +export const VaccineCoveragePerAgeGroup = ({ title, description, metadata, values, sortingOrder, text }: VaccineCoveragePerAgeGroupProps) => { const breakpoints = useBreakpoints(true); const componentName = VaccineCoveragePerAgeGroup.name; const requiredData: TableData[] = values.map((value) => { @@ -59,4 +59,4 @@ export function VaccineCoveragePerAgeGroup({ title, description, metadata, value )} ); -} +}; diff --git a/packages/app/src/domain/variants/variants-table-tile/components/narrow-variants-table.tsx b/packages/app/src/domain/variants/variants-table-tile/components/narrow-variants-table.tsx index 029af61faa..43825e873c 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/narrow-variants-table.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/narrow-variants-table.tsx @@ -18,7 +18,7 @@ interface NarrowVariantsTableProps { text: TableText; } -export function NarrowVariantsTable(props: NarrowVariantsTableProps) { +export const NarrowVariantsTable = (props: NarrowVariantsTableProps) => { const intl = useIntl(); const { rows, text } = props; const columnNames = text.kolommen; @@ -47,7 +47,7 @@ export function NarrowVariantsTable(props: NarrowVariantsTableProps) { ); -} +}; interface MobileVariantRowProps { row: VariantRow; diff --git a/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx b/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx index 6167dd8f31..7be7bc5072 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx @@ -8,7 +8,7 @@ interface PercentageBarWithNumberProps { formatValue: (value: number) => string; } -export function PercentageBarWithNumber({ percentage, color, formatValue }: PercentageBarWithNumberProps) { +export const PercentageBarWithNumber = ({ percentage, color, formatValue }: PercentageBarWithNumberProps) => { return ( @@ -19,4 +19,4 @@ export function PercentageBarWithNumber({ percentage, color, formatValue }: Perc ); -} +}; diff --git a/packages/app/src/domain/variants/variants-table-tile/components/variant-difference.tsx b/packages/app/src/domain/variants/variants-table-tile/components/variant-difference.tsx index ee37be1010..3124720e76 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/variant-difference.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/variant-difference.tsx @@ -11,7 +11,7 @@ interface VariantDifferenceProps { value: DifferenceDecimal; } -export function VariantDifference({ value, text, isWideTable }: VariantDifferenceProps) { +export const VariantDifference = ({ value, text, isWideTable }: VariantDifferenceProps) => { const { formatPercentage } = useIntl(); const options = { @@ -58,7 +58,7 @@ export function VariantDifference({ value, text, isWideTable }: VariantDifferenc }); return <>{returnValue}; -} +}; interface DifferenceProps { color: string; diff --git a/packages/app/src/domain/variants/variants-table-tile/components/wide-variants-table.tsx b/packages/app/src/domain/variants/variants-table-tile/components/wide-variants-table.tsx index 921d15de38..2f53067af4 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/wide-variants-table.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/wide-variants-table.tsx @@ -16,7 +16,7 @@ interface WideVariantsTableProps { text: TableText; } -export function WideVariantsTable(props: WideVariantsTableProps) { +export const WideVariantsTable = (props: WideVariantsTableProps) => { const { rows, text } = props; const intl = useIntl(); @@ -65,4 +65,4 @@ export function WideVariantsTable(props: WideVariantsTableProps) { ); -} +}; diff --git a/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx b/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx index 998ff38329..2215800487 100644 --- a/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx +++ b/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx @@ -54,7 +54,7 @@ export const getStaticProps = createGetStaticProps( } ); -export default function BehaviorPageVr(props: StaticProps) { +const BehaviorPageVr = (props: StaticProps) => { const { pageText, lastGenerated, content, selectedVrData: data, vrName, chartBehaviorOptions } = props; const { commonTexts, formatDateFromSeconds, formatNumber } = useIntl(); const { text } = useDynamicLokalizeTexts(pageText, selectLokalizeTexts); @@ -148,4 +148,6 @@ export default function BehaviorPageVr(props: StaticProps ); -} +}; + +export default BehaviorPageVr; diff --git a/packages/app/src/utils/format-age-group-string.ts b/packages/app/src/utils/format-age-group-string.ts index 93828060ac..5b9efab756 100644 --- a/packages/app/src/utils/format-age-group-string.ts +++ b/packages/app/src/utils/format-age-group-string.ts @@ -18,7 +18,7 @@ import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; * @returns */ -export function formatAgeGroupString(ageGroup: string, templates: { oldest: string; group: string;}) { +export const formatAgeGroupString = (ageGroup: string, templates: { oldest: string; group: string }) => { switch (true) { case ageGroup.includes('-'): { const [age_low, age_high] = ageGroup.split('-'); @@ -35,4 +35,4 @@ export function formatAgeGroupString(ageGroup: string, templates: { oldest: stri throw new Error(`Invalid age group ${ageGroup}`); } } -} +}; From 9c0f48218f79da5e1af9ef9da4a63bc7b9614725 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 26 Jan 2023 12:21:22 +0100 Subject: [PATCH 18/23] feat(table-improvements): PR feedback - adding comments, sorting types, adding sanity key. --- packages/app/src/components/age-groups/age-group.tsx | 2 +- .../components/tables/components/wide-percentage-data.tsx | 1 + .../src/components/tables/components/wide-percentage.tsx | 6 +++--- .../app/src/domain/behavior/behavior-per-age-group-tile.tsx | 4 ++-- packages/app/src/domain/behavior/behavior-table-tile.tsx | 2 +- .../autumn-2022-shot-coverage-per-age-group.tsx | 2 +- .../booster-shot-coverage-per-age-group.tsx | 2 +- .../vaccine-coverage-per-age-group.tsx | 2 +- packages/cms/src/lokalize/key-mutations.csv | 3 +++ 9 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/app/src/components/age-groups/age-group.tsx b/packages/app/src/components/age-groups/age-group.tsx index 600fae7b5b..62a0fea0aa 100644 --- a/packages/app/src/components/age-groups/age-group.tsx +++ b/packages/app/src/components/age-groups/age-group.tsx @@ -6,9 +6,9 @@ import { formatBirthyearRangeString } from '~/utils/format-birthyear-range-strin import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; interface AgeGroupProps { + birthYearRange: string; range: string; peopleInAgeGroup?: number; - birthYearRange: string; } export const AgeGroup = ({ range, peopleInAgeGroup, birthYearRange }: AgeGroupProps) => { diff --git a/packages/app/src/components/tables/components/wide-percentage-data.tsx b/packages/app/src/components/tables/components/wide-percentage-data.tsx index c77cd873f4..42b0d98dbe 100644 --- a/packages/app/src/components/tables/components/wide-percentage-data.tsx +++ b/packages/app/src/components/tables/components/wide-percentage-data.tsx @@ -34,6 +34,7 @@ export const PercentageData = ({ percentageDataPoints }: PercentageDataProps) => {percentageDataPoints.map((percentageDataPoint, index) => ( + // In some cases, the percentage value is a string so it needs to be parsed for the progress bar to be filled properly. { +export const WidePercentage = ({ value, color, justifyContent }: WidePercentageProps) => { return ( - + {value} ); diff --git a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx index 0d2e4100c9..7d8b71f408 100644 --- a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx @@ -72,13 +72,13 @@ export const BehaviorPerAgeGroup = ({ title, description, data, currentId, setCu firstColumn: text.shared.leeftijden.tabel.age_group, secondColumn: text.shared.basisregels.rules_followed, thirdColumn: text.shared.basisregels.rules_supported, - fourthColumn: '', + fourthColumn: '', // Intentionally left empty for spacing purposes. }} tableData={requiredData} percentageData={percentageData} /> ) : ( - + ) ) : ( diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index a646ee5581..7d4748fc34 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -45,7 +45,7 @@ export const BehaviorTableTile = ({ title, description, value, annotation, setCu firstColumn: text.basisregels.header_basisregel, secondColumn: text.basisregels.rules_followed, thirdColumn: text.basisregels.rules_supported, - fourthColumn: '', + fourthColumn: '', // Intentionally left empty for spacing purposes. }} tableData={behaviorsTableData} percentageData={percentageData} diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index 83c649ad3a..ca94fe198a 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -49,7 +49,7 @@ export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata firstColumn: text.headers.agegroup, secondColumn: text.headers.autumn_2022_shot, thirdColumn: text.headers.fully_vaccinated, - fourthColumn: '', + fourthColumn: '', // Intentionally left empty for spacing purposes. }} tableData={sortedData} percentageData={percentageData} diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx index a7fdc94c7e..4905f5d679 100644 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx @@ -53,7 +53,7 @@ export const BoosterShotCoveragePerAgeGroup = ({ title, description, metadata, v firstColumn: text.vaccination_coverage.headers.agegroup, secondColumn: text.vaccination_coverage.headers.fully_vaccinated, thirdColumn: text.archived.vaccination_coverage.campaign_headers.booster_shot, - fourthColumn: '', + fourthColumn: '', // Intentionally left empty for spacing purposes. }} tableData={sortedData} percentageData={percentageData} diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx index 008da2c881..505eea3be1 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx @@ -49,7 +49,7 @@ export const VaccineCoveragePerAgeGroup = ({ title, description, metadata, value firstColumn: text.vaccination_coverage.headers.agegroup, secondColumn: text.archived.vaccination_coverage.campaign_headers.first_shot, thirdColumn: text.archived.vaccination_coverage.campaign_headers.coverage, - fourthColumn: '', + fourthColumn: '', // Intentionally left empty for spacing purposes. }} tableData={sortedData} percentageData={percentageData} diff --git a/packages/cms/src/lokalize/key-mutations.csv b/packages/cms/src/lokalize/key-mutations.csv index a1d7be1ba1..396c3cf40f 100644 --- a/packages/cms/src/lokalize/key-mutations.csv +++ b/packages/cms/src/lokalize/key-mutations.csv @@ -11,3 +11,6 @@ timestamp,action,key,document_id,move_to 2023-01-20T16:16:04.215Z,add,pages.behavior_page.shared.basisregels.rules_supported,AE5jpq5sZWNgXeEUcJ13cd,__ 2023-01-23T15:40:31.128Z,add,pages.behavior_page.shared.basisregels.footer_trend_up_annotation,say0BNKaNSuhganBiTKhoE,__ 2023-01-23T15:40:32.050Z,add,pages.behavior_page.shared.basisregels.footer_trend_down_annotation,gwBtgw3hhC8JAGy8EpyiE9,__ +2023-01-26T11:19:17.324Z,add,pages.behavior_page.nl.tabel_per_leeftijdsgroep.narrow_table_header,wvJta9ElXUYLPkPUArz3Ny,__ +2023-01-26T11:19:17.326Z,delete,pages.behavior_page.nl.tabel_per_leeftijdsgroep.explanation.compliance,cnFn4yM5oz3WY1CrntwS2v,__ +2023-01-26T11:19:17.328Z,delete,pages.behavior_page.nl.tabel_per_leeftijdsgroep.explanation.support,Ks5SlP9grM5GaBz68RNpjk,__ From 987fd9b0558221ae2455545c2b21e876306cb509 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 26 Jan 2023 12:30:11 +0100 Subject: [PATCH 19/23] feat(table-improvements): PR feedback. --- packages/app/src/components/age-groups/age-group.tsx | 10 ++++++---- .../app/src/domain/behavior/behavior-table-tile.tsx | 6 +++--- .../behavior/components/behavior-icon-with-label.tsx | 2 +- .../src/domain/behavior/components/behavior-trend.tsx | 6 +++--- .../components/percentage-bar-with-number.tsx | 4 ++-- .../components/shared-table-components.tsx | 2 +- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/app/src/components/age-groups/age-group.tsx b/packages/app/src/components/age-groups/age-group.tsx index 62a0fea0aa..05e3a90948 100644 --- a/packages/app/src/components/age-groups/age-group.tsx +++ b/packages/app/src/components/age-groups/age-group.tsx @@ -16,14 +16,16 @@ export const AgeGroup = ({ range, peopleInAgeGroup, birthYearRange }: AgeGroupPr const ageRange = formatAgeGroupString(range, commonTexts.common.agegroup); const yearOfBirthRange = formatBirthyearRangeString(birthYearRange, commonTexts.common.birthyears); - const totalText = replaceVariablesInText(commonTexts.common.agegroup.total_people, { - total: formatNumber(peopleInAgeGroup), - }); + const totalText = peopleInAgeGroup + ? replaceVariablesInText(commonTexts.common.agegroup.total_people, { + total: formatNumber(peopleInAgeGroup), + }) + : ''; return ( {ageRange} - {`${yearOfBirthRange}${peopleInAgeGroup ? `: ${totalText}` : ''}`} + {`${yearOfBirthRange}: ${totalText}`} ); }; diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index 7d4748fc34..7d689b62fa 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -58,21 +58,21 @@ export const BehaviorTableTile = ({ title, description, value, annotation, setCu - + {text.basisregels.footer_trend_down_annotation} - + {text.basisregels.footer_trend_up_annotation} - + {annotation} diff --git a/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx b/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx index 4735a03384..2343e0595c 100644 --- a/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx +++ b/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx @@ -28,7 +28,7 @@ export const BehaviorIconWithLabel = ({ id, description, onClickConfig }: Behavi return ( - + diff --git a/packages/app/src/domain/behavior/components/behavior-trend.tsx b/packages/app/src/domain/behavior/components/behavior-trend.tsx index 33f783b12d..772585054f 100644 --- a/packages/app/src/domain/behavior/components/behavior-trend.tsx +++ b/packages/app/src/domain/behavior/components/behavior-trend.tsx @@ -16,10 +16,10 @@ interface BehaviorTrendProps { hasMarginRight?: boolean; } -export const BehaviorTrend = ({ trend, text, hasMarginRight }: BehaviorTrendProps) => { +export const BehaviorTrend = ({ trend, text, hasMarginRight = false }: BehaviorTrendProps) => { if (trend === 'up') { return ( - + {text} @@ -28,7 +28,7 @@ export const BehaviorTrend = ({ trend, text, hasMarginRight }: BehaviorTrendProp if (trend === 'down') { return ( - + {text} diff --git a/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx b/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx index 7be7bc5072..572bc5cee8 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx @@ -10,8 +10,8 @@ interface PercentageBarWithNumberProps { export const PercentageBarWithNumber = ({ percentage, color, formatValue }: PercentageBarWithNumberProps) => { return ( - - + + {formatValue(percentage)}% diff --git a/packages/app/src/domain/variants/variants-table-tile/components/shared-table-components.tsx b/packages/app/src/domain/variants/variants-table-tile/components/shared-table-components.tsx index dc7f4af1d6..78d3c4ec21 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/shared-table-components.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/shared-table-components.tsx @@ -34,6 +34,6 @@ export const Cell = styled.td` border-bottom: ${({ border, mobile }) => (border || !mobile ? `1px solid ${colors.gray2}` : undefined)}; float: ${({ alignRight }) => (alignRight ? 'right' : undefined)}; max-width: ${({ narrow }) => (narrow ? space[4] : undefined)}; - padding: ${({ hasPaddingRight }) => (hasPaddingRight ? `${space[3]} ${space[3]} ${space[3]} ${space[0]}` : `${space[3]} ${space[0]}`)}; + padding: ${({ hasPaddingRight }) => (hasPaddingRight ? `${space[3]} ${space[3]} ${space[3]} 0` : `${space[3]} 0`)}; vertical-align: top; `; From 0426790a3e0f2e93fc98158fd0878bdd98b6b996 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Thu, 26 Jan 2023 15:45:48 +0100 Subject: [PATCH 20/23] feat(table-improvements): Changes in design - added a column header for the percentage bar column to all relevant tables. --- .../app/src/domain/behavior/behavior-per-age-group-tile.tsx | 2 +- packages/app/src/domain/behavior/behavior-table-tile.tsx | 4 +--- .../autumn-2022-shot-coverage-per-age-group.tsx | 2 +- .../booster-shot-coverage-per-age-group.tsx | 2 +- .../vaccine-coverage-per-age-group.tsx | 2 +- packages/app/src/pages/landelijk/gedrag.tsx | 2 -- packages/cms/src/lokalize/key-mutations.csv | 1 + 7 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx index 7d8b71f408..d09a4470bd 100644 --- a/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-per-age-group-tile.tsx @@ -72,7 +72,7 @@ export const BehaviorPerAgeGroup = ({ title, description, data, currentId, setCu firstColumn: text.shared.leeftijden.tabel.age_group, secondColumn: text.shared.basisregels.rules_followed, thirdColumn: text.shared.basisregels.rules_supported, - fourthColumn: '', // Intentionally left empty for spacing purposes. + fourthColumn: text.shared.basisregels.percentage_bar_column_header, }} tableData={requiredData} percentageData={percentageData} diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index 7d689b62fa..a1816b1c8a 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -20,8 +20,6 @@ import { useBehaviorLookupKeys } from './logic/use-behavior-lookup-keys'; interface BehaviorTableTileProps { title: string; description: string; - complianceExplanation: string; - supportExplanation: string; value: NlBehaviorValue | VrBehaviorArchived_20221019Value; annotation: string; setCurrentId: React.Dispatch>; @@ -45,7 +43,7 @@ export const BehaviorTableTile = ({ title, description, value, annotation, setCu firstColumn: text.basisregels.header_basisregel, secondColumn: text.basisregels.rules_followed, thirdColumn: text.basisregels.rules_supported, - fourthColumn: '', // Intentionally left empty for spacing purposes. + fourthColumn: text.basisregels.percentage_bar_column_header, }} tableData={behaviorsTableData} percentageData={percentageData} diff --git a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx index ca94fe198a..2d9c320183 100644 --- a/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/autumn-2022-shot-coverage-per-age-group/autumn-2022-shot-coverage-per-age-group.tsx @@ -49,7 +49,7 @@ export const Autumn2022ShotCoveragePerAgeGroup = ({ title, description, metadata firstColumn: text.headers.agegroup, secondColumn: text.headers.autumn_2022_shot, thirdColumn: text.headers.fully_vaccinated, - fourthColumn: '', // Intentionally left empty for spacing purposes. + fourthColumn: text.headers.difference_autumn_2022_shot_and_fully_vaccinated, }} tableData={sortedData} percentageData={percentageData} diff --git a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx index 4905f5d679..008389a604 100644 --- a/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/booster-shot-coverage-per-age-group/booster-shot-coverage-per-age-group.tsx @@ -53,7 +53,7 @@ export const BoosterShotCoveragePerAgeGroup = ({ title, description, metadata, v firstColumn: text.vaccination_coverage.headers.agegroup, secondColumn: text.vaccination_coverage.headers.fully_vaccinated, thirdColumn: text.archived.vaccination_coverage.campaign_headers.booster_shot, - fourthColumn: '', // Intentionally left empty for spacing purposes. + fourthColumn: text.archived.vaccination_coverage.headers.difference_booster_shot_and_fully_vaccinated, }} tableData={sortedData} percentageData={percentageData} diff --git a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx index 505eea3be1..adf7828bb5 100644 --- a/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/vaccine-coverage-per-age-group/vaccine-coverage-per-age-group.tsx @@ -49,7 +49,7 @@ export const VaccineCoveragePerAgeGroup = ({ title, description, metadata, value firstColumn: text.vaccination_coverage.headers.agegroup, secondColumn: text.archived.vaccination_coverage.campaign_headers.first_shot, thirdColumn: text.archived.vaccination_coverage.campaign_headers.coverage, - fourthColumn: '', // Intentionally left empty for spacing purposes. + fourthColumn: text.archived.vaccination_coverage.headers.difference, }} tableData={sortedData} percentageData={percentageData} diff --git a/packages/app/src/pages/landelijk/gedrag.tsx b/packages/app/src/pages/landelijk/gedrag.tsx index 1482a357b3..26d75a8d62 100644 --- a/packages/app/src/pages/landelijk/gedrag.tsx +++ b/packages/app/src/pages/landelijk/gedrag.tsx @@ -167,8 +167,6 @@ export default function BehaviorPage(props: StaticProps) Date: Thu, 26 Jan 2023 15:59:59 +0100 Subject: [PATCH 21/23] feat(table-improvements): PR feedback part 78. --- packages/app/src/components/percentage-bar.tsx | 1 - .../tables/components/percentage-bar-without-number.tsx | 7 ++++--- .../behavior/components/behavior-icon-with-label.tsx | 2 +- .../components/percentage-bar-with-number.tsx | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/app/src/components/percentage-bar.tsx b/packages/app/src/components/percentage-bar.tsx index adee713aae..53a06388af 100644 --- a/packages/app/src/components/percentage-bar.tsx +++ b/packages/app/src/components/percentage-bar.tsx @@ -13,7 +13,6 @@ interface PercentageProps { export const PercentageBar = ({ percentage, height, color, backgroundColor = colors.gray2, backgroundStyle = 'normal' }: PercentageProps) => { const minWidth = percentage > 0 ? '2px' : undefined; - backgroundColor = backgroundStyle === 'normal' ? (backgroundColor ? backgroundColor : colors.gray2) : backgroundColor; return ( diff --git a/packages/app/src/components/tables/components/percentage-bar-without-number.tsx b/packages/app/src/components/tables/components/percentage-bar-without-number.tsx index ddac4e6293..83938d519a 100644 --- a/packages/app/src/components/tables/components/percentage-bar-without-number.tsx +++ b/packages/app/src/components/tables/components/percentage-bar-without-number.tsx @@ -1,7 +1,8 @@ import { Box } from '~/components/base'; import { PercentageBar } from '~/components/percentage-bar'; +import { space } from '~/style/theme'; -interface PercentageBarWithoutNumberProps { +interface PercentageBarWithoutNumberProps { color: string; percentage: number; marginBottom?: string; @@ -11,8 +12,8 @@ export const PercentageBarWithoutNumber = ({ color, percentage, marginBottom }: return ( - + ); -} \ No newline at end of file +}; diff --git a/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx b/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx index 2343e0595c..982cb983a4 100644 --- a/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx +++ b/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx @@ -28,7 +28,7 @@ export const BehaviorIconWithLabel = ({ id, description, onClickConfig }: Behavi return ( - + diff --git a/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx b/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx index 572bc5cee8..aa12d9a08b 100644 --- a/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx +++ b/packages/app/src/domain/variants/variants-table-tile/components/percentage-bar-with-number.tsx @@ -1,6 +1,7 @@ import { Box } from '~/components/base'; import { PercentageBar } from '~/components/percentage-bar'; import { InlineText } from '~/components/typography'; +import { space } from '~/style/theme'; interface PercentageBarWithNumberProps { percentage: number; @@ -10,7 +11,7 @@ interface PercentageBarWithNumberProps { export const PercentageBarWithNumber = ({ percentage, color, formatValue }: PercentageBarWithNumberProps) => { return ( - + {formatValue(percentage)}% From 5f1ba024309ddc6d7b37af86150191d0fe92ffd7 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Tue, 31 Jan 2023 10:31:17 +0100 Subject: [PATCH 22/23] feat(table-consistency): PR feedback. --- .../src/domain/behavior/components/behavior-icon-with-label.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx b/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx index 982cb983a4..ebe51589ab 100644 --- a/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx +++ b/packages/app/src/domain/behavior/components/behavior-icon-with-label.tsx @@ -32,7 +32,7 @@ export const BehaviorIconWithLabel = ({ id, description, onClickConfig }: Behavi - anchorButtonClickHandler(id, onClickConfig.scrollRef)}> + anchorButtonClickHandler(id, onClickConfig.scrollRef)}> {description} From 3ba8f175af84789f83ac5b6097ad8133e1ee3106 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard28 Date: Tue, 31 Jan 2023 11:19:37 +0100 Subject: [PATCH 23/23] feat(table-consistency):Remove props again. --- packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx b/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx index acae749136..ddb70ea159 100644 --- a/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx +++ b/packages/app/src/pages/veiligheidsregio/[code]/gedrag.tsx @@ -122,8 +122,6 @@ const BehaviorPageVr = (props: StaticProps) => {