diff --git a/packages/app/src/components/chart-tile-double-column.tsx b/packages/app/src/components/chart-tile-double-column.tsx index 2f7d7b7ce3..c7c199f073 100644 --- a/packages/app/src/components/chart-tile-double-column.tsx +++ b/packages/app/src/components/chart-tile-double-column.tsx @@ -1,13 +1,13 @@ -import { ReactNode } from 'react'; -import css from '@styled-system/css'; import { asResponsiveArray } from '~/style/utils'; import { Box } from './base'; import { ErrorBoundary } from './error-boundary'; import { FullscreenChartTile } from './fullscreen-chart-tile'; import { Heading } from './typography'; import { Markdown } from './markdown'; -import { MetadataProps } from '~/components/metadata'; +import { MetadataProps } from './metadata/types'; +import { ReactNode } from 'react'; import { space } from '~/style/theme'; +import css from '@styled-system/css'; interface ChartTileDoubleColumnProps { title: string; diff --git a/packages/app/src/components/chart-tile.tsx b/packages/app/src/components/chart-tile.tsx index 6f65e6f571..e91fdb88c7 100644 --- a/packages/app/src/components/chart-tile.tsx +++ b/packages/app/src/components/chart-tile.tsx @@ -1,15 +1,15 @@ -import { TimeframeOption } from '@corona-dashboard/common'; -import { ReactNode, useEffect, useState } from 'react'; -import styled from 'styled-components'; -import theme, { space } from '~/style/theme'; import { Box, Spacer } from './base'; import { ChartTileToggle, ChartTileToggleProps } from './chart-tile-toggle'; import { ChartTimeControls } from './chart-time-controls'; import { ErrorBoundary } from './error-boundary'; import { FullscreenChartTile } from './fullscreen-chart-tile'; -import { Markdown } from './markdown'; -import { MetadataProps } from '~/components/metadata'; import { Heading } from './typography'; +import { Markdown } from './markdown'; +import { MetadataProps } from './metadata/types'; +import { ReactNode, useEffect, useState } from 'react'; +import { TimeframeOption } from '@corona-dashboard/common'; +import styled from 'styled-components'; +import theme, { space } from '~/style/theme'; interface ChartTileProps { children: ReactNode; diff --git a/packages/app/src/components/choropleth-tile.tsx b/packages/app/src/components/choropleth-tile.tsx index f9efe420bb..f47b407092 100644 --- a/packages/app/src/components/choropleth-tile.tsx +++ b/packages/app/src/components/choropleth-tile.tsx @@ -1,14 +1,15 @@ -import { ChoroplethThresholdsValue } from '@corona-dashboard/common'; -import { space } from '~/style/theme'; -import { ChoroplethLegenda } from '~/components/choropleth-legenda'; -import { useBreakpoints } from '~/utils/use-breakpoints'; import { Box } from './base'; +import { CalendarGear } from '@corona-dashboard/icons'; import { ChartRegionControls, RegionControlOption } from './chart-region-controls'; +import { ChoroplethLegenda } from '~/components/choropleth-legenda'; +import { ChoroplethThresholdsValue } from '@corona-dashboard/common'; import { ErrorBoundary } from './error-boundary'; import { FullscreenChartTile } from './fullscreen-chart-tile'; -import { MetadataProps } from '~/components/metadata'; import { Heading, Text } from './typography'; -import { CalendarGear } from '@corona-dashboard/icons'; +import { MetadataProps } from './metadata/types'; +import { space } from '~/style/theme'; +import { useBreakpoints } from '~/utils/use-breakpoints'; + type ChoroplethTileProps = { title: string; description?: string | React.ReactNode; diff --git a/packages/app/src/components/fullscreen-chart-tile.tsx b/packages/app/src/components/fullscreen-chart-tile.tsx index e40a3594ca..60f2aa00b8 100644 --- a/packages/app/src/components/fullscreen-chart-tile.tsx +++ b/packages/app/src/components/fullscreen-chart-tile.tsx @@ -1,18 +1,19 @@ -import { colors } from '@corona-dashboard/common'; +import { Box } from './base/box'; import { Close, Expand } from '@corona-dashboard/icons'; -import { useEffect, useRef, useState } from 'react'; -import styled from 'styled-components'; -import { Tile } from '~/components/tile'; -import { useIntl } from '~/intl'; -import { space } from '~/style/theme'; +import { colors } from '@corona-dashboard/common'; +import { IconButton } from './icon-button'; +import { Metadata } from '~/components/metadata'; +import { MetadataProps } from './metadata/types'; +import { Modal } from './modal'; import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; +import { space } from '~/style/theme'; +import { Spacer } from './base'; +import { Tile } from '~/components/tile'; import { useBreakpoints } from '~/utils/use-breakpoints'; +import { useEffect, useRef, useState } from 'react'; +import { useIntl } from '~/intl'; import { usePrevious } from '~/utils/use-previous'; -import { Spacer } from './base'; -import { Box } from './base/box'; -import { IconButton } from './icon-button'; -import { Metadata, MetadataProps } from '~/components/metadata'; -import { Modal } from './modal'; +import styled from 'styled-components'; interface FullscreenChartTileProps { children: React.ReactNode; diff --git a/packages/app/src/components/kpi-tile.tsx b/packages/app/src/components/kpi-tile.tsx index 80d83cb9cf..06534a58bb 100644 --- a/packages/app/src/components/kpi-tile.tsx +++ b/packages/app/src/components/kpi-tile.tsx @@ -1,9 +1,11 @@ -import { Markdown } from '~/components/markdown'; -import { Tile } from '~/components/tile'; -import { fontSizes } from '~/style/theme'; import { Box } from './base'; -import { Metadata, MetadataProps } from '~/components/metadata'; +import { fontSizes } from '~/style/theme'; import { Heading } from './typography'; +import { Markdown } from '~/components/markdown'; +import { Metadata } from '~/components/metadata'; +import { MetadataProps } from './metadata/types'; +import { Tile } from '~/components/tile'; + interface KpiTileProps { title?: string; description?: string; diff --git a/packages/app/src/components/kpi/bordered-kpi-section.tsx b/packages/app/src/components/kpi/bordered-kpi-section.tsx index d21650fc37..51df98694a 100644 --- a/packages/app/src/components/kpi/bordered-kpi-section.tsx +++ b/packages/app/src/components/kpi/bordered-kpi-section.tsx @@ -3,11 +3,11 @@ import styled from 'styled-components'; import { Box } from '~/components/base'; import { mediaQueries, space } from '~/style/theme'; import { KpiTile } from '../kpi-tile'; -import { MetadataProps } from '~/components/metadata'; import { TwoKpiSection } from '../two-kpi-section'; import { KpiContent } from './components/kpi-content'; import { BorderedKpiSectionProps } from './types'; import { Markdown } from '../markdown'; +import { MetadataProps } from '../metadata/types'; export const BorderedKpiSection = ({ title, description, source, dateOrRange, tilesData, disclaimer }: BorderedKpiSectionProps) => { const metadata: MetadataProps = { diff --git a/packages/app/src/components/kpi/components/kpi-content.tsx b/packages/app/src/components/kpi/components/kpi-content.tsx index 3304d511ee..41f4dcca66 100644 --- a/packages/app/src/components/kpi/components/kpi-content.tsx +++ b/packages/app/src/components/kpi/components/kpi-content.tsx @@ -1,14 +1,14 @@ +import { Bar } from '~/domain/vaccine/components/bar'; +import { BoldText } from '~/components/typography'; import { Box } from '~/components/base'; import { KpiValue } from '~/components/kpi-value'; import { Markdown } from '~/components/markdown'; -import { BoldText } from '~/components/typography'; -import { Bar } from '~/domain/vaccine/components/bar'; +import { Metadata, MetadataProps } from '~/components'; import { parseBirthyearRange } from '~/domain/vaccine/logic/parse-birthyear-range'; -import { useIntl } from '~/intl'; -import { space } from '~/style/theme'; import { replaceVariablesInText } from '~/utils'; +import { space } from '~/style/theme'; import { TileData as KpiContentProps } from '../types'; -import { Metadata, MetadataProps } from '~/components'; +import { useIntl } from '~/intl'; export const KpiContent = ({ title, description, value, bar, birthyear, differenceValue, isPercentage = false, dateOrRange, source }: KpiContentProps) => { const { commonTexts } = useIntl(); diff --git a/packages/app/src/components/lokalize-metadata.tsx b/packages/app/src/components/lokalize-metadata.tsx index 22abdb135c..31e6fc5424 100644 --- a/packages/app/src/components/lokalize-metadata.tsx +++ b/packages/app/src/components/lokalize-metadata.tsx @@ -1,7 +1,7 @@ -import { useIntl } from '~/intl'; import { Box } from '~/components/base'; -import { Text } from '~/components/typography'; import { space } from '~/style/theme'; +import { Text } from '~/components/typography'; +import { useIntl } from '~/intl'; export interface MetadataProps { date: string; diff --git a/packages/app/src/components/metadata/components/page-information-block-metadata.tsx b/packages/app/src/components/metadata/components/page-information-block-metadata.tsx index 2d975cff10..8b6b0d4eb8 100644 --- a/packages/app/src/components/metadata/components/page-information-block-metadata.tsx +++ b/packages/app/src/components/metadata/components/page-information-block-metadata.tsx @@ -1,11 +1,11 @@ import { Box } from '~/components/base'; import { Clock, Database, MeerInformatie } from '@corona-dashboard/icons'; import { colors } from '@corona-dashboard/common'; -import React from 'react'; import { MetadataItem } from '~/components/metadata/components/items/metadata-item'; import { MetadataProps } from '~/components'; -import { useIntl } from '~/intl'; import { MetadataReference } from '~/components/metadata/components/items/metadata-reference'; +import { useIntl } from '~/intl'; +import React from 'react'; interface PageInformationBlockMetadataProps extends MetadataProps { dateText: string | undefined; diff --git a/packages/app/src/components/metadata/components/tile-footer-metadata.tsx b/packages/app/src/components/metadata/components/tile-footer-metadata.tsx index b49eca484b..35330037a6 100644 --- a/packages/app/src/components/metadata/components/tile-footer-metadata.tsx +++ b/packages/app/src/components/metadata/components/tile-footer-metadata.tsx @@ -1,15 +1,14 @@ -import { space } from '~/style/theme'; -import { Text } from '~/components/typography'; -import { replaceVariablesInText } from '~/utils'; import { Box } from '~/components/base'; import { Calendar, Clock, Database } from '@corona-dashboard/icons'; import { colors } from '@corona-dashboard/common'; -import { insertDateIntoString } from '~/components/metadata/logic/insert-date-into-string'; import { Markdown, MetadataProps } from '~/components'; -import React from 'react'; +import { MetadataIcon } from '~/components/metadata/components/items/metadata-icon'; import { MetadataItem } from '~/components/metadata/components/items/metadata-item'; +import { replaceVariablesInText } from '~/utils'; +import { space } from '~/style/theme'; +import { Text } from '~/components/typography'; import { useIntl } from '~/intl'; -import { MetadataIcon } from '~/components/metadata/components/items/metadata-icon'; +import React from 'react'; interface TileFooterMetadataProps extends MetadataProps { dateString: string | null; @@ -28,7 +27,7 @@ interface TileFooterMetadataProps extends MetadataProps { * @param {string} props.datumsText - Textual representation of the metadata date. * @param {(number|DateRange|string)} props.date - Date of the metadata item. It can be a number, a DateRange object, or a string. * @param {DateRange} props.datePeriod - Date range for the metadata. - * @param {number} props.dateOfInsertionUnix - Unix timestamp of when the metadata was inserted. + * @param {number} props.dateOfInsertion - Unix timestamp of when the metadata was inserted. * @param {boolean} props.isArchivedGraph - Flag indicating whether the metadata is for an archived graph. * @param {Source} props.source - Source of the metadata. * @param {Source[]} [props.dataSources=[]] - Array of data sources for the metadata. @@ -39,19 +38,19 @@ interface TileFooterMetadataProps extends MetadataProps { * @returns {ReactElement} A React element that contains the tile footer with metadata items. */ export function TileFooterMetadata({ + dataSources = [], + date, + dateOfInsertion, dateString, - marginBottom, datumsText, - date, - datePeriod, - dateOfInsertionUnix, - isArchivedGraph, - source, - dataSources = [], - referenceLink, disclaimer, - obtainedAt, intervalString, + isArchivedGraph, + marginBottom, + obtainedAt, + referenceLink, + source, + timeframePeriod, }: TileFooterMetadataProps) { const { commonTexts, formatDateFromSeconds } = useIntl(); const metadataText = commonTexts.common.metadata; @@ -66,35 +65,33 @@ export function TileFooterMetadata({ }) ) : ( <> - {datePeriod && ( + {timeframePeriod && ( {replaceVariablesInText(commonTexts.common.metadata.time_interval, { - dateStart: formatDateFromSeconds(datePeriod.start, 'weekday-long'), - dateEnd: formatDateFromSeconds(datePeriod.end, 'weekday-long'), + dateStart: formatDateFromSeconds(timeframePeriod.start, 'weekday-long'), + dateEnd: formatDateFromSeconds(timeframePeriod.end, 'weekday-long'), })} )} - {dateOfInsertionUnix && ( - } - items={[ - { - text: insertDateIntoString( - formatDateFromSeconds, - isArchivedGraph ? commonTexts.common.metadata.last_insertion_date_archived : commonTexts.common.metadata.last_insertion_date, - dateOfInsertionUnix, - dateOfInsertionUnix, - 'weekday-long' - ), - }, - ]} - /> + {dateOfInsertion && ( + + + + + + {isArchivedGraph + ? replaceVariablesInText(commonTexts.common.metadata.last_insertion_date_archived, { + dateOfInsertion: formatDateFromSeconds(dateOfInsertion, 'weekday-long'), + }) + : replaceVariablesInText(commonTexts.common.metadata.last_insertion_date, { dateOfInsertion: formatDateFromSeconds(dateOfInsertion, 'weekday-long') })} + + )} {source ? ( diff --git a/packages/app/src/components/metadata/metadata.tsx b/packages/app/src/components/metadata/metadata.tsx index af5c0d9dad..4f56068b7f 100644 --- a/packages/app/src/components/metadata/metadata.tsx +++ b/packages/app/src/components/metadata/metadata.tsx @@ -1,14 +1,14 @@ import { External as ExternalLinkIcon } from '@corona-dashboard/icons'; import { ExternalLink } from '~/components/external-link'; -import { Text } from '../typography'; -import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; -import { space } from '~/style/theme'; -import { useIntl } from '~/intl'; -import React from 'react'; import { insertDateIntoString } from '~/components/metadata/logic/insert-date-into-string'; import { MetadataProps } from './types'; import { PageInformationBlockMetadata } from '~/components/metadata/components/page-information-block-metadata'; +import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; +import { space } from '~/style/theme'; +import { Text } from '../typography'; import { TileFooterMetadata } from '~/components/metadata/components/tile-footer-metadata'; +import { useIntl } from '~/intl'; +import React from 'react'; /** * @function @@ -20,25 +20,25 @@ import { TileFooterMetadata } from '~/components/metadata/components/tile-footer * @returns {JSX.Element} JSX Element that represents metadata information. */ export function Metadata({ + accessibilitySubject, dataSources = [], date, - dateOfInsertionUnix, - datePeriod, + dateOfInsertion, + dateOrRange, datumsText, disclaimer, intervalCount, isArchivedGraph = false, - isTileFooter, isPageInformationBlock, + isTileFooter, + jsonSources = [], marginBottom, - obtainedAt, - source, - dateOrRange, - accessibilitySubject, moreInformationLabel, moreInformationLink, + obtainedAt, referenceLink, - jsonSources = [], + source, + timeframePeriod, }: MetadataProps) { const { commonTexts, formatDateFromSeconds } = useIntl(); @@ -56,7 +56,7 @@ export function Metadata({ }) : null; - const dateText = datumsText && dateOfInsertionUnix && dateOrRange ? insertDateIntoString(formatDateFromSeconds, datumsText, dateOfInsertionUnix, dateOrRange) : undefined; + const dateText = datumsText && dateOfInsertion && dateOrRange ? insertDateIntoString(formatDateFromSeconds, datumsText, dateOfInsertion, dateOrRange) : undefined; const intervalString = intervalCount && @@ -94,8 +94,8 @@ export function Metadata({ marginBottom={marginBottom} datumsText={datumsText} date={date} - datePeriod={datePeriod} - dateOfInsertionUnix={dateOfInsertionUnix} + timeframePeriod={timeframePeriod} + dateOfInsertion={dateOfInsertion} isArchivedGraph={isArchivedGraph} source={source} dataSources={dataSources} diff --git a/packages/app/src/components/metadata/types.ts b/packages/app/src/components/metadata/types.ts index 1c0e4e7894..290b4689a7 100644 --- a/packages/app/src/components/metadata/types.ts +++ b/packages/app/src/components/metadata/types.ts @@ -48,7 +48,7 @@ export interface DateRange { * @property {string} [intervalCount] - Interval count for the metadata. * @property {string} [disclaimer] - Disclaimer text for the metadata. * @property {DateRange} [datePeriod] - Date range for the metadata. - * @property {number} [dateOfInsertionUnix] - Unix timestamp of when the metadata was inserted. + * @property {number} [dateOfInsertion] - Unix timestamp of when the metadata was inserted. * @property {boolean} [isArchivedGraph] - Flag indicating whether the metadata is for an archived graph. * @property {number|DateRange} [dateOrRange] - Date or date range of the metadata. * @property {string} [accessibilitySubject] - Accessibility subject text for the metadata. @@ -68,8 +68,8 @@ export type MetadataProps = { datumsText?: string; intervalCount?: string; disclaimer?: string; - datePeriod?: DateRange; - dateOfInsertionUnix?: number; + timeframePeriod?: DateRange; + dateOfInsertion?: number; isArchivedGraph?: boolean; dateOrRange?: number | DateRange; accessibilitySubject?: string; diff --git a/packages/app/src/components/page-information-block/page-information-block.tsx b/packages/app/src/components/page-information-block/page-information-block.tsx index 8d974ef189..34cc5f2fa4 100644 --- a/packages/app/src/components/page-information-block/page-information-block.tsx +++ b/packages/app/src/components/page-information-block/page-information-block.tsx @@ -1,19 +1,20 @@ -import { colors } from '@corona-dashboard/common'; -import { ChevronDown, ChevronRight, Warning } from '@corona-dashboard/icons'; -import { ReactNode, isValidElement } from 'react'; -import styled from 'styled-components'; +import { Anchor, BoldText } from '~/components/typography'; import { Box } from '~/components/base'; -import { RichContent } from '~/components/cms/rich-content'; +import { ChevronDown, ChevronRight, Warning } from '@corona-dashboard/icons'; +import { colors } from '@corona-dashboard/common'; +import { Header } from './components/header'; import { Markdown } from '~/components/markdown'; -import { Anchor, BoldText } from '~/components/typography'; -import { WarningTile } from '~/components/warning-tile'; -import { useIntl } from '~/intl'; import { mediaQueries, radii, space } from '~/style/theme'; +import { Metadata } from '~/components/metadata/metadata'; +import { MetadataProps } from '../metadata/types'; +import { PageLinks } from './components/page-links'; +import { ReactNode, isValidElement } from 'react'; +import { RichContent } from '~/components/cms/rich-content'; import { RichContentBlock } from '~/types/cms'; +import { useIntl } from '~/intl'; import { useScopedWarning } from '~/utils/use-scoped-warning'; -import { Header } from './components/header'; -import { Metadata, MetadataProps } from '~/components/metadata'; -import { PageLinks } from './components/page-links'; +import { WarningTile } from '~/components/warning-tile'; +import styled from 'styled-components'; interface InformationBlockProps { title?: string; diff --git a/packages/app/src/components/time-series-chart/time-series-chart.tsx b/packages/app/src/components/time-series-chart/time-series-chart.tsx index 20db305ec7..b29c75e2bc 100644 --- a/packages/app/src/components/time-series-chart/time-series-chart.tsx +++ b/packages/app/src/components/time-series-chart/time-series-chart.tsx @@ -135,13 +135,13 @@ export type TimeSeriesChartProps void; + onHandleTimeframePeriodChange?: (value: DateRange | undefined) => void; /** * By default markers for all series are displayed on hover, also the tooltip @@ -177,7 +177,7 @@ export function TimeSeriesChart { - if (onHandleTimeIntervalChange) { - if (isDateSpanSeries(values)) { - onHandleTimeIntervalChange({ + if (onHandleTimeframePeriodChange) { + if (values.length == 0) { + onHandleTimeframePeriodChange(undefined); + } else if (isDateSpanSeries(values)) { + onHandleTimeframePeriodChange({ start: values[0] ? values[0].date_start_unix : 0, end: values[values.length - 1] ? values[values.length - 1].date_end_unix : 0, }); } else if (isDateSeries(values)) { - onHandleTimeIntervalChange({ start: values[0] ? values[0].date_unix : 0, end: values[values.length - 1] ? values[values.length - 1].date_unix : 0 }); + onHandleTimeframePeriodChange({ start: values[0] ? values[0].date_unix : 0, end: values[values.length - 1] ? values[values.length - 1].date_unix : 0 }); } } - }, [values, timeframe, onHandleTimeIntervalChange]); + }, [timeframe, onHandleTimeframePeriodChange]); const cutValuesConfig = useMemo(() => extractCutValuesConfig(timespanAnnotations), [timespanAnnotations]); diff --git a/packages/app/src/domain/behavior/behavior-line-chart-tile.tsx b/packages/app/src/domain/behavior/behavior-line-chart-tile.tsx index 3c1b1d6c48..3d19f7f4ed 100644 --- a/packages/app/src/domain/behavior/behavior-line-chart-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-line-chart-tile.tsx @@ -1,19 +1,19 @@ -import { colors, ArchivedNlBehaviorValue } from '@corona-dashboard/common'; -import { dropRightWhile, dropWhile } from 'lodash'; -import { useMemo } from 'react'; -import { isPresent } from 'ts-is-present'; +import { BehaviorIdentifier } from './logic/behavior-types'; +import { BoldText } from '~/components/typography'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; +import { colors, ArchivedNlBehaviorValue } from '@corona-dashboard/common'; +import { dropRightWhile, dropWhile } from 'lodash'; import { InlineTooltip } from '~/components/inline-tooltip'; -import { MetadataProps } from '~/components/metadata'; +import { isPresent } from 'ts-is-present'; +import { MetadataProps } from '~/components/metadata/types'; +import { SelectBehavior } from './components/select-behavior'; import { SeriesConfig, TimeSeriesChart } from '~/components/time-series-chart'; -import { TimelineEventConfig } from '~/components/time-series-chart/components/timeline'; -import { BoldText } from '~/components/typography'; import { SiteText } from '~/locale'; import { space } from '~/style/theme'; +import { TimelineEventConfig } from '~/components/time-series-chart/components/timeline'; import { useBreakpoints } from '~/utils/use-breakpoints'; -import { SelectBehavior } from './components/select-behavior'; -import { BehaviorIdentifier } from './logic/behavior-types'; +import { useMemo } from 'react'; type ValueType = ArchivedNlBehaviorValue; type ValueKey = keyof ValueType; 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 c2c96704eb..801def0d98 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 @@ -3,7 +3,6 @@ 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 { 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'; @@ -17,6 +16,7 @@ import { assert } from '~/utils/assert'; import { useBreakpoints } from '~/utils/use-breakpoints'; import { SelectBehavior } from './components/select-behavior'; import { BehaviorIdentifier } from './logic/behavior-types'; +import { MetadataProps } from '~/components/metadata/types'; const AGE_GROUPS_KEYS = ['70_plus', '55_69', '40_54', '25_39', '16_24'] as const; diff --git a/packages/app/src/domain/behavior/behavior-table-tile.tsx b/packages/app/src/domain/behavior/behavior-table-tile.tsx index 8812e73d66..26fa74af2e 100644 --- a/packages/app/src/domain/behavior/behavior-table-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-table-tile.tsx @@ -1,21 +1,21 @@ -import { colors, ArchivedNlBehaviorValue } from '@corona-dashboard/common'; -import React, { useMemo } from 'react'; -import { isDefined, isPresent } from 'ts-is-present'; +import { BehaviorIconWithLabel, OnClickConfig } from './components/behavior-icon-with-label'; +import { BehaviorIdentifier } from './logic/behavior-types'; +import { BehaviorTrend } from './components/behavior-trend'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; -import { MetadataProps } from '~/components/metadata'; -import { useGetPercentageData } from '~/components/tables/logic/use-get-percentage-data'; +import { colors, ArchivedNlBehaviorValue } from '@corona-dashboard/common'; +import { isDefined, isPresent } from 'ts-is-present'; +import { MetadataProps } from '~/components/metadata/types'; 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 { TableData } from '~/components/tables/types'; +import { Text } from '~/components/typography'; import { useBehaviorLookupKeys } from './logic/use-behavior-lookup-keys'; +import { useBreakpoints } from '~/utils/use-breakpoints'; +import { useGetPercentageData } from '~/components/tables/logic/use-get-percentage-data'; +import { WideTable } from '~/components/tables/wide-table'; +import React, { useMemo } from 'react'; interface BehaviorTableTileProps { title: string; diff --git a/packages/app/src/domain/hospital/admissions-per-age-group/admissions-per-age-group.tsx b/packages/app/src/domain/hospital/admissions-per-age-group/admissions-per-age-group.tsx index 768a998506..0a7717c91d 100644 --- a/packages/app/src/domain/hospital/admissions-per-age-group/admissions-per-age-group.tsx +++ b/packages/app/src/domain/hospital/admissions-per-age-group/admissions-per-age-group.tsx @@ -1,19 +1,20 @@ +import { AccessibilityDefinition } from '~/utils/use-accessibility-annotations'; +import { BASE_SERIES_CONFIG } from './series-config'; +import { DateRange } from '~/components/metadata'; import { DAY_IN_SECONDS, NlHospitalNicePerAgeGroupValue, NlIntensiveCareNicePerAgeGroupValue, TimeframeOption } from '@corona-dashboard/common'; -import { Spacer } from '~/components/base'; import { ErrorBoundary } from '~/components/error-boundary'; +import { getBoundaryDateStartUnix } from '~/utils/get-boundary-date-start-unix'; import { InteractiveLegend, SelectOption } from '~/components/interactive-legend'; -import { TimeSeriesChart } from '~/components/time-series-chart'; -import { TimelineEventConfig } from '~/components/time-series-chart/components/timeline'; -import { TooltipSeriesList } from '~/components/time-series-chart/components/tooltip/tooltip-series-list'; import { LineSeriesDefinition } from '~/components/time-series-chart/logic'; -import { useIntl } from '~/intl'; -import { space } from '~/style/theme'; -import { getBoundaryDateStartUnix } from '~/utils/get-boundary-date-start-unix'; import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; -import { AccessibilityDefinition } from '~/utils/use-accessibility-annotations'; +import { space } from '~/style/theme'; +import { Spacer } from '~/components/base'; +import { TimelineEventConfig } from '~/components/time-series-chart/components/timeline'; +import { TimeSeriesChart } from '~/components/time-series-chart'; +import { TooltipSeriesList } from '~/components/time-series-chart/components/tooltip/tooltip-series-list'; import { useBreakpoints } from '~/utils/use-breakpoints'; +import { useIntl } from '~/intl'; import { useList } from '~/utils/use-list'; -import { BASE_SERIES_CONFIG } from './series-config'; type NLHospitalAdmissionPerAgeGroupValue = NlIntensiveCareNicePerAgeGroupValue | NlHospitalNicePerAgeGroupValue; @@ -26,9 +27,10 @@ interface AdmissionsPerAgeGroup { */ accessibility: AccessibilityDefinition; timelineEvents?: TimelineEventConfig[]; + onHandleTimeframePeriodChange?: (value: DateRange | undefined) => void; } -export function AdmissionsPerAgeGroup({ values, timeframe, accessibility, timelineEvents }: AdmissionsPerAgeGroup) { +export function AdmissionsPerAgeGroup({ values, timeframe, accessibility, timelineEvents, onHandleTimeframePeriodChange }: AdmissionsPerAgeGroup) { const { commonTexts } = useIntl(); const { list, toggle, clear } = useList(); const breakpoints = useBreakpoints(true); @@ -91,6 +93,7 @@ export function AdmissionsPerAgeGroup({ values, timeframe, accessibility, timeli ], timelineEvents, }} + onHandleTimeframePeriodChange={onHandleTimeframePeriodChange} /> ); diff --git a/packages/app/src/domain/infection_radar/infection-radar-per-age-group.tsx b/packages/app/src/domain/infection_radar/infection-radar-per-age-group.tsx index 284e41a0c5..ac0f71f8f8 100644 --- a/packages/app/src/domain/infection_radar/infection-radar-per-age-group.tsx +++ b/packages/app/src/domain/infection_radar/infection-radar-per-age-group.tsx @@ -26,10 +26,10 @@ interface InfectionRadarSymptomsPerAgeGroup { timeframe: TimeframeOption; timelineEvents?: TimelineEventConfig[]; text: SiteText['pages']['infectie_radar_page']['nl']; - onHandleTimeIntervalChange?: (value: DateRange) => void; + onHandleTimeframePeriodChange?: (value: DateRange | undefined) => void; } -export function InfectionRadarSymptomsPerAgeGroup({ values, timeframe, accessibility, timelineEvents, text, onHandleTimeIntervalChange }: InfectionRadarSymptomsPerAgeGroup) { +export function InfectionRadarSymptomsPerAgeGroup({ values, timeframe, accessibility, timelineEvents, text, onHandleTimeframePeriodChange }: InfectionRadarSymptomsPerAgeGroup) { const { commonTexts } = useIntl(); const { list, toggle, clear } = useList(); const breakpoints = useBreakpoints(true); @@ -91,7 +91,7 @@ export function InfectionRadarSymptomsPerAgeGroup({ values, timeframe, accessibi valueAnnotation: text.infection_radar_infected_per_age_group.value_annotation, timelineEvents, }} - onHandleTimeIntervalChange={onHandleTimeIntervalChange} + onHandleTimeframePeriodChange={onHandleTimeframePeriodChange} /> ); diff --git a/packages/app/src/domain/sewer/sewer-chart/sewer-chart.tsx b/packages/app/src/domain/sewer/sewer-chart/sewer-chart.tsx index 803acac297..911276a591 100644 --- a/packages/app/src/domain/sewer/sewer-chart/sewer-chart.tsx +++ b/packages/app/src/domain/sewer/sewer-chart/sewer-chart.tsx @@ -2,8 +2,9 @@ import { AccessibilityDefinition } from '~/utils/use-accessibility-annotations'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; import { ChartTimeControls } from '~/components/chart-time-controls'; -import { colors, isDateSpanSeries, NlSewer, SewerPerInstallationData, TimeframeOption, TimeframeOptionsList } from '@corona-dashboard/common'; +import { colors, NlSewer, SewerPerInstallationData, TimeframeOption, TimeframeOptionsList } from '@corona-dashboard/common'; import { DateRange } from '~/components/metadata'; +import { getDateFromValues } from '~/utils/get-last-insertion-date-of-page'; import { isPresent } from 'ts-is-present'; import { mediaQueries, space } from '~/style/theme'; import { mergeData, useSewerStationSelectPropsSimplified } from './logic'; @@ -11,11 +12,10 @@ import { RichContentSelect } from '~/components/rich-content-select'; import { Text } from '~/components/typography'; import { TimelineEventConfig } from '~/components/time-series-chart/components/timeline'; import { TimeSeriesChart } from '~/components/time-series-chart'; -import { useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { useIntl } from '~/intl'; import { useRouter } from 'next/router'; import { useScopedWarning } from '~/utils/use-scoped-warning'; -import { useValuesInTimeframe } from '~/components/time-series-chart/logic'; import { Warning } from '@corona-dashboard/icons'; import { WarningTile } from '~/components/warning-tile'; import styled from 'styled-components'; @@ -90,10 +90,10 @@ export const SewerChart = ({ accessibility, dataAverages, dataPerInstallation, t const [sewerTimeframe, setSewerTimeframe] = useState(TimeframeOption.ALL); const router = useRouter(); - const values = useValuesInTimeframe(dataAverages.values, timeframe); - const [metadataTimeInterval, setMetadataTimeInterval] = useState({ start: 0, end: 0 }); - const metadataLastInsertion = values[values.length - 1] ? values[values.length - 1].date_of_insertion_unix : 1; // Weird behavior if set to 0 + const [sewerChartTimeframePeriod, setSewerChartTimeframePeriod] = useState({ start: 0, end: 0 }); + + const metadataLastInsertionDate = getDateFromValues(dataAverages); const scopedGmName = commonTexts.gemeente_index.municipality_warning; const scopedWarning = useScopedWarning(vrNameOrGmName || '', warning || ''); @@ -104,21 +104,14 @@ export const SewerChart = ({ accessibility, dataAverages, dataPerInstallation, t return () => router.events.off('routeChangeStart', routeChangeHandler); }, [onChange, router.events]); - useEffect(() => { - if (isDateSpanSeries(values)) { - setMetadataTimeInterval({ - start: values[0] ? values[0].date_start_unix : 0, - end: values[values.length - 1] ? values[values.length - 1].date_end_unix : 0, - }); - } else { - setMetadataTimeInterval({ start: values[0] ? values[0].date_unix : 0, end: values[values.length - 1] ? values[values.length - 1].date_unix : 0 }); - } - }, [timeframe, values, setMetadataTimeInterval]); - useEffect(() => { setSewerTimeframe(timeframe); }, [timeframe, setSewerTimeframe]); + const handleSetSewerChartTimeframePeriodChange = useCallback((value: DateRange | undefined) => { + setSewerChartTimeframePeriod(value); + }, []); + const dataOptions = incompleteDatesAndTexts && selectedInstallation === 'ZEEWOLDE' ? { @@ -157,8 +150,8 @@ export const SewerChart = ({ accessibility, dataAverages, dataPerInstallation, t title={text.title} metadata={{ source: text.source, - datePeriod: metadataTimeInterval, - dateOfInsertionUnix: metadataLastInsertion, + timeframePeriod: sewerChartTimeframePeriod, + dateOfInsertion: metadataLastInsertionDate, }} description={text.description} > @@ -216,6 +209,7 @@ export const SewerChart = ({ accessibility, dataAverages, dataPerInstallation, t ]} dataOptions={dataOptions} forceLegend + onHandleTimeframePeriodChange={handleSetSewerChartTimeframePeriodChange} /> ) : ( ) } diff --git a/packages/app/src/domain/tested/g-number-bar-chart-tile.tsx b/packages/app/src/domain/tested/g-number-bar-chart-tile.tsx index ee06eabaee..ec5ae18860 100644 --- a/packages/app/src/domain/tested/g-number-bar-chart-tile.tsx +++ b/packages/app/src/domain/tested/g-number-bar-chart-tile.tsx @@ -25,6 +25,9 @@ export function GNumberBarChartTile({ data: __data, timeframeInitialValue = Time const last_value = __data.last_value; const endDate = createDateFromUnixTimestamp(last_value.date_unix); + const metadataTimeframePeriod = { start: values[0].date_unix, end: values[values.length - 1].date_unix }; + const metadataDateOfInsertion = values[values.length - 1].date_of_insertion_unix; + return ( diff --git a/packages/app/src/domain/tested/reproduction-chart-tile.tsx b/packages/app/src/domain/tested/reproduction-chart-tile.tsx index 9f236f7fbf..d66bbd371a 100644 --- a/packages/app/src/domain/tested/reproduction-chart-tile.tsx +++ b/packages/app/src/domain/tested/reproduction-chart-tile.tsx @@ -36,6 +36,9 @@ export const ReproductionChartTile = ({ ); const last_value = last(values) as ArchivedNlReproductionValue; + const metadataTimeframePeriod = { start: values[0].date_unix, end: values[values.length - 1].date_unix }; + const metadataDateOfInsertion = data.last_value.date_of_insertion_unix; + 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 0204f0fff7..f474a97c33 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,15 +1,15 @@ -import { ArchivedNlVaccineCoveragePerAgeGroupAutumn_2022Value } from '@corona-dashboard/common'; import { AgeGroup } from '~/components/age-groups/age-group'; +import { ArchivedNlVaccineCoveragePerAgeGroupAutumn_2022Value } from '@corona-dashboard/common'; import { ChartTile } from '~/components/chart-tile'; -import { MetadataProps } from '~/components/metadata'; +import { COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; +import { getSortingOrder } from '../logic/get-sorting-order'; +import { MetadataProps } from '~/components/metadata/types'; import { NarrowTable } from '~/components/tables/narrow-table'; import { SingleCoverageTableData } from '~/components/tables/types'; -import { WideTable } from '~/components/tables/wide-table'; -import { COLOR_AUTUMN_2022_SHOT } from '~/domain/vaccine/common'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; -import { getSortingOrder } from '../logic/get-sorting-order'; import { useGetSingleCoveragePercentageData } from '~/components/tables/logic/use-get-single-coverage-percentage-data'; +import { WideTable } from '~/components/tables/wide-table'; interface Autumn2022ShotCoveragePerAgeGroupProps { title: 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 0e44525d75..53a31bdc25 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,7 +1,7 @@ import { ArchivedGmVaccineCoveragePerAgeGroupWithBoosterShotValue, ArchivedNlVaccineCoveragePerAgeGroupWithBoosterShotValue } from '@corona-dashboard/common'; import { AgeGroup } from '~/components/age-groups/age-group'; import { ChartTile } from '~/components/chart-tile'; -import { MetadataProps } from '~/components/metadata'; +import {} from '~/components/metadata'; import { useGetPercentageData } from '~/components/tables/logic/use-get-percentage-data'; import { NarrowTable } from '~/components/tables/narrow-table'; import { TableData } from '~/components/tables/types'; @@ -10,6 +10,7 @@ import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; import { COLOR_FULLY_BOOSTERED, COLOR_FULLY_VACCINATED } from '../common'; import { getSortingOrder } from '../logic/get-sorting-order'; +import { MetadataProps } from '~/components/metadata/types'; interface BoosterCoveragePerAgeGroupProps { title: string; diff --git a/packages/app/src/domain/vaccine/primary-series-coverage-per-age-group/primary-series-coverage-per-age-group.tsx b/packages/app/src/domain/vaccine/primary-series-coverage-per-age-group/primary-series-coverage-per-age-group.tsx index 447c403be3..f06fabf92e 100644 --- a/packages/app/src/domain/vaccine/primary-series-coverage-per-age-group/primary-series-coverage-per-age-group.tsx +++ b/packages/app/src/domain/vaccine/primary-series-coverage-per-age-group/primary-series-coverage-per-age-group.tsx @@ -1,15 +1,15 @@ -import { ArchivedNlVaccineCoveragePerAgeGroupAutumn_2022Value } from '@corona-dashboard/common'; import { AgeGroup } from '~/components/age-groups/age-group'; +import { ArchivedNlVaccineCoveragePerAgeGroupAutumn_2022Value } from '@corona-dashboard/common'; import { ChartTile } from '~/components/chart-tile'; -import { MetadataProps } from '~/components/metadata'; -import { useGetSingleCoveragePercentageData } from '~/components/tables/logic/use-get-single-coverage-percentage-data'; +import { COLOR_FULLY_VACCINATED } from '~/domain/vaccine/common'; +import { getSortingOrder } from '../logic/get-sorting-order'; +import { MetadataProps } from '~/components/metadata/types'; import { NarrowTable } from '~/components/tables/narrow-table'; import { SingleCoverageTableData } from '~/components/tables/types'; -import { WideTable } from '~/components/tables/wide-table'; -import { COLOR_FULLY_VACCINATED } from '~/domain/vaccine/common'; import { SiteText } from '~/locale'; import { useBreakpoints } from '~/utils/use-breakpoints'; -import { getSortingOrder } from '../logic/get-sorting-order'; +import { useGetSingleCoveragePercentageData } from '~/components/tables/logic/use-get-single-coverage-percentage-data'; +import { WideTable } from '~/components/tables/wide-table'; interface PrimarySeriesShotCoveragePerAgeGroupProps { title: string; diff --git a/packages/app/src/domain/vaccine/primary-series-kpi-header.tsx b/packages/app/src/domain/vaccine/primary-series-kpi-header.tsx index 7e7074cf35..49fae37f14 100644 --- a/packages/app/src/domain/vaccine/primary-series-kpi-header.tsx +++ b/packages/app/src/domain/vaccine/primary-series-kpi-header.tsx @@ -1,7 +1,6 @@ -import { PageInformationBlock } from '~/components'; -import { Vaccinaties as VaccinatieIcon } from '@corona-dashboard/icons'; import { Box } from '~/components/base'; -import { MetadataProps } from '~/components/metadata'; +import { MetadataProps, PageInformationBlock } from '~/components'; +import { Vaccinaties as VaccinatieIcon } from '@corona-dashboard/icons'; interface PrimarySeriesKpiHeaderProps { title: string; @@ -19,7 +18,7 @@ export function PrimarySeriesKpiHeader({ title, description, metadata }: Primary metadata={{ datumsText: metadata.datumsText, dateOrRange: metadata.dateOrRange, - dateOfInsertionUnix: metadata.dateOfInsertionUnix, + dateOfInsertion: metadata.dateOfInsertion, dataSources: metadata.dataSources, }} /> diff --git a/packages/app/src/domain/vaccine/vaccinations-kpi-header.tsx b/packages/app/src/domain/vaccine/vaccinations-kpi-header.tsx index aad031f7ef..c6a2d7a463 100644 --- a/packages/app/src/domain/vaccine/vaccinations-kpi-header.tsx +++ b/packages/app/src/domain/vaccine/vaccinations-kpi-header.tsx @@ -23,10 +23,10 @@ type TextTypes = { interface VaccineKpiHeaderProps { text: TextTypes; dateUnix: number; - dateOfInsertionUnix: number; + dateOfInsertion: number; } -export function VaccinationsKpiHeader({ text, dateUnix, dateOfInsertionUnix }: VaccineKpiHeaderProps) { +export function VaccinationsKpiHeader({ text, dateUnix, dateOfInsertion }: VaccineKpiHeaderProps) { return ( ; }; + const metadataTimeframePeriod = { start: data.values[0].date_start_unix, end: data.values[data.values.length - 1].date_end_unix }; + const metadataDateOfInsertion = data.last_value.date_of_insertion_unix; + return ( diff --git a/packages/app/src/domain/vaccine/vaccine-stock-per-supplier-chart.tsx b/packages/app/src/domain/vaccine/vaccine-stock-per-supplier-chart.tsx index d040bf0598..59023dce8f 100644 --- a/packages/app/src/domain/vaccine/vaccine-stock-per-supplier-chart.tsx +++ b/packages/app/src/domain/vaccine/vaccine-stock-per-supplier-chart.tsx @@ -1,15 +1,15 @@ -import { colors, getValuesInTimeframe, ArchivedNlVaccineStockValue, TimeframeOption } from '@corona-dashboard/common'; -import { pick } from 'lodash'; -import { useMemo, useState } from 'react'; -import { isPresent } from 'ts-is-present'; -import { Spacer } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; +import { colors, getValuesInTimeframe, ArchivedNlVaccineStockValue, TimeframeOption } from '@corona-dashboard/common'; import { InteractiveLegend, SelectOption } from '~/components/interactive-legend'; +import { isPresent } from 'ts-is-present'; +import { pick } from 'lodash'; +import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; import { SeriesConfig, TimeSeriesChart } from '~/components/time-series-chart'; import { SiteText } from '~/locale'; import { space } from '~/style/theme'; +import { Spacer } from '~/components/base'; import { useCurrentDate } from '~/utils/current-date-context'; -import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; +import { useMemo, useState } from 'react'; interface VaccineStockPerSupplierChartProps { values: ArchivedNlVaccineStockValue[]; @@ -28,6 +28,9 @@ export function VaccineStockPerSupplierChart({ values, text }: VaccineStockPerSu [values, today] ); + const metadataTimeframePeriod = { start: values[0].date_unix, end: values[values.length - 1].date_unix }; + const metadataDateOfInsertion = values[values.length - 1].date_of_insertion_unix; + const optionsConfig: SelectOption[] = [ { metricProperty: 'bio_n_tech_pfizer', @@ -89,6 +92,9 @@ export function VaccineStockPerSupplierChart({ values, text }: VaccineStockPerSu description={text.stock_per_supplier_chart.description} metadata={{ source: text.bronnen.rivm, + dateOfInsertion: metadataDateOfInsertion, + timeframePeriod: metadataTimeframePeriod, + isArchivedGraph: true, }} > diff --git a/packages/app/src/domain/variants/variants-stacked-area-tile.tsx b/packages/app/src/domain/variants/variants-stacked-area-tile.tsx index e311c337d4..8189ff7eaf 100644 --- a/packages/app/src/domain/variants/variants-stacked-area-tile.tsx +++ b/packages/app/src/domain/variants/variants-stacked-area-tile.tsx @@ -1,19 +1,20 @@ -import { TimeframeOption, TimeframeOptionsList } from '@corona-dashboard/common'; -import { useMemo, useState } from 'react'; -import { Spacer } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; +import { ColorMatch, VariantChartValue, VariantsStackedAreaTileText } from '~/domain/variants/data-selection/types'; +import { DateRange } from '~/components/metadata'; +import { GappedAreaSeriesDefinition } from '~/components/time-series-chart/logic'; import { InteractiveLegend } from '~/components/interactive-legend'; import { Legend, LegendItem } from '~/components/legend'; -import { MetadataProps } from '~/components/metadata'; +import { MetadataProps } from '~/components/metadata/types'; +import { reorderAndFilter } from '~/domain/variants/logic/reorder-and-filter'; +import { space } from '~/style/theme'; +import { Spacer } from '~/components/base'; +import { TimeframeOption, TimeframeOptionsList } from '@corona-dashboard/common'; import { TimeSeriesChart } from '~/components/time-series-chart'; import { TooltipSeriesList } from '~/components/time-series-chart/components/tooltip/tooltip-series-list'; -import { GappedAreaSeriesDefinition } from '~/components/time-series-chart/logic'; import { useList } from '~/utils/use-list'; -import { space } from '~/style/theme'; -import { useUnreliableDataAnnotations } from './logic/use-unreliable-data-annotations'; -import { ColorMatch, VariantChartValue, VariantsStackedAreaTileText } from '~/domain/variants/data-selection/types'; +import { useMemo, useState } from 'react'; import { useSeriesConfig } from '~/domain/variants/logic/use-series-config'; -import { reorderAndFilter } from '~/domain/variants/logic/reorder-and-filter'; +import { useUnreliableDataAnnotations } from './logic/use-unreliable-data-annotations'; const alwaysEnabled: (keyof VariantChartValue)[] = []; @@ -22,9 +23,10 @@ interface VariantsStackedAreaTileProps { values: VariantChartValue[]; metadata: MetadataProps; variantColors: ColorMatch[]; + onHandleTimeframePeriodChange?: (value: DateRange | undefined) => void; } -export const VariantsStackedAreaTile = ({ text, values, variantColors, metadata }: VariantsStackedAreaTileProps) => { +export const VariantsStackedAreaTile = ({ text, values, variantColors, metadata, onHandleTimeframePeriodChange }: VariantsStackedAreaTileProps) => { const [variantStackedAreaTimeframe, setVariantStackedAreaTimeframe] = useState(TimeframeOption.ALL); const { list, toggle, clear } = useList(alwaysEnabled); @@ -78,6 +80,7 @@ export const VariantsStackedAreaTile = ({ text, values, variantColors, metadata )} numGridLines={0} tickValues={[0, 25, 50, 75, 100]} + onHandleTimeframePeriodChange={onHandleTimeframePeriodChange} /> diff --git a/packages/app/src/domain/variants/variants-stacked-bar-chart-tile.tsx b/packages/app/src/domain/variants/variants-stacked-bar-chart-tile.tsx index 07aff84a78..d01d8784df 100644 --- a/packages/app/src/domain/variants/variants-stacked-bar-chart-tile.tsx +++ b/packages/app/src/domain/variants/variants-stacked-bar-chart-tile.tsx @@ -1,16 +1,17 @@ import { ChartTile, MetadataProps, TimeSeriesChart } from '~/components'; -import { Spacer } from '~/components/base'; -import { TimeframeOption, TimeframeOptionsList } from '@corona-dashboard/common'; -import { useState } from 'react'; import { ColorMatch, OrderMatch, VariantChartValue, VariantDynamicLabels, VariantsOverTimeGraphText } from '~/domain/variants/data-selection/types'; -import { useBarConfig } from '~/domain/variants/logic/use-bar-config'; +import { DateRange } from '~/components/metadata'; import { InteractiveLegend, SelectOption } from '~/components/interactive-legend'; -import { useList } from '~/utils/use-list'; -import { TooltipSeriesList } from '~/components/time-series-chart/components/tooltip/tooltip-series-list'; +import { reorderAndFilter } from '~/domain/variants/logic/reorder-and-filter'; import { space } from '~/style/theme'; +import { Spacer } from '~/components/base'; +import { TimeframeOption, TimeframeOptionsList } from '@corona-dashboard/common'; +import { TooltipSeriesList } from '~/components/time-series-chart/components/tooltip/tooltip-series-list'; +import { useBarConfig } from '~/domain/variants/logic/use-bar-config'; import { useCurrentDate } from '~/utils/current-date-context'; -import { reorderAndFilter } from '~/domain/variants/logic/reorder-and-filter'; import { useIntl } from '~/intl'; +import { useList } from '~/utils/use-list'; +import { useState } from 'react'; interface VariantsStackedBarChartTileProps { description: string; @@ -21,6 +22,7 @@ interface VariantsStackedBarChartTileProps { variantColors: ColorMatch[]; variantLabels: VariantDynamicLabels; variantOrders: OrderMatch[]; + onHandleTimeframePeriodChange?: (value: DateRange | undefined) => void; } const alwaysEnabled: (keyof VariantChartValue)[] = []; @@ -45,6 +47,7 @@ export const VariantsStackedBarChartTile = ({ variantColors, variantOrders, metadata, + onHandleTimeframePeriodChange, }: VariantsStackedBarChartTileProps) => { const today = useCurrentDate(); const { commonTexts } = useIntl(); @@ -80,6 +83,7 @@ export const VariantsStackedBarChartTile = ({ timeframe={variantTimeFrame} disableLegend formatTooltip={(data) => (data, interactiveLegendOptions)} hasTwoColumns={hasTwoColumns} />} + onHandleTimeframePeriodChange={onHandleTimeframePeriodChange} /> ); diff --git a/packages/app/src/domain/variants/variants-table-tile.tsx b/packages/app/src/domain/variants/variants-table-tile.tsx index bd2eb9f760..152ca8a7d1 100644 --- a/packages/app/src/domain/variants/variants-table-tile.tsx +++ b/packages/app/src/domain/variants/variants-table-tile.tsx @@ -6,14 +6,13 @@ import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; import { FullscreenChartTile } from '~/components/fullscreen-chart-tile'; import { Markdown } from '~/components/markdown'; -import { MetadataProps } from '~/components/metadata'; import { Heading } from '~/components/typography'; import { useIntl } from '~/intl'; import { fontSizes, space } from '~/style/theme'; import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; import { VariantsTable } from './variants-table-tile/components/variants-table'; import { TableText } from './variants-table-tile/types'; -import { Tile } from '~/components'; +import { MetadataProps, Tile } from '~/components'; import { VariantRow } from '~/domain/variants/data-selection/types'; interface VariantsTableTileProps { diff --git a/packages/app/src/pages/gemeente/[code]/de-coronaprik.tsx b/packages/app/src/pages/gemeente/[code]/de-coronaprik.tsx index 5d5d5ed9c1..94357cea2d 100644 --- a/packages/app/src/pages/gemeente/[code]/de-coronaprik.tsx +++ b/packages/app/src/pages/gemeente/[code]/de-coronaprik.tsx @@ -138,7 +138,7 @@ export const VaccinationsGmPage = (props: StaticProps) => metadata={{ datumsText: textGm.vaccination_coverage.top_level_information_block.dates, dateOrRange: filteredVaccination.primarySeries.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textShared.bronnen.rivm], jsonSources: [ getMunicipalityJsonLink(reverseRouter.json.municipality(currentData.code), jsonText.metrics_municipality_json.text), diff --git a/packages/app/src/pages/gemeente/[code]/patienten-in-beeld.tsx b/packages/app/src/pages/gemeente/[code]/patienten-in-beeld.tsx index 3c9e5f0748..cfe2f980af 100644 --- a/packages/app/src/pages/gemeente/[code]/patienten-in-beeld.tsx +++ b/packages/app/src/pages/gemeente/[code]/patienten-in-beeld.tsx @@ -108,8 +108,13 @@ function IntakeHospital(props: StaticProps) { }), }; - const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); + const hospitalNiceTimeframePeriod = { + start: data.hospital_nice_archived_20240228.values[0].date_start_unix, + end: data.hospital_nice_archived_20240228.values[data.hospital_nice_archived_20240228.values.length - 1].date_end_unix, + }; + const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); + //const lastInsertionDateHospitalNice = getLastInsertionDateOfPage(data, ['hospital_nice_archived_20240228']); return ( @@ -124,7 +129,7 @@ function IntakeHospital(props: StaticProps) { metadata={{ datumsText: textGm.datums, dateOrRange: lastValue.date_end_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textGm.bronnen.rivm], jsonSources: [ getMunicipalityJsonLink(reverseRouter.json.municipality(data.code), jsonText.metrics_municipality_json.text), @@ -160,7 +165,7 @@ function IntakeHospital(props: StaticProps) { diff --git a/packages/app/src/pages/gemeente/[code]/positieve-testen.tsx b/packages/app/src/pages/gemeente/[code]/positieve-testen.tsx index 1d3426a342..5282042b4f 100644 --- a/packages/app/src/pages/gemeente/[code]/positieve-testen.tsx +++ b/packages/app/src/pages/gemeente/[code]/positieve-testen.tsx @@ -98,6 +98,12 @@ function PositivelyTestedPeople(props: StaticProps) { }), }; + const testedOverallTimeframePeriod = { + start: archivedData.tested_overall_archived_20230331.values[0].date_unix, + end: archivedData.tested_overall_archived_20230331.values[archivedData.tested_overall_archived_20230331.values.length - 1].date_unix, + }; + const testedOverallDateOfInsertion = getLastInsertionDateOfPage(archivedData, ['tested_overall_archived_20230331']); + const lastInsertionDateOfPage = getLastInsertionDateOfPage(archivedData, pageMetrics); return ( @@ -114,7 +120,7 @@ function PositivelyTestedPeople(props: StaticProps) { metadata={{ datumsText: textGm.datums, dateOrRange: archivedLastValue.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textGm.bronnen.rivm], jsonSources: [ getMunicipalityJsonLink(reverseRouter.json.municipality(data.code), jsonText.metrics_municipality_json.text), @@ -186,6 +192,8 @@ function PositivelyTestedPeople(props: StaticProps) { description={textGm.linechart_toelichting} metadata={{ source: textGm.bronnen.rivm, + dateOfInsertion: testedOverallDateOfInsertion, + timeframePeriod: testedOverallTimeframePeriod, }} timeframeOptions={TimeframeOptionsList} timeframeInitialValue={positivelyTestedPeopleTimeframe} diff --git a/packages/app/src/pages/gemeente/[code]/rioolwater.tsx b/packages/app/src/pages/gemeente/[code]/rioolwater.tsx index c7f63eed90..db025c2613 100644 --- a/packages/app/src/pages/gemeente/[code]/rioolwater.tsx +++ b/packages/app/src/pages/gemeente/[code]/rioolwater.tsx @@ -108,7 +108,7 @@ const SewerWater = (props: StaticProps) => { start: sewerAverages.last_value.date_start_unix, end: sewerAverages.last_value.date_end_unix, }, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textGm.bronnen.rivm], jsonSources: [getMunicipalityJsonLink(reverseRouter.json.municipality(data.code), jsonText.metrics_municipality_json.text)], }} diff --git a/packages/app/src/pages/gemeente/[code]/sterfte.tsx b/packages/app/src/pages/gemeente/[code]/sterfte.tsx index 6e9552dd5a..7be6e30165 100644 --- a/packages/app/src/pages/gemeente/[code]/sterfte.tsx +++ b/packages/app/src/pages/gemeente/[code]/sterfte.tsx @@ -88,7 +88,13 @@ const DeceasedMunicipalPage = (props: StaticProps) => { const hasActiveWarningTile = !!textGm.notification.message; + const deceasedRivmTimeframePeriod = { + start: data.deceased_rivm_archived_20221231.values[0].date_unix, + end: data.deceased_rivm_archived_20221231.values[data.deceased_rivm_archived_20221231.values.length - 1].date_unix, + }; + const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); + const lastInsertionDateDeceasedRivm = getLastInsertionDateOfPage(data, ['deceased_rivm_archived_20221231']); return ( @@ -105,7 +111,7 @@ const DeceasedMunicipalPage = (props: StaticProps) => { metadata={{ datumsText: textGm.section_deceased_rivm.datums, dateOrRange: data.deceased_rivm_archived_20221231.last_value.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textGm.section_deceased_rivm.bronnen.rivm], jsonSources: [getMunicipalityJsonLink(reverseRouter.json.municipality(data.code), jsonText.metrics_archived_municipality_json.text)], }} @@ -147,7 +153,7 @@ const DeceasedMunicipalPage = (props: StaticProps) => { timeframeOptions={TimeframeOptionsList} title={textGm.section_deceased_rivm.line_chart_covid_daily_title} description={textGm.section_deceased_rivm.line_chart_covid_daily_description} - metadata={{ source: textGm.section_deceased_rivm.bronnen.rivm }} + metadata={{ source: textGm.section_deceased_rivm.bronnen.rivm, dateOfInsertion: lastInsertionDateDeceasedRivm, timeframePeriod: deceasedRivmTimeframePeriod }} onSelectTimeframe={setDeceasedMunicipalTimeframe} > ) => { description: textNl.metadata.description, }; + const metadataTimeframePeriod = { + start: data.infectious_people_archived_20210709.values[0].date_unix, + end: data.infectious_people_archived_20210709.values[data.infectious_people_archived_20210709.values.length - 1].date_unix, + }; + const hasActiveWarningTile = !!textNl.belangrijk_bericht; return ( @@ -76,7 +81,7 @@ const InfectiousPeople = (props: StaticProps) => { metadata={{ datumsText: textNl.datums, dateOrRange: lastFullValue.date_unix, - dateOfInsertionUnix: lastFullValue.date_of_insertion_unix, + dateOfInsertion: lastFullValue.date_of_insertion_unix, dataSources: [textNl.bronnen.rivm], jsonSources: [{ href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }], }} @@ -88,7 +93,11 @@ const InfectiousPeople = (props: StaticProps) => { {hasActiveWarningTile && } - + ) => { end_date: lastThermometerSetDate, }), dateOrRange: endDate, - dateOfInsertionUnix: endDate, + dateOfInsertion: endDate, dataSources: [textNl.bronnen.rivm], jsonSources: [{ href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }], }} diff --git a/packages/app/src/pages/landelijk/coronamelder.tsx b/packages/app/src/pages/landelijk/coronamelder.tsx index e0fc07f031..44c692024f 100644 --- a/packages/app/src/pages/landelijk/coronamelder.tsx +++ b/packages/app/src/pages/landelijk/coronamelder.tsx @@ -15,6 +15,7 @@ import { useIntl } from '~/intl'; import { useReverseRouter } from '~/utils'; import { useState } from 'react'; import { WarningTile } from '~/components/warning-tile'; +import { getLastInsertionDateOfPage } from '~/utils/get-last-insertion-date-of-page'; const selectLokalizeTexts = (siteText: SiteText) => ({ metadataTexts: siteText.pages.topical_page.nl.nationaal_metadata, @@ -49,6 +50,11 @@ const CoronamelderPage = (props: StaticProps) => { description: textNl.metadata.description, }; + const metadataTimeframePeriod = { + start: data.corona_melder_app_warning_archived_20220421.values[0].date_unix, + end: data.corona_melder_app_warning_archived_20220421.values[data.corona_melder_app_warning_archived_20220421.values.length - 1].date_unix, + }; + const hasActiveWarningTile = !!corona_melder_app.belangrijk_bericht; return ( @@ -63,7 +69,7 @@ const CoronamelderPage = (props: StaticProps) => { metadata={{ datumsText: corona_melder_app.header.datums, dateOrRange: warningLastValue.date_unix, - dateOfInsertionUnix: warningLastValue.date_of_insertion_unix, + dateOfInsertion: warningLastValue.date_of_insertion_unix, dataSources: [corona_melder_app.header.bronnen.rivm], jsonSources: [{ href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }], }} @@ -74,6 +80,8 @@ const CoronamelderPage = (props: StaticProps) => { ) { const lastInsertionDateOfPage = getLastInsertionDateOfPage(archivedData, pageMetrics); + const vaccineVaccinatedOrSupportTimeframePeriod = { + start: archivedData.vaccine_vaccinated_or_support_archived_20230411.values[0].date_start_unix, + end: archivedData.vaccine_vaccinated_or_support_archived_20230411.values[archivedData.vaccine_vaccinated_or_support_archived_20230411.values.length - 1].date_end_unix, + }; + return ( @@ -178,7 +183,7 @@ function VaccinationPage(props: StaticProps) { metadata={{ datumsText: textNl.dates, dateOrRange: archivedData.vaccine_administered_total_archived_20220324.last_value.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textShared.bronnen.rivm], jsonSources: [ { href: reverseRouter.json.national(), text: jsonText.metrics_national_json.text }, @@ -234,7 +239,7 @@ function VaccinationPage(props: StaticProps) { metadata={{ datumsText: textNl.dates_archived, dateOrRange: archivedData.vaccine_administered_total_archived_20220324.last_value.date_unix, - dateOfInsertionUnix: archivedData.vaccine_coverage_per_age_group_estimated_fully_vaccinated_archived_20231004.last_value.date_unix, + dateOfInsertion: archivedData.vaccine_coverage_per_age_group_estimated_fully_vaccinated_archived_20231004.last_value.date_unix, dataSources: [textShared.bronnen.rivm], }} /> @@ -437,7 +442,7 @@ function VaccinationPage(props: StaticProps) { ) { ) { start: archivedData.vaccine_vaccinated_or_support_archived_20230411.last_value.date_start_unix, end: archivedData.vaccine_vaccinated_or_support_archived_20230411.last_value.date_end_unix, }, + source: textNl.vaccination_coverage.bronnen.rivm, + dateOfInsertion: getLastInsertionDateOfPage(archivedData, ['vaccine_vaccinated_or_support_archived_20230411']), + timeframePeriod: vaccineVaccinatedOrSupportTimeframePeriod, + isArchivedGraph: true, }} > ) const behaviorAnnotations = data.behavior_annotations_archived_20230412; const behaviorPerAgeGroup = data.behavior_per_age_group_archived_20230411; + const behaviorChartTimeframePeriod = { start: behaviorValues[0].date_start_unix, end: behaviorValues[behaviorValues.length - 1].date_end_unix }; + const reverseRouter = useReverseRouter(); const { commonTexts, formatNumber, formatDateFromSeconds, formatPercentage, locale } = useIntl(); @@ -133,7 +135,7 @@ export default function BehaviorPage(props: StaticProps) start: behaviorLastValue.date_start_unix, end: behaviorLastValue.date_end_unix, }, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.bronnen.rivm], jsonSources: [{ href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }], }} @@ -198,6 +200,9 @@ export default function BehaviorPage(props: StaticProps) metadata={{ date: { start: behaviorLastValue.date_start_unix, end: behaviorLastValue.date_end_unix }, source: textNl.bronnen.rivm, + dateOfInsertion: getLastInsertionDateOfPage(data, ['behavior_archived_20230411']), + timeframePeriod: behaviorChartTimeframePeriod, + isArchivedGraph: true, }} {...timelineProp} currentId={currentId} diff --git a/packages/app/src/pages/landelijk/gehandicaptenzorg.tsx b/packages/app/src/pages/landelijk/gehandicaptenzorg.tsx index 7ee464746e..2a4254061a 100644 --- a/packages/app/src/pages/landelijk/gehandicaptenzorg.tsx +++ b/packages/app/src/pages/landelijk/gehandicaptenzorg.tsx @@ -94,6 +94,13 @@ function DisabilityCare(props: StaticProps) { description: textNl.besmette_locaties.metadata.description, }; + // All timeseries charts use the same set of data, thus the inteval is equal + const metadataTimeframePeriod = { + start: data.disability_care_archived_20230126.values[0].date_unix, + end: data.disability_care_archived_20230126.values[data.disability_care_archived_20230126.values.length - 1].date_unix, + }; + + // This date can be used for all timeseries charts metadata components since the pageMetrics value only contains one metric const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); const hasActiveWarningTile = !!textNl.belangrijk_bericht; @@ -110,7 +117,7 @@ function DisabilityCare(props: StaticProps) { metadata={{ datumsText: textNl.positief_geteste_personen.datums, dateOrRange: lastValue.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.positief_geteste_personen.bronnen.rivm], jsonSources: [ { href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }, @@ -126,7 +133,7 @@ function DisabilityCare(props: StaticProps) { {hasActiveWarningTile && } ) { metadata={{ datumsText: textNl.besmette_locaties.datums, dateOrRange: lastValue.date_unix, - dateOfInsertionUnix: lastValue.date_of_insertion_unix, + dateOfInsertion: lastValue.date_of_insertion_unix, dataSources: [textNl.besmette_locaties.bronnen.rivm], }} referenceLink={textNl.besmette_locaties.reference.href} @@ -216,6 +223,8 @@ function DisabilityCare(props: StaticProps) { title={textNl.besmette_locaties.charts.linechart_title} metadata={{ source: textNl.besmette_locaties.bronnen.rivm, + dateOfInsertion: lastInsertionDateOfPage, + timeframePeriod: metadataTimeframePeriod, }} timeframeOptions={TimeframeOptionsList} description={textNl.besmette_locaties.charts.linechart_description} @@ -250,14 +259,14 @@ function DisabilityCare(props: StaticProps) { metadata={{ datumsText: textNl.oversterfte.datums, dateOrRange: lastValue.date_unix, - dateOfInsertionUnix: lastValue.date_of_insertion_unix, + dateOfInsertion: lastValue.date_of_insertion_unix, dataSources: [textNl.oversterfte.bronnen.rivm], }} referenceLink={textNl.oversterfte.reference.href} /> ({ metadataTexts: siteText.pages.topical_page.nl.nationaal_metadata, @@ -68,10 +68,10 @@ const InfectionRadar = (props: StaticProps) => { const reverseRouter = useReverseRouter(); const [confirmedCasesSelfTestedTimeframe, setConfirmedCasesSelfTestedTimeframe] = useState(TimeframeOption.SIX_MONTHS); - const [confirmedCasesSelfTestedTimeInterval, setConfirmedCasesSelfTestedTimeInterval] = useState({ start: 0, end: 0 }); + const [confirmedCasesSelfTestedTimeframePeriod, setConfirmedCasesSelfTestedTimeframePeriod] = useState({ start: 0, end: 0 }); const [confirmedCasesCovidSymptomsPerAgeTimeFrame, setConfirmedCasesCovidSymptomsPerAgeTimeFrame] = useState(TimeframeOption.THREE_MONTHS); - const [confirmedCasesCovidSymptomsPerAgeTimeInterval, setConfirmedCasesCovidSymptomsPerAgeTimeInterval] = useState({ start: 0, end: 0 }); + const [confirmedCasesCovidSymptomsPerAgeTimeframePeriod, setConfirmedCasesCovidSymptomsPerAgeTimeframePeriod] = useState({ start: 0, end: 0 }); const { commonTexts } = useIntl(); @@ -85,15 +85,16 @@ const InfectionRadar = (props: StaticProps) => { description: textNl.metadata.description, }; - const handleSetConfirmedCasesSelfTestedTimeInterval = (value: DateRange) => { - setConfirmedCasesSelfTestedTimeInterval(value); - }; + const handleSetConfirmedCasesSelfTestedTimeframePeriodChange = useCallback((value: DateRange | undefined) => { + setConfirmedCasesSelfTestedTimeframePeriod(value); + }, []); - const handleSetConfirmedCasesCovidSymptomsPerAgeTimeInterval = (value: DateRange) => { - setConfirmedCasesCovidSymptomsPerAgeTimeInterval(value); - }; + const handleSetConfirmedCasesCovidSymptomsPerAgeTimeframePeriod = useCallback((value: DateRange | undefined) => { + setConfirmedCasesCovidSymptomsPerAgeTimeframePeriod(value); + }, []); const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); + const lastInsertionDateConfirmedCasesCovidSymptomsPerAgeTimeframePeriod = getLastInsertionDateOfPage(data, ['infectionradar_symptoms_trend_per_age_group_weekly']); return ( @@ -111,7 +112,7 @@ const InfectionRadar = (props: StaticProps) => { start: data.self_test_overall.last_value.date_start_unix, end: data.self_test_overall.last_value.date_end_unix, }, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.sources.rivm], jsonSources: [{ href: reverseRouter.json.national(), text: jsonText.metrics_national_json.text }], }} @@ -151,8 +152,8 @@ const InfectionRadar = (props: StaticProps) => { description={textNl.chart_self_tests.description} metadata={{ source: textNl.sources.self_test, - datePeriod: confirmedCasesSelfTestedTimeInterval, - dateOfInsertionUnix: data.self_test_overall.last_value.date_of_insertion_unix, + timeframePeriod: confirmedCasesSelfTestedTimeframePeriod, + dateOfInsertion: getLastInsertionDateOfPage(data, ['self_test_overall']), }} timeframeOptions={TimeframeOptionsList} timeframeInitialValue={confirmedCasesSelfTestedTimeframe} @@ -177,7 +178,7 @@ const InfectionRadar = (props: StaticProps) => { timelineEvents: getTimelineEvents(content.elements.timeSeries, 'self_test_overall'), }} forceLegend - onHandleTimeIntervalChange={handleSetConfirmedCasesSelfTestedTimeInterval} + onHandleTimeframePeriodChange={handleSetConfirmedCasesSelfTestedTimeframePeriodChange} /> @@ -188,8 +189,8 @@ const InfectionRadar = (props: StaticProps) => { timeframeInitialValue={confirmedCasesCovidSymptomsPerAgeTimeFrame} metadata={{ source: textNl.chart_infection_radar_age_groups.source.rivm, - datePeriod: confirmedCasesCovidSymptomsPerAgeTimeInterval, - dateOfInsertionUnix: data.infectionradar_symptoms_trend_per_age_group_weekly.last_value.date_of_insertion_unix, + timeframePeriod: confirmedCasesCovidSymptomsPerAgeTimeframePeriod, + dateOfInsertion: lastInsertionDateConfirmedCasesCovidSymptomsPerAgeTimeframePeriod, }} onSelectTimeframe={setConfirmedCasesCovidSymptomsPerAgeTimeFrame} > @@ -201,7 +202,7 @@ const InfectionRadar = (props: StaticProps) => { timeframe={confirmedCasesCovidSymptomsPerAgeTimeFrame} timelineEvents={getTimelineEvents(content.elements.timeSeries, 'infectionradar_symptoms_trend_per_age_group_weekly')} text={textNl} - onHandleTimeIntervalChange={handleSetConfirmedCasesCovidSymptomsPerAgeTimeInterval} + onHandleTimeframePeriodChange={handleSetConfirmedCasesCovidSymptomsPerAgeTimeframePeriod} /> diff --git a/packages/app/src/pages/landelijk/klachten-bij-huisartsen.tsx b/packages/app/src/pages/landelijk/klachten-bij-huisartsen.tsx index d308e11018..a6f0b57ac6 100644 --- a/packages/app/src/pages/landelijk/klachten-bij-huisartsen.tsx +++ b/packages/app/src/pages/landelijk/klachten-bij-huisartsen.tsx @@ -1,6 +1,6 @@ import { Arts } from '@corona-dashboard/icons'; import { ChartTile } from '~/components/chart-tile'; -import { colors, TimeframeOption } from '@corona-dashboard/common'; +import { colors, getLastFilledValue, TimeframeOption } from '@corona-dashboard/common'; import { createGetStaticProps, StaticProps } from '~/static-props/create-get-static-props'; import { getLastGeneratedDate, getLokalizeTexts, selectArchivedNlData } from '~/static-props/get-data'; import { Languages, SiteText } from '~/locale'; @@ -13,6 +13,7 @@ import { useDynamicLokalizeTexts } from '~/utils/cms/use-dynamic-lokalize-texts' import { useIntl } from '~/intl'; import { useReverseRouter } from '~/utils'; import { WarningTile } from '~/components/warning-tile'; +import { getLastInsertionDateOfPage } from '~/utils/get-last-insertion-date-of-page'; const selectLokalizeTexts = (siteText: SiteText) => ({ metadataTexts: siteText.pages.topical_page.nl.nationaal_metadata, @@ -35,13 +36,19 @@ const SuspectedPatients = (props: StaticProps) => { const { metadataTexts, jsonText } = useDynamicLokalizeTexts(pageText, selectLokalizeTexts); const { commonTexts } = useIntl(); const text = commonTexts.verdenkingen_huisartsen; - + const lastFullValue = getLastFilledValue(archivedData.doctor_archived_20210903); const metadata = { ...metadataTexts, title: text.metadata.title, description: text.metadata.description, }; + const metadataTimeframePeriod = { + start: archivedData.doctor_archived_20210903.values[0].date_start_unix, + end: lastFullValue.date_end_unix, + }; + const metadataLastDateOfInsertion = getLastInsertionDateOfPage(archivedData, ['doctor_archived_20210903']); + const hasActiveWarningTile = !!text.belangrijk_bericht; return ( @@ -57,7 +64,7 @@ const SuspectedPatients = (props: StaticProps) => { metadata={{ datumsText: text.datums, dateOrRange: lastValue.date_end_unix, - dateOfInsertionUnix: lastValue.date_of_insertion_unix, + dateOfInsertion: lastValue.date_of_insertion_unix, dataSources: [text.bronnen.nivel], jsonSources: [{ href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }], }} @@ -65,7 +72,11 @@ const SuspectedPatients = (props: StaticProps) => { {hasActiveWarningTile && } - + ) { const ElderlyPeopleText = textNl['70_plussers']; + const nursingHomeInfectedLocationsOverTimeTimeframePeriod = { + start: data.vulnerable_nursing_home_archived_20230711.values[0].date_unix, + end: data.vulnerable_nursing_home_archived_20230711.values[data.vulnerable_nursing_home_archived_20230711.values.length - 1].date_unix, + }; + + const nursingHomeConfirmedCasesOverTimeTimeframePeriod = { + start: data.nursing_home_archived_20230126.values[0].date_unix, + end: data.nursing_home_archived_20230126.values[data.nursing_home_archived_20230126.values.length - 1].date_unix, + }; + + const nursingHomeDeceasedOverTimeTimeframePeriod = { + start: data.nursing_home_archived_20230126.values[0].date_unix, + end: data.nursing_home_archived_20230126.values[data.nursing_home_archived_20230126.values.length - 1].date_unix, + }; + const metadata = { ...metadataTexts, title: infectedLocationsText.metadata.title, @@ -124,6 +139,9 @@ function VulnerableGroups(props: StaticProps) { const hasActiveWarningTile = !!textNl.belangrijk_bericht; const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); + const lastInsertionDateNursingHomeInfectedLocationsOverTime = getLastInsertionDateOfPage(data, ['vulnerable_nursing_home_archived_20230711']); + const lastInsertionDateNursingHomeConfirmedCasesOverTime = getLastInsertionDateOfPage(data, ['nursing_home_archived_20230126']); + const lastInsertionDateNursingHomeDeceasedOverTime = getLastInsertionDateOfPage(data, ['nursing_home_archived_20230126']); return ( @@ -138,7 +156,7 @@ function VulnerableGroups(props: StaticProps) { metadata={{ datumsText: positiveTestedPeopleText.datums, dateOrRange: vulnerableNursingHomeDataLastValue.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [positiveTestedPeopleText.bronnen.rivm], jsonSources: [ { href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }, @@ -215,7 +233,12 @@ function VulnerableGroups(props: StaticProps) { ) { ) { metadata={{ datumsText: textNl.datums, dateOrRange: nursinghomeDataLastValue.date_unix, - dateOfInsertionUnix: nursinghomeDataLastValue.date_of_insertion_unix, + dateOfInsertion: nursinghomeDataLastValue.date_of_insertion_unix, dataSources: [textNl.bronnen.rivm], }} referenceLink={textNl.reference.href} @@ -327,7 +355,12 @@ function VulnerableGroups(props: StaticProps) { ) => { const [hospitalAdmissionsPerAgeGroupOverTimeTimeframe, setHospitalAdmissionsPerAgeGroupOverTimeTimeframe] = useState(TimeframeOption.ALL); const [intensiveCareAdmissionsPerAgeGroupOverTimeTimeframe, setIntensiveCareAdmissionsPerAgeGroupOverTimeTimeframe] = useState(TimeframeOption.ALL); + const [hospitalAdmissionsPerAgeGroupOverTimeTimeframePeriod, setHospitalAdmissionsPerAgeGroupOverTimeTimeframePeriod] = useState({ start: 0, end: 0 }); + const [intensiveCareAdmissionsPerAgeGroupOverTimeTimeframePeriod, setIntensiveCareAdmissionsPerAgeGroupOverTimeTimeframePeriod] = useState({ + start: 0, + end: 0, + }); + const [isArchivedContentShown, setIsArchivedContentShown] = useState(false); const admissionsPerAgeGroupOverTimeToggleItems: ChartTileToggleItem[] = [ @@ -105,6 +112,25 @@ const PatientsPage = (props: StaticProps) => { const [hospitalAdmissionsOverTimeTimeframe, setHospitalAdmissionsOverTimeTimeframe] = useState(TimeframeOption.ALL); const [intensiveCareAdmissionsOverTimeTimeframe, setIntensiveCareAdmissionsOverTimeTimeframe] = useState(TimeframeOption.ALL); + const [hospitalAdmissionsOverTimeTimeframePeriod, setHospitalAdmissionsOverTimeTimeframePeriod] = useState({ start: 0, end: 0 }); + const [intensiveCareAdmissionsOverTimeTimeframePeriod, setIntensiveCareAdmissionsOverTimeTimeframePeriod] = useState({ start: 0, end: 0 }); + + const handleHospitalAdmissionsPerAgeGroupOverTimeTimeframePeriod = useCallback((value: DateRange | undefined) => { + setHospitalAdmissionsPerAgeGroupOverTimeTimeframePeriod(value); + }, []); + + const handleIntensiveCareAdmissionsPerAgeGroupOverTimeTimeframePeriodChange = useCallback((value: DateRange | undefined) => { + setIntensiveCareAdmissionsPerAgeGroupOverTimeTimeframePeriod(value); + }, []); + + const handleHospitalAdmissionsOverTimeTimeframePeriodChange = useCallback((value: DateRange | undefined) => { + setHospitalAdmissionsOverTimeTimeframePeriod(value); + }, []); + + const handleIntensiveCareAdmissionsOverTimeTimeframePeriodChange = useCallback((value: DateRange | undefined) => { + setIntensiveCareAdmissionsOverTimeTimeframePeriod(value); + }, []); + const admissionsOverTimeToggleItems: ChartTileToggleItem[] = [ { label: textNl.hospitals.admissions_chart.toggle_label, @@ -130,6 +156,10 @@ const PatientsPage = (props: StaticProps) => { ); const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); + const lastInsertionDateHospitalAdmissionsPerAgeGroupOverTime = getLastInsertionDateOfPage(data, ['hospital_nice_per_age_group']); + const lastInsertionDateIntensiveCareAdmissionsPerAgeGroupOverTime = getLastInsertionDateOfPage(data, ['intensive_care_nice_per_age_group']); + const lastInsertionDateHospitalAdmissionsOverTime = getLastInsertionDateOfPage(data, ['hospital_nice']); + const lastInsertionDateIntensiveCareAdmissionsOverTime = getLastInsertionDateOfPage(data, ['intensive_care_nice']); const archivedChoroplethDataGm: ArchivedGmCollectionHospitalNiceChoropleth[] = archivedChoropleth.gm.hospital_nice_choropleth_archived_20230830; const archivedChoroplethDataGmWeelklyAdmissions: ArchivedGmCollectionHospitalNiceChoroplethWeeklyAdmissions[] = archivedChoropleth.gm.hospital_nice_choropleth_archived_20240228; @@ -148,7 +178,7 @@ const PatientsPage = (props: StaticProps) => { metadata={{ datumsText: textNl.datums, dateOrRange: lastValueNice.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.sources.nice], jsonSources: [ { href: reverseRouter.json.national(), text: jsonText.metrics_national_json.text }, @@ -169,7 +199,11 @@ const PatientsPage = (props: StaticProps) => { description={textNl.hospitals.admissions_per_age_group_chart.description} timeframeOptions={TimeframeOptionsList} timeframeInitialValue={TimeframeOption.THIRTY_DAYS} - metadata={{ source: textNl.sources.nice }} + metadata={{ + source: textNl.sources.nice, + dateOfInsertion: lastInsertionDateHospitalAdmissionsPerAgeGroupOverTime, + timeframePeriod: hospitalAdmissionsPerAgeGroupOverTimeTimeframePeriod, + }} onSelectTimeframe={setHospitalAdmissionsPerAgeGroupOverTimeTimeframe} toggle={{ initialValue: selectedAdmissionsPerAgeGroupOverTimeChart, @@ -184,6 +218,7 @@ const PatientsPage = (props: StaticProps) => { values={data.hospital_nice_per_age_group.values} timeframe={hospitalAdmissionsPerAgeGroupOverTimeTimeframe} timelineEvents={getTimelineEvents(content.elements.timeSeries, 'hospital_nice_per_age_group')} + onHandleTimeframePeriodChange={handleHospitalAdmissionsPerAgeGroupOverTimeTimeframePeriod} /> )} @@ -194,7 +229,11 @@ const PatientsPage = (props: StaticProps) => { description={textNl.icu.admissions_per_age_group_chart.description} timeframeOptions={TimeframeOptionsList} timeframeInitialValue={TimeframeOption.THIRTY_DAYS} - metadata={{ source: textNl.sources.nice }} + metadata={{ + source: textNl.sources.nice, + dateOfInsertion: lastInsertionDateIntensiveCareAdmissionsPerAgeGroupOverTime, + timeframePeriod: intensiveCareAdmissionsPerAgeGroupOverTimeTimeframePeriod, + }} onSelectTimeframe={setIntensiveCareAdmissionsPerAgeGroupOverTimeTimeframe} toggle={{ initialValue: selectedAdmissionsPerAgeGroupOverTimeChart, @@ -209,6 +248,7 @@ const PatientsPage = (props: StaticProps) => { values={data.intensive_care_nice_per_age_group.values} timeframe={intensiveCareAdmissionsPerAgeGroupOverTimeTimeframe} timelineEvents={getTimelineEvents(content.elements.timeSeries, 'intensive_care_nice_per_age_group')} + onHandleTimeframePeriodChange={handleIntensiveCareAdmissionsPerAgeGroupOverTimeTimeframePeriodChange} /> )} @@ -221,6 +261,8 @@ const PatientsPage = (props: StaticProps) => { description={textNl.hospitals.admissions_chart.description} metadata={{ source: textNl.sources.nice, + dateOfInsertion: lastInsertionDateHospitalAdmissionsOverTime, + timeframePeriod: hospitalAdmissionsOverTimeTimeframePeriod, }} timeframeOptions={TimeframeOptionsList} timeframeInitialValue={TimeframeOption.THIRTY_DAYS} @@ -263,6 +305,7 @@ const PatientsPage = (props: StaticProps) => { ], timelineEvents: getTimelineEvents(content.elements.timeSeries, 'hospital_nice'), }} + onHandleTimeframePeriodChange={handleHospitalAdmissionsOverTimeTimeframePeriodChange} /> )} @@ -271,7 +314,11 @@ const PatientsPage = (props: StaticProps) => { ) => { color: colors.primary, }, ]} + onHandleTimeframePeriodChange={handleIntensiveCareAdmissionsOverTimeTimeframePeriodChange} /> )} diff --git a/packages/app/src/pages/landelijk/positieve-testen.tsx b/packages/app/src/pages/landelijk/positieve-testen.tsx index 0abd53aad9..1da7cb8bfc 100644 --- a/packages/app/src/pages/landelijk/positieve-testen.tsx +++ b/packages/app/src/pages/landelijk/positieve-testen.tsx @@ -114,6 +114,21 @@ function PositivelyTestedPeople(props: StaticProps) { description: textNl.metadata.description, }; + const testedOverallTimeframePeriod = { + start: data.tested_overall_archived_20230331.values[0].date_unix, + end: data.tested_overall_archived_20230331.values[data.tested_overall_archived_20230331.values.length - 1].date_unix, + }; + + const testedGgdTimeframePeriod = { + start: data.tested_ggd_archived_20230321.values[0].date_unix, + end: data.tested_ggd_archived_20230321.values[data.tested_ggd_archived_20230321.values.length - 1].date_unix, + }; + + const testedPerAgeGroupTimeframePeriod = { + start: data.tested_per_age_group_archived_20230331.values[0].date_unix, + end: data.tested_per_age_group_archived_20230331.values[data.tested_per_age_group_archived_20230331.values.length - 1].date_unix, + }; + const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); return ( @@ -129,7 +144,7 @@ function PositivelyTestedPeople(props: StaticProps) { metadata={{ datumsText: textNl.datums, dateOrRange: archivedDataOverallLastValue.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.bronnen.rivm], jsonSources: [ { href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }, @@ -153,6 +168,9 @@ function PositivelyTestedPeople(props: StaticProps) { })} metadata={{ source: textNl.bronnen.rivm, + dateOfInsertion: getLastInsertionDateOfPage(data, ['tested_overall_archived_20230331']), + timeframePeriod: testedOverallTimeframePeriod, + isArchivedGraph: true, }} timeframeOptions={TimeframeOptionsList} timeframeInitialValue={confirmedCasesInfectedTimeframe} @@ -203,6 +221,9 @@ function PositivelyTestedPeople(props: StaticProps) { metadata={{ date: getLastInsertionDateOfPage(data, ['tested_ggd_archived_20230321']), source: textNl.ggd.bronnen.rivm, + dateOfInsertion: getLastInsertionDateOfPage(data, ['tested_ggd_archived_20230321']), + timeframePeriod: testedGgdTimeframePeriod, + isArchivedGraph: true, }} onSelectTimeframe={setConfirmedCasesInfectedPercentageTimeframe} toggle={{ @@ -242,6 +263,8 @@ function PositivelyTestedPeople(props: StaticProps) { metadata={{ source: textNl.ggd.bronnen.rivm, date: getLastInsertionDateOfPage(data, ['tested_ggd_archived_20230321']), + dateOfInsertion: getLastInsertionDateOfPage(data, ['tested_per_age_group_archived_20230331']), + timeframePeriod: testedGgdTimeframePeriod, }} onSelectTimeframe={setConfirmedCasesTestedOverTimeTimeframe} toggle={{ @@ -284,6 +307,8 @@ function PositivelyTestedPeople(props: StaticProps) { timeframeOptions={TimeframeOptionsList} metadata={{ source: textNl.bronnen.rivm, + dateOfInsertion: getLastInsertionDateOfPage(data, ['tested_per_age_group_archived_20230331']), + timeframePeriod: testedPerAgeGroupTimeframePeriod, }} onSelectTimeframe={setConfirmedCasesInfectedPerAgeTimeframe} > diff --git a/packages/app/src/pages/landelijk/reproductiegetal.tsx b/packages/app/src/pages/landelijk/reproductiegetal.tsx index 465687f737..f0a426c735 100644 --- a/packages/app/src/pages/landelijk/reproductiegetal.tsx +++ b/packages/app/src/pages/landelijk/reproductiegetal.tsx @@ -97,7 +97,7 @@ const ReproductionIndex = (props: StaticProps) => { metadata={{ datumsText: textNl.datums, dateOrRange: reproductionLastValue.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.bronnen.rivm], jsonSources: [{ href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }], }} diff --git a/packages/app/src/pages/landelijk/rioolwater.tsx b/packages/app/src/pages/landelijk/rioolwater.tsx index 90df74d347..f0bfc95014 100644 --- a/packages/app/src/pages/landelijk/rioolwater.tsx +++ b/packages/app/src/pages/landelijk/rioolwater.tsx @@ -101,7 +101,7 @@ const SewerWater = (props: StaticProps) => { metadata={{ datumsText: textNl.datums, dateOrRange: sewerAverages.last_value.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.bronnen.rivm], jsonSources: [ { href: reverseRouter.json.national(), text: jsonText.metrics_national_json.text }, diff --git a/packages/app/src/pages/landelijk/sterfte.tsx b/packages/app/src/pages/landelijk/sterfte.tsx index c5710ae040..ede0bcf1f1 100644 --- a/packages/app/src/pages/landelijk/sterfte.tsx +++ b/packages/app/src/pages/landelijk/sterfte.tsx @@ -73,15 +73,21 @@ export const getStaticProps = createGetStaticProps( const DeceasedNationalPage = (props: StaticProps) => { const { pageText, selectedNlData: currentData, selectedArchivedNlData: archivedData, lastGenerated, content } = props; + const dataCbs = currentData.deceased_cbs; + const dataRivm = archivedData.deceased_rivm_archived_20221231; + const dataDeceasedPerAgeGroup = archivedData.deceased_rivm_per_age_group_archived_20221231; + const [deceasedOverTimeTimeframe, setDeceasedOverTimeTimeframe] = useState(TimeframeOption.ALL); + const deceasedOverTimeTimeframePeriod = { start: dataCbs.values[0].date_start_unix, end: dataCbs.values[dataCbs.values.length - 1].date_end_unix }; + const deceasedRivmTimeframePeriod = { start: dataRivm.values[0].date_unix, end: dataRivm.values[dataRivm.values.length - 1].date_unix }; + + const deceasedOverTimeLastInsertionDate = getLastInsertionDateOfPage(currentData, ['deceased_cbs']); + const deceasedRivmLastInsertionDate = getLastInsertionDateOfPage(archivedData, ['deceased_rivm_archived_20221231']); + const [isArchivedContentShown, setIsArchivedContentShown] = useState(false); const reverseRouter = useReverseRouter(); - const dataCbs = currentData.deceased_cbs; - const dataRivm = archivedData.deceased_rivm_archived_20221231; - const dataDeceasedPerAgeGroup = archivedData.deceased_rivm_per_age_group_archived_20221231; - const { commonTexts, formatPercentage } = useIntl(); const { metadataTexts, textNl, textShared, jsonText } = useDynamicLokalizeTexts(pageText, selectLokalizeTexts); @@ -111,7 +117,7 @@ const DeceasedNationalPage = (props: StaticProps) => { start: dataCbs.last_value.date_start_unix, end: dataCbs.last_value.date_end_unix, }, - dateOfInsertionUnix: dataCbs.last_value.date_of_insertion_unix, + dateOfInsertion: dataCbs.last_value.date_of_insertion_unix, dataSources: [textNl.section_sterftemonitor.bronnen.cbs], jsonSources: [ { href: reverseRouter.json.national(), text: jsonText.metrics_national_json.text }, @@ -127,7 +133,7 @@ const DeceasedNationalPage = (props: StaticProps) => { {hasActiveWarningTile && } @@ -204,7 +210,7 @@ const DeceasedNationalPage = (props: StaticProps) => { metadata={{ datumsText: textNl.section_deceased_rivm.datums, dateOrRange: dataRivm.last_value.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.section_deceased_rivm.bronnen.rivm], }} /> @@ -238,6 +244,9 @@ const DeceasedNationalPage = (props: StaticProps) => { description={textNl.section_deceased_rivm.line_chart_covid_daily_description} metadata={{ source: textNl.section_deceased_rivm.bronnen.rivm, + timeframePeriod: deceasedRivmTimeframePeriod, + dateOfInsertion: deceasedRivmLastInsertionDate, + isArchivedGraph: true, }} onSelectTimeframe={setDeceasedOverTimeTimeframe} > diff --git a/packages/app/src/pages/landelijk/thuiswonende-70-plussers.tsx b/packages/app/src/pages/landelijk/thuiswonende-70-plussers.tsx index a128b8ad06..4507abe1ea 100644 --- a/packages/app/src/pages/landelijk/thuiswonende-70-plussers.tsx +++ b/packages/app/src/pages/landelijk/thuiswonende-70-plussers.tsx @@ -91,6 +91,8 @@ function ElderlyAtHomeNationalPage(props: StaticProps) { description: textNl.metadata.description, }; + const metadataTimeframePeriod = { start: elderlyAtHomeData.values[0].date_unix, end: elderlyAtHomeData.values[elderlyAtHomeData.values.length - 1].date_unix }; + const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); const hasActiveWarningTile = !!textNl.belangrijk_bericht; @@ -108,7 +110,7 @@ function ElderlyAtHomeNationalPage(props: StaticProps) { metadata={{ datumsText: textNl.section_positive_tested.datums, dateOrRange: elderlyAtHomeData.last_value.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.section_positive_tested.bronnen.rivm], jsonSources: [ { href: reverseRouter.json.archivedNational(), text: jsonText.metrics_archived_national_json.text }, @@ -126,7 +128,7 @@ function ElderlyAtHomeNationalPage(props: StaticProps) { @@ -200,7 +202,7 @@ function ElderlyAtHomeNationalPage(props: StaticProps) { metadata={{ datumsText: textNl.section_deceased.datums, dateOrRange: elderlyAtHomeData.last_value.date_unix, - dateOfInsertionUnix: elderlyAtHomeData.last_value.date_of_insertion_unix, + dateOfInsertion: elderlyAtHomeData.last_value.date_of_insertion_unix, dataSources: [textNl.section_deceased.bronnen.rivm], }} referenceLink={textNl.section_deceased.reference.href} @@ -208,7 +210,7 @@ function ElderlyAtHomeNationalPage(props: StaticProps) { diff --git a/packages/app/src/pages/landelijk/varianten.tsx b/packages/app/src/pages/landelijk/varianten.tsx index 26fe1b944a..2f82f75133 100644 --- a/packages/app/src/pages/landelijk/varianten.tsx +++ b/packages/app/src/pages/landelijk/varianten.tsx @@ -19,10 +19,11 @@ import { TileList } from '~/components/tile-list'; import { useDynamicLokalizeTexts } from '~/utils/cms/use-dynamic-lokalize-texts'; import { useIntl } from '~/intl'; import { useReverseRouter } from '~/utils'; -import { useState } from 'react'; +import { useCallback, useState } from 'react'; import { VariantDynamicLabels } from '~/domain/variants/data-selection/types'; import { Varianten } from '@corona-dashboard/icons'; import { VariantsStackedAreaTile, VariantsStackedBarChartTile, VariantsTableTile } from '~/domain/variants'; +import { DateRange } from '~/components/metadata'; const pageMetrics = ['variants', 'named_difference']; @@ -98,6 +99,18 @@ export default function CovidVariantenPage(props: StaticProps(pageText, selectLokalizeTexts); const [isArchivedContentShown, setIsArchivedContentShown] = useState(false); + const [covidVariantsTimeframePeriod, setCovidVariantsTimeframePeriod] = useState({ start: 0, end: 0 }); + const archivedCovidVariantsTimeframePeriod = archivedVariantChart + ? { + start: archivedVariantChart[0].date_start_unix, + end: archivedVariantChart[archivedVariantChart?.length - 1].date_end_unix, + } + : undefined; + + const handleSetCovidVariantsTimeframePeriod = useCallback((value: DateRange | undefined) => { + setCovidVariantsTimeframePeriod(value); + }, []); + const metadata = { ...metadataTexts, title: textNl.metadata.title, @@ -140,7 +153,7 @@ export default function CovidVariantenPage(props: StaticProps )} @@ -234,6 +249,9 @@ export default function CovidVariantenPage(props: StaticProps )} diff --git a/packages/app/src/pages/landelijk/ziekenhuizen-in-beeld.tsx b/packages/app/src/pages/landelijk/ziekenhuizen-in-beeld.tsx index 3bcef1823f..506e4ecb8e 100644 --- a/packages/app/src/pages/landelijk/ziekenhuizen-in-beeld.tsx +++ b/packages/app/src/pages/landelijk/ziekenhuizen-in-beeld.tsx @@ -4,6 +4,7 @@ import { ChartTileToggleItem } from '~/components/chart-tile-toggle'; import { colors, getLastFilledValue, TimeframeOption, TimeframeOptionsList } from '@corona-dashboard/common'; import { createGetContent, getLastGeneratedDate, getLokalizeTexts, selectNlData } from '~/static-props/get-data'; import { createGetStaticProps, StaticProps } from '~/static-props/create-get-static-props'; +import { DateRange } from '~/components/metadata'; import { ElementsQueryResult, getElementsQuery, getTimelineEvents } from '~/queries/get-elements-query'; import { getArticleParts, getDataExplainedParts, getFaqParts, getLinkParts, getPagePartsQuery } from '~/queries/get-page-parts-query'; import { getLastInsertionDateOfPage } from '~/utils/get-last-insertion-date-of-page'; @@ -21,10 +22,10 @@ import { SEOHead } from '~/components/seo-head'; import { TileList } from '~/components/tile-list'; import { TimeSeriesChart } from '~/components/time-series-chart'; import { trimLeadingNullValues } from '~/utils/trim-leading-null-values'; +import { useCallback, useState } from 'react'; import { useDynamicLokalizeTexts } from '~/utils/cms/use-dynamic-lokalize-texts'; import { useIntl } from '~/intl'; import { useReverseRouter } from '~/utils'; -import { useState } from 'react'; const pageMetrics = [ 'difference.hospital_lcps__beds_occupied_covid', @@ -80,6 +81,9 @@ const HospitalsAndCarePage = (props: StaticProps) => { const [hospitalBedsOccupiedOverTimeTimeframe, setHospitalBedsOccupiedOverTimeTimeframe] = useState(TimeframeOption.THIRTY_DAYS); const [intensiveCareBedsTimeframe, setIntensiveCareBedsTimeframe] = useState(TimeframeOption.THIRTY_DAYS); + const [hospitalBedsOccupiedOverTimeTimeframePeriod, setHospitalBedOccupiedOverTimeTimeframePeriod] = useState({ start: 0, end: 0 }); + const [intensiveCareBedsTimeframePeriod, setIntensiveCareBedsTimeframePeriod] = useState({ start: 0, end: 0 }); + const gappedBarBandPaddingOverride = 0.4; const bedsOccupiedOverTimeToggleItems: ChartTileToggleItem[] = [ @@ -97,6 +101,9 @@ const HospitalsAndCarePage = (props: StaticProps) => { const [hospitalPatientInfluxOverTimeTimeframe, setHospitalPatientInfluxOverTimeTimeframe] = useState(TimeframeOption.THIRTY_DAYS); const [intensiveCarePatientInfluxOverTimeTimeframe, setIntensiveCarePatientInfluxOverTimeTimeframe] = useState(TimeframeOption.THIRTY_DAYS); + const [hospitalPatientInfluxOverTimeTimeframePeriod, setHospitalPatientInfluxOverTimeTimeframePeriod] = useState({ start: 0, end: 0 }); + const [intensiveCarePatientInfluxOverTimeTimeframePeriod, setIntensiveCarePatientInfluxOverTimeTimeframePeriod] = useState({ start: 0, end: 0 }); + const patientInfluxOverTimeToggleItems: ChartTileToggleItem[] = [ { label: textNl.hospitals.chart_patient_influx.toggle_label, @@ -115,6 +122,26 @@ const HospitalsAndCarePage = (props: StaticProps) => { const lcpsICWithoutRange = data.intensive_care_lcps.values.map((value) => ({ ...value, date_end_unix: undefined, date_start_unix: undefined })); const lastInsertionDateOfPage = getLastInsertionDateOfPage(data, pageMetrics); + const lastInsertionDateHospitalBedsOccupiedOverTime = getLastInsertionDateOfPage(data, ['hospital_lcps']); + const lastInsertionDateIntensiveCareBeds = getLastInsertionDateOfPage(data, ['intensive_care_lcps']); + const lastInsertionDateHospitalPatientInfluxOverTime = getLastInsertionDateOfPage(data, ['hospital_lcps']); + const lastInsertionDateIntensiveCarePatientInfluxOverTimeTimeframePeriod = getLastInsertionDateOfPage(data, ['intensive_care_lcps']); + + const handleHospitalBedsOccupiedOverTimeTimeframePeriodChange = useCallback((value: DateRange | undefined) => { + setHospitalBedOccupiedOverTimeTimeframePeriod(value); + }, []); + + const handleIntensiveCareBedsTimeframePeriodChange = useCallback((value: DateRange | undefined) => { + setIntensiveCareBedsTimeframePeriod(value); + }, []); + + const handleHospitalPatientInfluxOverTimeTimeframePeriodChange = useCallback((value: DateRange | undefined) => { + setHospitalPatientInfluxOverTimeTimeframePeriod(value); + }, []); + + const handleIntensiveCarePatientInfluxOverTimeTimeframePeriodChange = useCallback((value: DateRange | undefined) => { + setIntensiveCarePatientInfluxOverTimeTimeframePeriod(value); + }, []); return ( @@ -130,7 +157,7 @@ const HospitalsAndCarePage = (props: StaticProps) => { metadata={{ datumsText: textNl.datums, dateOrRange: hospitalLastValue.date_unix, - dateOfInsertionUnix: lastInsertionDateOfPage, + dateOfInsertion: lastInsertionDateOfPage, dataSources: [textNl.sources.lnaz], jsonSources: [{ href: reverseRouter.json.national(), text: jsonText.metrics_national_json.text }], }} @@ -168,7 +195,11 @@ const HospitalsAndCarePage = (props: StaticProps) => { timeframeOptions={TimeframeOptionsList} title={textNl.hospitals.chart_beds_occupied.title} description={textNl.hospitals.chart_beds_occupied.description} - metadata={{ source: textNl.sources.lnaz }} + metadata={{ + source: textNl.sources.lnaz, + timeframePeriod: hospitalBedsOccupiedOverTimeTimeframePeriod, + dateOfInsertion: lastInsertionDateHospitalBedsOccupiedOverTime, + }} timeframeInitialValue={hospitalBedsOccupiedOverTimeTimeframe} onSelectTimeframe={setHospitalBedsOccupiedOverTimeTimeframe} toggle={{ @@ -211,6 +242,7 @@ const HospitalsAndCarePage = (props: StaticProps) => { timelineEvents: getTimelineEvents(content.elements.timeSeries, 'hospital_lcps', 'beds_occupied_covid'), useDatesAsRange: false, }} + onHandleTimeframePeriodChange={handleHospitalBedsOccupiedOverTimeTimeframePeriodChange} /> )} @@ -219,7 +251,7 @@ const HospitalsAndCarePage = (props: StaticProps) => { ) => { timelineEvents: getTimelineEvents(content.elements.timeSeries, 'intensive_care_lcps', 'beds_occupied_covid'), useDatesAsRange: false, }} + onHandleTimeframePeriodChange={handleIntensiveCareBedsTimeframePeriodChange} /> )} @@ -293,7 +326,11 @@ const HospitalsAndCarePage = (props: StaticProps) => { timeframeOptions={TimeframeOptionsList} title={textNl.hospitals.chart_patient_influx.title} description={textNl.hospitals.chart_patient_influx.description} - metadata={{ source: textNl.sources.lnaz }} + metadata={{ + source: textNl.sources.lnaz, + timeframePeriod: hospitalPatientInfluxOverTimeTimeframePeriod, + dateOfInsertion: lastInsertionDateHospitalPatientInfluxOverTime, + }} timeframeInitialValue={hospitalPatientInfluxOverTimeTimeframe} onSelectTimeframe={setHospitalPatientInfluxOverTimeTimeframe} toggle={{ @@ -326,6 +363,7 @@ const HospitalsAndCarePage = (props: StaticProps) => { dataOptions={{ timelineEvents: getTimelineEvents(content.elements.timeSeries, 'hospital_lcps'), }} + onHandleTimeframePeriodChange={handleHospitalPatientInfluxOverTimeTimeframePeriodChange} /> )} @@ -335,7 +373,11 @@ const HospitalsAndCarePage = (props: StaticProps) => { timeframeOptions={TimeframeOptionsList} title={textNl.icu.chart_patient_influx.title} description={textNl.icu.chart_patient_influx.description} - metadata={{ source: textNl.sources.lnaz }} + metadata={{ + source: textNl.sources.lnaz, + timeframePeriod: intensiveCarePatientInfluxOverTimeTimeframePeriod, + dateOfInsertion: lastInsertionDateIntensiveCarePatientInfluxOverTimeTimeframePeriod, + }} timeframeInitialValue={intensiveCarePatientInfluxOverTimeTimeframe} onSelectTimeframe={setIntensiveCarePatientInfluxOverTimeTimeframe} toggle={{ @@ -368,6 +410,7 @@ const HospitalsAndCarePage = (props: StaticProps) => { dataOptions={{ timelineEvents: getTimelineEvents(content.elements.timeSeries, 'intensive_care_lcps'), }} + onHandleTimeframePeriodChange={handleIntensiveCarePatientInfluxOverTimeTimeframePeriodChange} /> )} diff --git a/packages/app/src/utils/get-last-insertion-date-of-page.ts b/packages/app/src/utils/get-last-insertion-date-of-page.ts index b689ed7800..3d2f82825f 100644 --- a/packages/app/src/utils/get-last-insertion-date-of-page.ts +++ b/packages/app/src/utils/get-last-insertion-date-of-page.ts @@ -6,8 +6,7 @@ function hasLastValue(metric: any): boolean { } function hasValues(metric: any): boolean { - return Array.isArray(metric?.values) && - typeof metric?.values[metric.values.length - 1]?.date_of_insertion_unix !== 'undefined'; + return Array.isArray(metric?.values) && typeof metric?.values[metric.values.length - 1]?.date_of_insertion_unix !== 'undefined'; } function hasInsertionDate(metric: any): boolean { @@ -15,8 +14,7 @@ function hasInsertionDate(metric: any): boolean { } function hasNestedLastValue(metric: any): boolean { - return Array.isArray(metric?.values) && - typeof metric?.values[0]?.last_value?.date_of_insertion_unix !== 'undefined'; + return Array.isArray(metric?.values) && typeof metric?.values[0]?.last_value?.date_of_insertion_unix !== 'undefined'; } // functions for getting values @@ -24,7 +22,7 @@ function getDateFromLastValue(metric: any): number { return metric?.last_value?.date_of_insertion_unix; } -function getDateFromValues(metric: any): number { +export function getDateFromValues(metric: any): number { return metric?.values[metric.values.length - 1]?.date_of_insertion_unix; } @@ -33,7 +31,7 @@ function getDateFromInsertionDate(metric: any): number { } function getDateFromNestedLastValue(metric: any): number { - return metric?.values.reduce((lastDate :number, innerValue: any) => { + return metric?.values.reduce((lastDate: number, innerValue: any) => { const metricDate = getMetricDate(innerValue); return Math.max(metricDate, lastDate); }, 0); @@ -55,10 +53,7 @@ function getMetricDate(metricOrUnixDate: any): number { return 0; } -export function getLastInsertionDateOfPage( - data: unknown, - pageMetrics: string[] -) { +export function getLastInsertionDateOfPage(data: unknown, pageMetrics: string[]) { const metricsAvailableInData: string[] = pageMetrics.filter((metricProperty) => { return typeof get(data, metricProperty) !== 'undefined'; }); @@ -72,5 +67,4 @@ export function getLastInsertionDateOfPage( const metricDate = getMetricDate(metric); return Math.max(metricDate, lastDate); }, 0); -}; - +}