From 8b323457c9929b10e06cac879cff734362ebafc1 Mon Sep 17 00:00:00 2001 From: VWSCoronaDashboard18 <93984341+VWSCoronaDashboard18@users.noreply.github.com> Date: Wed, 1 Jun 2022 23:57:34 +0200 Subject: [PATCH] Squashed commit of the following: commit 77ff7813298ad16ec14df33fe6f98b2128c50295 Author: VWSCoronaDashboard25 <98813868+VWSCoronaDashboard25@users.noreply.github.com> Date: Tue May 31 11:12:17 2022 +0200 feature(CMS): slice first 3 path elements of for the title because they are redundant in the preview (#4272) closes: COR-543 Co-authored-by: VWSCoronaDashboard25 commit f5bd004f8f688169093c7ceb9c50dbd0accac1c7 Author: MN <97020799+VWSCoronaDashboard24@users.noreply.github.com> Date: Mon May 30 16:10:34 2022 +0200 COR-725 unix date correction (#4255) * fix: use startOfDay for all graph values * fix: convert dates to startOfDay * fix: use endOfDay instead of middleOfDay for current date hook * fix: update tests Co-authored-by: VWSCoronaDashboard24 commit 6fcf9b4e1fc6a9a9b74921de1866458fd0f4f37f Author: J <93984341+VWSCoronaDashboard18@users.noreply.github.com> Date: Fri May 27 10:52:13 2022 +0200 Feature/cor 750 add dotted time series style (#4267) * Added a dot line for the time series graph * Added laganda support and group scatter plot dots commit 4eeff200484c1302a4c36698a5c30d3ecf01caa3 Author: VWSCoronaDashboard22 <93981265+VWSCoronaDashboard22@users.noreply.github.com> Date: Wed May 25 15:22:14 2022 +0200 Removed obsolete code for international pages (#4268) * Removed obsolete code for international pages * Removed type parameter commit 10d97063c626167c4eda20cc4bb069fef1b4ce9e Author: VWSCoronaDashboard25 <98813868+VWSCoronaDashboard25@users.noreply.github.com> Date: Wed May 25 14:24:46 2022 +0200 fix: set icon size for the top menu icons on smaller screens (#4266) These were forgotten with the refactor Co-authored-by: VWSCoronaDashboard25 commit 4f4abc9e9045f8a13de18678966c8e92c8072cb2 Author: VWSCoronaDashboard22 <93981265+VWSCoronaDashboard22@users.noreply.github.com> Date: Wed May 25 13:27:53 2022 +0200 Implemented redesign combobox and select list (#4264) * Implemented redesign combobox and select list * Removed unused imports * Removed sorting by score * Added padding to no results message * Always keep the same width for search form * Removed unused import * Fixed padding search results commit 38ec557d8dcca63bdf40a87a39a54993d76deeb8 Author: MN <97020799+VWSCoronaDashboard24@users.noreply.github.com> Date: Tue May 24 16:29:36 2022 +0200 COR-736 Behavior Choropleth Tooltip (#4262) * fix: fall back to - when no data is available for behavior choropleth tooltip * fix: show 0% when data is not null but 0 Co-authored-by: VWSCoronaDashboard24 commit cb44e92806b5a335d887ce30bbd7f74db8c69136 Author: HO <93981322+VWSCoronaDashboard19@users.noreply.github.com> Date: Tue May 24 14:45:50 2022 +0200 fix: revert changes, replace with empty div and pass optional props (#4263) commit 26a07c71e2ef4bf6e8cdc27dae0176806d9e7c38 Author: MN <97020799+VWSCoronaDashboard24@users.noreply.github.com> Date: Tue May 24 11:34:08 2022 +0200 COR-618 Resolve duplicate IDs (#4261) * fix: only render mini charts once based on screen size * fix: use unique ids for different chart elements and accessibility-annotations * fix: mock useUniqueId hook * fix: cleanup mock after test Co-authored-by: VWSCoronaDashboard24 commit 64861ee575314aae0d8d6faf2c20dbb335974bfc Author: HO <93981322+VWSCoronaDashboard19@users.noreply.github.com> Date: Mon May 23 15:02:23 2022 +0200 Archive page and add warning tile (#4260) * feat(situationsPage): archive page and add warning tile * feat: added new key for warning commit 1ab4c1b2096bc7e3681f6edc8e37b24575e7cba3 Author: VWSCoronaDashboard25 <98813868+VWSCoronaDashboard25@users.noreply.github.com> Date: Mon May 23 12:05:16 2022 +0200 Refactor/cor 73 remove fixed width and height in icons (#4256) * refactor: remove width and height of icons with a viewBox * refactor: replace width and height of icons with a viewBox * refactor: set size of metadata icon in metadata instead Use a styled span similar to the icon in the header component * refactor: set size of situation icon in code Using the extended properties of the generated React element Co-authored-by: VWSCoronaDashboard25 commit 2605658f00edd7830e4e2f15795d2c28002016a6 Author: VWSCoronaDashboard22 <93981265+VWSCoronaDashboard22@users.noreply.github.com> Date: Thu May 19 15:05:53 2022 +0200 Added string year to age group (#4259) commit f506760b93fcd698fdb312c1faa6027b31daca6b Author: J <93984341+VWSCoronaDashboard18@users.noreply.github.com> Date: Thu May 19 13:58:38 2022 +0200 Feature/cor 615 fix two kpi tiles with one column (#4257) * change to grid * Remove extra KPI tile * Fix margins and paddings commit 4d02ed502742fb416644de6a176bb7315cd587c1 Author: MN <97020799+VWSCoronaDashboard24@users.noreply.github.com> Date: Thu May 19 13:46:30 2022 +0200 fix: fall back to - when no data is available for behavior choropleth tooltip (#4258) Co-authored-by: VWSCoronaDashboard24 commit 2fd679be8c713b031b8f47e0e6acbb5898ae8e5d Author: VWSCoronaDashboard22 <93981265+VWSCoronaDashboard22@users.noreply.github.com> Date: Thu May 19 08:46:13 2022 +0200 Feature/cor 733 hospital admissions per 100000 (#4254) * Removed user-scalable and added maximum-scale=5 * Changed metric key and legend on hospital admissions choropleth commit ed58ee4d00890423f15e192a0dc72e1cd1e6c2e9 Author: VWSCoronaDashboard22 <93981265+VWSCoronaDashboard22@users.noreply.github.com> Date: Wed May 18 12:37:29 2022 +0200 Removed user-scalable and added maximum-scale=5 (#4253) commit eed6f66e0daf8e2c0f204a878a0e4712a27de47d Author: HO <93981322+VWSCoronaDashboard19@users.noreply.github.com> Date: Wed May 18 10:05:48 2022 +0200 feat: upgrade version sanity cli (#4251) commit 479eab055186af493ddc188d49b7864709eb77a5 Author: VWSCoronaDashboard22 <93981265+VWSCoronaDashboard22@users.noreply.github.com> Date: Wed May 18 09:51:22 2022 +0200 Set text y axis to bold and black (#4250) commit 20f9d6a91fa4c44fa01e931fce14dc56549f99b6 Author: VWSCoronaDashboard22 <93981265+VWSCoronaDashboard22@users.noreply.github.com> Date: Wed May 18 08:37:22 2022 +0200 Ignore forced maximum when out of bounds value is outside time domain (#4246) * Ignore forced maximum when out of bounds value is outside time domain * Lint fixes * Added hasOutofBoudsValues to useMemo dependency array * Use Math.min instead of ternary operator * Type check calculatedForcedMaximumValue for seriesMax commit f34638fb79a8a1dd821a2e93cdadb732b387925a Author: MN <97020799+VWSCoronaDashboard24@users.noreply.github.com> Date: Tue May 17 14:58:00 2022 +0200 COR-676 - Behavior keys optional in json schemas (#4241) * fix: make selftest_visit_behavior optional in json schemas * feat: make behavior json keys optional Co-authored-by: VWSCoronaDashboard24 commit 390905ba1284762aea9b61bb49736dc777718028 Author: HO <93981322+VWSCoronaDashboard19@users.noreply.github.com> Date: Tue May 17 13:57:11 2022 +0200 Remove booster past seven days from vaccinations page (#4249) * feat: updated schemas * feat(booster): remove last seven days from booster commit 50fc1e85cdd22452d408899a58d63a9b6414b338 Author: HO <93981322+VWSCoronaDashboard19@users.noreply.github.com> Date: Tue May 17 09:54:11 2022 +0200 feat(measures): change h2 to h1 for page title (#4247) commit 7d0b918b86c6b4ca389bfa88a4598e00858a4374 Author: HO <93981322+VWSCoronaDashboard19@users.noreply.github.com> Date: Tue May 17 09:03:53 2022 +0200 feat: change display names to search terms (#4245) commit 83dff1849e50b6c60cf877863c446eaabaa9047f Author: HO <93981322+VWSCoronaDashboard19@users.noreply.github.com> Date: Fri May 13 11:50:42 2022 +0200 feat: flip h1 with h2 and keep styling as it is (#4244) --- .../schema/nl/booster_shot_administered.json | 12 +--- .../age-demographic/age-demographic-chart.tsx | 11 ++- packages/app/src/components/index.ts | 3 + .../layout/components/top-navigation.tsx | 4 +- .../components/header.tsx | 9 +-- .../components/metadata.tsx | 22 ++++-- .../rich-content-select/components/index.tsx | 4 +- .../components/bar-trend.tsx | 2 +- .../components/gapped-line-trend.tsx | 2 +- .../time-series-chart/components/index.ts | 1 + .../components/scatter-plot.tsx | 67 +++++++++++++++++++ .../components/series-icon.tsx | 3 + .../time-series-chart/components/series.tsx | 17 ++++- .../components/split-bar-trend.tsx | 2 +- .../time-series-chart/logic/common.ts | 6 +- .../time-series-chart/logic/hover-state.ts | 1 + .../time-series-chart/logic/legend.tsx | 8 ++- .../time-series-chart/logic/series.ts | 10 +++ .../time-series-chart/time-series-chart.tsx | 23 ++++--- .../app/src/components/two-kpi-section.tsx | 14 +++- .../behavior/behavior-choropleths-tile.tsx | 13 ++-- .../behavior/tooltip/vr-behavior-tooltip.tsx | 26 ++++--- packages/app/src/domain/layout/logic/types.ts | 1 + packages/app/src/domain/layout/nl-layout.tsx | 15 ++--- packages/app/src/domain/layout/vr-layout.tsx | 19 +++++- .../situations/components/situation-icon.tsx | 2 +- .../topical/components/search/context.tsx | 11 ++- .../topical/components/search/hit-list.tsx | 53 +++++++++++++-- .../components/search/search-results.tsx | 27 ++------ .../topical/components/search/search.tsx | 5 +- .../components/search/use-search-results.ts | 6 +- .../topical/mini-tile-selector-layout.tsx | 20 +++--- .../vaccine/vaccinations-shot-kpi-section.tsx | 21 +++--- ...ne-booster-administrations-kpi-section.tsx | 33 +++------ packages/app/src/pages/_app.tsx | 2 +- .../app/src/pages/actueel/gemeente/[code].tsx | 5 +- .../pages/actueel/veiligheidsregio/[code].tsx | 5 +- .../gemeente/[code]/ziekenhuis-opnames.tsx | 3 +- .../app/src/pages/landelijk/brononderzoek.tsx | 17 ++++- .../landelijk/intensive-care-opnames.tsx | 8 ++- .../app/src/pages/landelijk/maatregelen.tsx | 4 +- .../app/src/pages/landelijk/vaccinaties.tsx | 24 ++----- .../pages/landelijk/ziekenhuis-opnames.tsx | 8 ++- .../veiligheidsregio/[code]/brononderzoek.tsx | 29 +++++--- .../veiligheidsregio/[code]/maatregelen.tsx | 2 +- .../[code]/ziekenhuis-opnames.tsx | 3 +- packages/app/src/static-props/get-data.ts | 31 +-------- .../__tests__/current-date-context.spec.tsx | 8 +-- .../use-accessibility-features.spec.tsx | 18 ++++- .../app/src/utils/current-date-context.tsx | 6 +- .../utils/use-accessibility-annotations.tsx | 4 +- packages/cms/package.json | 4 +- packages/cms/src/lokalize/key-mutations.csv | 4 ++ .../src/schemas/documents/lokalize-text.ts | 9 ++- packages/common/src/data/gm.ts | 4 +- packages/common/src/types/data.ts | 4 +- packages/common/src/utils/timeframe/index.ts | 20 ++++-- packages/icons/src/svg/afstand-sporten.svg | 2 +- packages/icons/src/svg/afstand.svg | 2 +- packages/icons/src/svg/alcohol-verkoop.svg | 2 +- packages/icons/src/svg/arts-small.svg | 2 +- packages/icons/src/svg/avoid_crowds.svg | 2 +- packages/icons/src/svg/avondklok.svg | 4 +- .../icons/src/svg/basisregels_afstand.svg | 2 +- .../icons/src/svg/basisregels_blijf-thuis.svg | 2 +- packages/icons/src/svg/basisregels_drukte.svg | 2 +- .../icons/src/svg/basisregels_elleboog.svg | 2 +- .../icons/src/svg/basisregels_geen-bezoek.svg | 2 +- .../src/svg/basisregels_handenwassen.svg | 2 +- .../icons/src/svg/basisregels_mondkapje.svg | 2 +- packages/icons/src/svg/basisregels_testen.svg | 2 +- packages/icons/src/svg/bevolking.svg | 2 +- packages/icons/src/svg/bezoek.svg | 2 +- packages/icons/src/svg/bibliotheken.svg | 2 +- .../icons/src/svg/binnen-met-zitplaats.svg | 2 +- .../icons/src/svg/binnen-zonder-zitplaats.svg | 2 +- packages/icons/src/svg/binnensporten.svg | 2 +- .../icons/src/svg/binnensportlocaties.svg | 2 +- packages/icons/src/svg/boosterprik.svg | 2 +- packages/icons/src/svg/chart.svg | 2 +- packages/icons/src/svg/check-small.svg | 4 +- packages/icons/src/svg/check.svg | 2 +- packages/icons/src/svg/checked.svg | 2 +- .../icons/src/svg/chevron-down-magenta.svg | 2 +- packages/icons/src/svg/chevron-down.svg | 2 +- packages/icons/src/svg/chevron-large.svg | 2 +- packages/icons/src/svg/chevron.svg | 2 +- packages/icons/src/svg/clock.svg | 2 +- packages/icons/src/svg/close-thick.svg | 2 +- packages/icons/src/svg/close.svg | 2 +- packages/icons/src/svg/contactberoepen.svg | 2 +- packages/icons/src/svg/coronavirus.svg | 2 +- packages/icons/src/svg/cross-small.svg | 4 +- packages/icons/src/svg/cross.svg | 2 +- packages/icons/src/svg/curfew.svg | 4 +- packages/icons/src/svg/database.svg | 2 +- .../icons/src/svg/doorstroomevenementen.svg | 2 +- packages/icons/src/svg/download.svg | 2 +- .../src/svg/een-persoon-doorgestreept.svg | 2 +- packages/icons/src/svg/elleboog.svg | 2 +- packages/icons/src/svg/expand.svg | 2 +- packages/icons/src/svg/external.svg | 2 +- packages/icons/src/svg/frame_2.svg | 2 +- packages/icons/src/svg/frisse_lucht.svg | 2 +- packages/icons/src/svg/gathering.svg | 2 +- .../src/svg/gedeeltelijk-open-rugzak.svg | 2 +- packages/icons/src/svg/gedrag.svg | 2 +- packages/icons/src/svg/geen-entertainment.svg | 2 +- .../src/svg/geen-max-aantal-bezoekers.svg | 2 +- packages/icons/src/svg/geen-wedstrijden.svg | 2 +- packages/icons/src/svg/gehandicapten-zorg.svg | 2 +- packages/icons/src/svg/gehandicaptenzorg.svg | 2 +- ...rganiseerde-kunst-en-cultuurbeoefening.svg | 2 +- packages/icons/src/svg/groepen.svg | 2 +- packages/icons/src/svg/handenwassen.svg | 2 +- packages/icons/src/svg/health_care.svg | 2 +- packages/icons/src/svg/home_and_visits.svg | 2 +- .../svg/horeca-en-evenementen_bestellen.svg | 2 +- .../svg/horeca-en-evenementen_etendrinken.svg | 2 +- .../svg/horeca-en-evenementen_evenementen.svg | 2 +- packages/icons/src/svg/horeca_evenementen.svg | 2 +- packages/icons/src/svg/hospitality.svg | 2 +- packages/icons/src/svg/information.svg | 2 +- packages/icons/src/svg/keep_distance.svg | 2 +- packages/icons/src/svg/klachten.svg | 2 +- packages/icons/src/svg/klok-2100.svg | 2 +- packages/icons/src/svg/kunst-cultuur.svg | 2 +- packages/icons/src/svg/kunstcultuur_musea.svg | 2 +- packages/icons/src/svg/locatie.svg | 2 +- packages/icons/src/svg/lopend.svg | 2 +- packages/icons/src/svg/maatregelen.svg | 2 +- .../icons/src/svg/max-aantal-bezoekers.svg | 2 +- packages/icons/src/svg/max_visitors.svg | 2 +- packages/icons/src/svg/meer-informatie.svg | 2 +- .../icons/src/svg/meerdaagse-evenementen.svg | 2 +- packages/icons/src/svg/menu.svg | 2 +- packages/icons/src/svg/mondkapje.svg | 2 +- packages/icons/src/svg/nederland.svg | 2 +- packages/icons/src/svg/notification.svg | 2 +- ...onderwijs-en-kinderopvang_kinderopvang.svg | 2 +- .../onderwijs-en-kinderopvang_noodopvang.svg | 2 +- .../onderwijs-en-kinderopvang_op-afstand.svg | 2 +- .../icons/src/svg/ontmoetingen_bezoek.svg | 2 +- packages/icons/src/svg/openbaar-vervoer.svg | 2 +- packages/icons/src/svg/openingstijden.svg | 2 +- packages/icons/src/svg/other.svg | 2 +- packages/icons/src/svg/oversterfte.svg | 2 +- .../icons/src/svg/positief_geteste_mensen.svg | 2 +- .../svg/publiek-toegankelijke-locaties.svg | 2 +- packages/icons/src/svg/recreatie.svg | 2 +- packages/icons/src/svg/reizen.svg | 2 +- .../icons/src/svg/reproductiegetal-small.svg | 2 +- packages/icons/src/svg/reproductiegetal.svg | 2 +- packages/icons/src/svg/rioolvirus.svg | 2 +- .../icons/src/svg/school_and_day_care.svg | 2 +- packages/icons/src/svg/search-icon-bold.svg | 2 +- packages/icons/src/svg/search-icon.svg | 2 +- packages/icons/src/svg/sneeze_cough_elbow.svg | 2 +- .../src/svg/sport_binnensportlocaties.svg | 2 +- packages/icons/src/svg/sport_buiten.svg | 2 +- packages/icons/src/svg/sport_wedstrijden.svg | 2 +- .../icons/src/svg/sporter-met-zweetband.svg | 2 +- packages/icons/src/svg/stap-1_avondklok.svg | 2 +- packages/icons/src/svg/stap_1-horeca_max.svg | 2 +- .../icons/src/svg/stap_1-horeca_pertafel.svg | 2 +- .../src/svg/stap_1-horeca_reserveren.svg | 2 +- .../svg/stap_1-horeca_sportaccomodaties.svg | 2 +- .../icons/src/svg/stap_1-horeca_terras.svg | 2 +- .../src/svg/stap_1-horeca_verplaatsen.svg | 2 +- .../src/svg/stap_1-onderwijs_bibliotheek.svg | 2 +- .../icons/src/svg/stap_1-onderwijs_open.svg | 2 +- packages/icons/src/svg/stap_1-theorie.svg | 2 +- packages/icons/src/svg/stap_1-thuisbezoek.svg | 2 +- packages/icons/src/svg/stap_1-uitvaarten.svg | 2 +- .../icons/src/svg/stap_1-winkels_alleen.svg | 2 +- .../icons/src/svg/stap_1-winkels_markten.svg | 2 +- packages/icons/src/svg/stap_1-winkels_max.svg | 2 +- .../icons/src/svg/stap_1-winkels_open.svg | 2 +- packages/icons/src/svg/stopwatch.svg | 2 +- .../icons/src/svg/symptoms_get_tested.svg | 2 +- packages/icons/src/svg/symptoms_stay_home.svg | 2 +- packages/icons/src/svg/taxi.svg | 2 +- packages/icons/src/svg/testbewijs.svg | 2 +- packages/icons/src/svg/testen.svg | 2 +- packages/icons/src/svg/teststraat.svg | 2 +- packages/icons/src/svg/thuis.svg | 2 +- packages/icons/src/svg/thuisblijven.svg | 2 +- packages/icons/src/svg/thuiswerken.svg | 2 +- packages/icons/src/svg/toegangsbewijzen.svg | 2 +- packages/icons/src/svg/travel.svg | 2 +- packages/icons/src/svg/unchecked.svg | 2 +- packages/icons/src/svg/vaccinaties.svg | 2 +- packages/icons/src/svg/vaccine.svg | 4 +- .../icons/src/svg/vaccine_booster_third.svg | 2 +- packages/icons/src/svg/varianten.svg | 2 +- packages/icons/src/svg/vermijd.svg | 2 +- packages/icons/src/svg/verpleeghuis.svg | 2 +- packages/icons/src/svg/verpleeghuiszorg.svg | 2 +- .../src/svg/vervoer-en-reizen_blijfthuis.svg | 2 +- .../src/svg/vervoer-en-reizen_buitenland.svg | 2 +- .../icons/src/svg/vervoer-en-reizen_ov.svg | 2 +- packages/icons/src/svg/vliegen.svg | 2 +- packages/icons/src/svg/wash_hands.svg | 2 +- .../src/svg/wear_mask_public_indoors.svg | 2 +- .../src/svg/wear_mask_public_transport.svg | 2 +- .../svg/winkelen-en-boodschappen_alcohol.svg | 2 +- .../src/svg/winkelen-en-boodschappen_open.svg | 2 +- packages/icons/src/svg/work.svg | 2 +- packages/icons/src/svg/work_from_home.svg | 2 +- packages/icons/src/svg/ziekenhuis-small.svg | 2 +- yarn.lock | 10 +-- 211 files changed, 616 insertions(+), 405 deletions(-) create mode 100644 packages/app/src/components/time-series-chart/components/scatter-plot.tsx diff --git a/packages/app/schema/nl/booster_shot_administered.json b/packages/app/schema/nl/booster_shot_administered.json index 87a1103142..5f6326eeea 100644 --- a/packages/app/schema/nl/booster_shot_administered.json +++ b/packages/app/schema/nl/booster_shot_administered.json @@ -25,19 +25,13 @@ "administered_total": { "type": "number" }, - "ggd_administered_last_7_days": { - "type": "number" - }, "ggd_administered_total": { "type": "number" }, "others_administered_total": { "type": "number" }, - "date_start_unix": { - "type": "integer" - }, - "date_end_unix": { + "date_unix": { "type": "integer" }, "date_of_insertion_unix": { @@ -46,11 +40,9 @@ }, "required": [ "administered_total", - "ggd_administered_last_7_days", "ggd_administered_total", "others_administered_total", - "date_start_unix", - "date_end_unix", + "date_unix", "date_of_insertion_unix" ], "additionalProperties": false diff --git a/packages/app/src/components/age-demographic/age-demographic-chart.tsx b/packages/app/src/components/age-demographic/age-demographic-chart.tsx index f0d2045e62..8dd6c7a8ed 100644 --- a/packages/app/src/components/age-demographic/age-demographic-chart.tsx +++ b/packages/app/src/components/age-demographic/age-demographic-chart.tsx @@ -10,6 +10,7 @@ import { KeyboardEvent, MouseEvent } from 'react'; import styled from 'styled-components'; import { Box } from '~/components/base'; import { Text } from '~/components/typography'; +import { replaceVariablesInText } from '~/utils'; import { AccessibilityDefinition, useAccessibilityAnnotations, @@ -229,12 +230,16 @@ export function AgeDemographicChart({ textAnchor="middle" verticalAnchor="middle" fontSize="12" + fontWeight="bold" y={ageGroupRangePoint(value) + singleBarHeight / 2} x={width / 2} - fill={colors.annotation} + fill="black" > - {formatAgeGroupRange(ageGroupRange(value)) + - (isClippedValue ? ' *' : '')} + {replaceVariablesInText(text.age_group_range_tooltip, { + ageGroupRange: + formatAgeGroupRange(ageGroupRange(value)) + + (isClippedValue ? ' *' : ''), + })} {collapsible.button( - {collapsible.isOpen ? : } + {collapsible.isOpen + ? + : } {collapsible.isOpen ? commonTexts.nav.menu.close_menu diff --git a/packages/app/src/components/page-information-block/components/header.tsx b/packages/app/src/components/page-information-block/components/header.tsx index 05d5065569..c97bd2a07a 100644 --- a/packages/app/src/components/page-information-block/components/header.tsx +++ b/packages/app/src/components/page-information-block/components/header.tsx @@ -32,7 +32,7 @@ export function Header({ {icon && !isMediumScreen && {icon}} {category && ( - + {category} {screenReaderCategory && ( {`- ${screenReaderCategory}`} @@ -41,12 +41,7 @@ export function Header({ )} {icon && isMediumScreen && {icon}} - + {title} diff --git a/packages/app/src/components/page-information-block/components/metadata.tsx b/packages/app/src/components/page-information-block/components/metadata.tsx index 4dbd28b6e3..ac3cc04eef 100644 --- a/packages/app/src/components/page-information-block/components/metadata.tsx +++ b/packages/app/src/components/page-information-block/components/metadata.tsx @@ -7,6 +7,7 @@ import { } from '@corona-dashboard/icons'; import css from '@styled-system/css'; import { Fragment } from 'react'; +import styled from 'styled-components' import { Box } from '~/components/base'; import { ExternalLink } from '~/components/external-link'; import { Anchor, InlineText, Text } from '~/components/typography'; @@ -61,9 +62,9 @@ export function Metadata({ return ( - + - + {dateText} @@ -157,9 +158,7 @@ function MetadataItem({ return ( - - {icon} - + {icon} {referenceLink && !items && ( @@ -223,7 +222,7 @@ function MetadataReference({ icon, referenceLink }: metadataReferenceProps) { return ( - {icon} + {icon} @@ -249,3 +248,14 @@ function MetadataReference({ icon, referenceLink }: metadataReferenceProps) { ); } + +const Icon = styled.span(() => + css({ + minWidth: '1.8rem', + + svg: { + height: '15px', + width: 'auto', + }, + }) +); diff --git a/packages/app/src/components/rich-content-select/components/index.tsx b/packages/app/src/components/rich-content-select/components/index.tsx index 238c64127b..de45576dfb 100644 --- a/packages/app/src/components/rich-content-select/components/index.tsx +++ b/packages/app/src/components/rich-content-select/components/index.tsx @@ -101,7 +101,9 @@ export const ListBoxOption = styled(Box)( }, }, '&:hover': { - backgroundColor: 'tileGray', + backgroundColor: 'blue', + color: 'white', + fontWeight: 'normal', }, }) ); diff --git a/packages/app/src/components/time-series-chart/components/bar-trend.tsx b/packages/app/src/components/time-series-chart/components/bar-trend.tsx index 970a4a203e..c9ee8bd671 100644 --- a/packages/app/src/components/time-series-chart/components/bar-trend.tsx +++ b/packages/app/src/components/time-series-chart/components/bar-trend.tsx @@ -119,7 +119,7 @@ export function BarTrend({ height={barHeight} width={barWidth} fill={transparentize(1 - fillOpacity, color)} - id={id} + id={`${id}_${index}`} /> ); })} diff --git a/packages/app/src/components/time-series-chart/components/gapped-line-trend.tsx b/packages/app/src/components/time-series-chart/components/gapped-line-trend.tsx index dbf2a0db79..6e9c5be3b7 100644 --- a/packages/app/src/components/time-series-chart/components/gapped-line-trend.tsx +++ b/packages/app/src/components/time-series-chart/components/gapped-line-trend.tsx @@ -35,7 +35,7 @@ export function GappedLinedTrend(props: GappedLinedTrendProps) { curve={curve} getX={getX} getY={getY} - id={id} + id={`${id}_${index}`} /> ))} diff --git a/packages/app/src/components/time-series-chart/components/index.ts b/packages/app/src/components/time-series-chart/components/index.ts index 18c25f2d3a..ed37ed435a 100644 --- a/packages/app/src/components/time-series-chart/components/index.ts +++ b/packages/app/src/components/time-series-chart/components/index.ts @@ -6,6 +6,7 @@ export * from './chart-container'; export * from './date-line-marker'; export * from './date-span-marker'; export * from './line-trend'; +export * from './scatter-plot'; export * from './overlay'; export * from './point-markers'; export * from './range-trend'; diff --git a/packages/app/src/components/time-series-chart/components/scatter-plot.tsx b/packages/app/src/components/time-series-chart/components/scatter-plot.tsx new file mode 100644 index 0000000000..b564fd77c7 --- /dev/null +++ b/packages/app/src/components/time-series-chart/components/scatter-plot.tsx @@ -0,0 +1,67 @@ +import { useMemo } from 'react'; +import { isPresent } from 'ts-is-present'; +import { SeriesItem, SeriesSingleValue } from '../logic'; +import { Group } from '@visx/group'; + +const DEFAULT_DOT_SIZE = 3; + +type LineTrendProps = { + series: SeriesSingleValue[]; + color: string; + getX: (v: SeriesItem) => number; + getY: (v: SeriesSingleValue) => number; + id: string; +}; + +export function ScatterPlot({ + series: dataSeries, + color, + getX, + getY, + id, +}: LineTrendProps) { + const series = useMemo( + () => dataSeries.filter((x) => isPresent(x.__value)), + [dataSeries] + ); + + return series.length === 0 ? null : ( + + {series.map((data, i) => ( + + ))} + + ); +} + +interface ScatterPlotIconProps { + color: string; + radius?: number; + width?: number; + height?: number; +} + +export function ScatterPlotIcon({ + color, + width = 15, + height = 15, + radius = 3, +}: ScatterPlotIconProps) { + return ( + + + + ); +} diff --git a/packages/app/src/components/time-series-chart/components/series-icon.tsx b/packages/app/src/components/time-series-chart/components/series-icon.tsx index 8f9466caf8..589f3c3f60 100644 --- a/packages/app/src/components/time-series-chart/components/series-icon.tsx +++ b/packages/app/src/components/time-series-chart/components/series-icon.tsx @@ -4,6 +4,7 @@ import { findSplitPointForValue, SeriesConfig } from '../logic'; import { AreaTrendIcon } from './area-trend'; import { BarTrendIcon } from './bar-trend'; import { LineTrendIcon } from './line-trend'; +import { ScatterPlotIcon } from './scatter-plot'; import { RangeTrendIcon } from './range-trend'; import { SplitAreaTrendIcon } from './split-area-trend'; import { StackedAreaTrendIcon } from './stacked-area-trend'; @@ -33,6 +34,8 @@ export function SeriesIcon({ style={config.style} /> ); + case 'scatter-plot': + return ; case 'range': return ( diff --git a/packages/app/src/components/time-series-chart/components/series.tsx b/packages/app/src/components/time-series-chart/components/series.tsx index 19ba630f82..0699cdb44b 100644 --- a/packages/app/src/components/time-series-chart/components/series.tsx +++ b/packages/app/src/components/time-series-chart/components/series.tsx @@ -1,7 +1,7 @@ import { TimestampedValue } from '@corona-dashboard/common'; import { ScaleLinear } from 'd3-scale'; import { memo } from 'react'; -import { AreaTrend, BarTrend, LineTrend, RangeTrend } from '.'; +import { AreaTrend, BarTrend, LineTrend, ScatterPlot, RangeTrend } from '.'; import { Bounds, GetX, @@ -61,8 +61,8 @@ function SeriesUnmemoized({ const config = seriesConfig[index]; const id = config.type === 'range' - ? `${chartId}_${config.metricPropertyLow}_${config.metricPropertyHigh}` - : `${chartId}_${config.metricProperty}`; + ? `${chartId}_${config.metricPropertyLow}_${config.metricPropertyHigh}_${config.type}` + : `${chartId}_${config.metricProperty}_${config.type}`; switch (config.type) { case 'gapped-line': @@ -93,6 +93,17 @@ function SeriesUnmemoized({ id={id} /> ); + case 'scatter-plot': + return ( + + ); case 'area': return ( boolean; + checkIsOutofBounds: ( + a: any, + b: number, + c: [start: number, end: number] + ) => boolean; }; export interface BenchmarkConfig { diff --git a/packages/app/src/components/time-series-chart/logic/hover-state.ts b/packages/app/src/components/time-series-chart/logic/hover-state.ts index fe5d5f47f4..67d449a918 100644 --- a/packages/app/src/components/time-series-chart/logic/hover-state.ts +++ b/packages/app/src/components/time-series-chart/logic/hover-state.ts @@ -333,6 +333,7 @@ export function useHoverState({ switch (config.type) { case 'line': + case 'scatter-plot': case 'gapped-line': case 'area': case 'gapped-area': diff --git a/packages/app/src/components/time-series-chart/logic/legend.tsx b/packages/app/src/components/time-series-chart/logic/legend.tsx index 603919b7c9..e7f406bc8c 100644 --- a/packages/app/src/components/time-series-chart/logic/legend.tsx +++ b/packages/app/src/components/time-series-chart/logic/legend.tsx @@ -20,7 +20,8 @@ type SplitLegendGroup = { label: string; items: LegendItem[] }; export function useLegendItems( domain: number[], config: SeriesConfig, - dataOptions?: DataOptions + dataOptions?: DataOptions, + hasOutofBoudsValues = false ) { const { timelineEvents, timespanAnnotations, outOfBoundsConfig } = dataOptions || {}; @@ -50,9 +51,9 @@ export function useLegendItems( }) .filter(isDefined); - if (outOfBoundsConfig) { + if (hasOutofBoudsValues) { legendItems.push({ - label: outOfBoundsConfig.label, + label: outOfBoundsConfig?.label, shape: 'custom', shapeComponent: , } as LegendItem); @@ -136,5 +137,6 @@ export function useLegendItems( timelineEvents, timespanAnnotations, outOfBoundsConfig, + hasOutofBoudsValues, ]); } diff --git a/packages/app/src/components/time-series-chart/logic/series.ts b/packages/app/src/components/time-series-chart/logic/series.ts index ecf400ee73..041b9756bd 100644 --- a/packages/app/src/components/time-series-chart/logic/series.ts +++ b/packages/app/src/components/time-series-chart/logic/series.ts @@ -15,6 +15,7 @@ import { SplitPoint } from './split'; type SeriesConfigSingle = | LineSeriesDefinition + | ScatterPlotSeriesDefinition | RangeSeriesDefinition | AreaSeriesDefinition | StackedAreaSeriesDefinition @@ -89,6 +90,15 @@ export interface LineSeriesDefinition curve?: 'linear' | 'step'; } +export interface ScatterPlotSeriesDefinition + extends SeriesCommonDefinition { + type: 'scatter-plot'; + metricProperty: keyof T; + label: string; + shortLabel?: string; + color: string; +} + export interface AreaSeriesDefinition extends SeriesCommonDefinition { type: 'area'; 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 b05e39015f..7c633cfddc 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 @@ -241,11 +241,14 @@ export function TimeSeriesChart< [seriesList, seriesConfig, benchmark?.value] ); - const seriesMax = isDefined(forcedMaximumValue) - ? isFunction(forcedMaximumValue) - ? forcedMaximumValue(calculatedSeriesMax) - : forcedMaximumValue - : calculatedSeriesMax; + const calculatedForcedMaximumValue = isFunction(forcedMaximumValue) + ? forcedMaximumValue(calculatedSeriesMax) + : forcedMaximumValue; + + const seriesMax = + typeof calculatedForcedMaximumValue === 'number' + ? Math.min(calculatedForcedMaximumValue, calculatedSeriesMax) + : calculatedSeriesMax; const minimumRanges = seriesConfig .map((c) => c.minimumRange) @@ -275,11 +278,13 @@ export function TimeSeriesChart< const { legendItems, splitLegendGroups } = useLegendItems( xScale.domain(), seriesConfig, - dataOptions + dataOptions, + dataOptions?.outOfBoundsConfig && seriesMax < calculatedSeriesMax ); const timeDomain = useMemo( - () => getTimeDomain({ values, today: endDate ?? today, withPadding: false }), + () => + getTimeDomain({ values, today: endDate ?? today, withPadding: false }), [values, endDate, today] ); @@ -367,7 +372,8 @@ export function TimeSeriesChart< seriesMax, isOutOfBounds: dataOptions?.outOfBoundsConfig?.checkIsOutofBounds( values[valuesIndex], - seriesMax + seriesMax, + timeDomain ), }, tooltipLeft: nearestPoint.x, @@ -391,6 +397,7 @@ export function TimeSeriesChart< timelineState.events, metricPropertyFormatters, seriesMax, + timeDomain, ]); useOnClickOutside([containerRef], () => tooltipData && hideTooltip()); diff --git a/packages/app/src/components/two-kpi-section.tsx b/packages/app/src/components/two-kpi-section.tsx index 13477919d1..1b63a16e75 100644 --- a/packages/app/src/components/two-kpi-section.tsx +++ b/packages/app/src/components/two-kpi-section.tsx @@ -1,19 +1,29 @@ -import css from '@styled-system/css'; import React from 'react'; +import css from '@styled-system/css'; import { asResponsiveArray } from '~/style/utils'; import { Box } from './base'; interface TwoKpiSectionProps { children: React.ReactNode; spacing?: number; + hasBorder?: boolean; + hasPadding?: boolean; } -export function TwoKpiSection({ children, spacing }: TwoKpiSectionProps) { +export function TwoKpiSection({ + children, + spacing, + hasBorder = false, + hasPadding = false, +}: TwoKpiSectionProps) { return ( *': { flex: 1, }, diff --git a/packages/app/src/domain/behavior/behavior-choropleths-tile.tsx b/packages/app/src/domain/behavior/behavior-choropleths-tile.tsx index a2cf6d2189..c083eb4322 100644 --- a/packages/app/src/domain/behavior/behavior-choropleths-tile.tsx +++ b/packages/app/src/domain/behavior/behavior-choropleths-tile.tsx @@ -4,6 +4,7 @@ import { VrCollectionBehavior, } from '@corona-dashboard/common'; import css from '@styled-system/css'; +import { isNumber } from 'lodash'; import { useMemo } from 'react'; import { Box } from '~/components/base'; import { ChartTile } from '~/components/chart-tile'; @@ -164,24 +165,28 @@ function ChoroplethBlock({ }} minHeight={!isSmallScreen ? 350 : 400} formatTooltip={(context) => { - const currentComplianceValue = + const currentComplianceValueKey = `${currentId}_compliance` as keyof VrCollectionBehavior; - const currentSupportValue = + const currentSupportValueKey = `${currentId}_support` as keyof VrCollectionBehavior; // Return null when there is no data available to prevent breaking the application when using tab if (keysWithoutData.includes(currentId)) return null; + const complianceValue = + context.dataItem[currentComplianceValueKey]; + const supportValue = context.dataItem[currentSupportValueKey]; + return ( diff --git a/packages/app/src/domain/behavior/tooltip/vr-behavior-tooltip.tsx b/packages/app/src/domain/behavior/tooltip/vr-behavior-tooltip.tsx index 815e1bd6b5..5b1661963f 100644 --- a/packages/app/src/domain/behavior/tooltip/vr-behavior-tooltip.tsx +++ b/packages/app/src/domain/behavior/tooltip/vr-behavior-tooltip.tsx @@ -15,8 +15,8 @@ import { useReverseRouter } from '~/utils/use-reverse-router'; interface VrBehaviorTooltipProps { context: TooltipData; currentMetric: BehaviorIdentifier; - currentComplianceValue: number; - currentSupportValue: number; + currentComplianceValue: number | null; + currentSupportValue: number | null; behaviorType: 'compliance' | 'support'; text: SiteText['pages']['behaviorPage']; } @@ -29,25 +29,29 @@ export function VrBehaviorTooltip({ behaviorType, text, }: VrBehaviorTooltipProps) { - const { commonTexts } = useIntl(); + const { commonTexts, formatPercentage } = useIntl(); const reverseRouter = useReverseRouter(); const complianceThresholdKey = `${currentMetric}_compliance` as const; const supportThresholdKey = `${currentMetric}_support` as const; const complianceFilteredThreshold = getThresholdValue( thresholds.vr[complianceThresholdKey], - currentComplianceValue + currentComplianceValue ?? 0 ); const supportFilteredThreshold = getThresholdValue( thresholds.vr[supportThresholdKey], - currentSupportValue + currentSupportValue ?? 0 ); const complianceTooltipInfo = ( ); @@ -55,7 +59,11 @@ export function VrBehaviorTooltip({ const supportTooltipInfo = ( ); @@ -89,7 +97,7 @@ export function VrBehaviorTooltip({ interface TooltipInfoProps { title: string; - value: number; + value: string; background: string; } @@ -98,7 +106,7 @@ function TooltipInfo({ title, value, background }: TooltipInfoProps) { {title} - {`${value}%`} + {value} diff --git a/packages/app/src/domain/layout/logic/types.ts b/packages/app/src/domain/layout/logic/types.ts index 9fe177adf1..40013040df 100644 --- a/packages/app/src/domain/layout/logic/types.ts +++ b/packages/app/src/domain/layout/logic/types.ts @@ -27,6 +27,7 @@ export type VrItemKeys = | 'vaccinations'; export type VrCategoryKeys = + | 'archived_metrics' | 'behaviour' | 'early_indicators' | 'hospitals' diff --git a/packages/app/src/domain/layout/nl-layout.tsx b/packages/app/src/domain/layout/nl-layout.tsx index 07444766b2..53ed72e1f4 100644 --- a/packages/app/src/domain/layout/nl-layout.tsx +++ b/packages/app/src/domain/layout/nl-layout.tsx @@ -45,13 +45,7 @@ export function NlLayout(props: NlLayoutProps) { ['hospitals', ['hospital_admissions', 'intensive_care_admissions']], [ 'infections', - [ - 'positive_tests', - 'reproduction_number', - 'mortality', - 'variants', - 'source_investigation', - ], + ['positive_tests', 'reproduction_number', 'mortality', 'variants'], ], ['behaviour', ['compliance']], [ @@ -67,7 +61,12 @@ export function NlLayout(props: NlLayoutProps) { map: [ [ 'archived_metrics', - ['coronamelder_app', 'infectious_people', 'general_practitioner_suspicions'], + [ + 'source_investigation', + 'coronamelder_app', + 'infectious_people', + 'general_practitioner_suspicions', + ], ], ], }); diff --git a/packages/app/src/domain/layout/vr-layout.tsx b/packages/app/src/domain/layout/vr-layout.tsx index 20bd04bed0..74c9c69ec2 100644 --- a/packages/app/src/domain/layout/vr-layout.tsx +++ b/packages/app/src/domain/layout/vr-layout.tsx @@ -70,7 +70,7 @@ export function VrLayout(props: VrLayoutProps) { map: [ ['vaccinations', ['vaccinations']], ['hospitals', ['hospital_admissions']], - ['infections', ['positive_tests', 'mortality', 'source_investigation']], + ['infections', ['positive_tests', 'mortality']], ['behaviour', ['compliance']], [ 'vulnerable_groups', @@ -80,6 +80,12 @@ export function VrLayout(props: VrLayoutProps) { ], }); + const archivedItems = useSidebar({ + layout: 'vr', + code: code, + map: [['archived_metrics', ['source_investigation']]], + }); + return ( <> @@ -144,6 +150,17 @@ export function VrLayout(props: VrLayoutProps) { + + + + + + )} diff --git a/packages/app/src/domain/situations/components/situation-icon.tsx b/packages/app/src/domain/situations/components/situation-icon.tsx index a073a6b95a..ba8d431f4f 100644 --- a/packages/app/src/domain/situations/components/situation-icon.tsx +++ b/packages/app/src/domain/situations/components/situation-icon.tsx @@ -21,5 +21,5 @@ const icons = { export function SituationIcon({ id }: { id: SituationKey }) { const IconFromMap = icons[id]; - return ; + return ; } diff --git a/packages/app/src/domain/topical/components/search/context.tsx b/packages/app/src/domain/topical/components/search/context.tsx index 5d3ef7e9bd..5155600304 100644 --- a/packages/app/src/domain/topical/components/search/context.tsx +++ b/packages/app/src/domain/topical/components/search/context.tsx @@ -21,6 +21,7 @@ interface SearchContextProviderProps { containerRef: RefObject; children: (context: SearchContext) => ReactNode; initialValue?: string; + activeResult?: string; } const searchContext = createContext(undefined); @@ -29,8 +30,9 @@ export function SearchContextProvider({ children, containerRef, initialValue = '', + activeResult, }: SearchContextProviderProps) { - const value = useSearchContextValue(initialValue, containerRef); + const value = useSearchContextValue(initialValue, containerRef, activeResult); return ( @@ -49,7 +51,8 @@ export function useSearchContext() { function useSearchContextValue( initialValue: string, - containerRef: RefObject + containerRef: RefObject, + activeResult?: string ) { const router = useRouter(); const breakpoints = useBreakpoints(); @@ -90,7 +93,7 @@ function useSearchContextValue( /** * the useSearchResults-hook which will perform the actual search */ - const { hits, vrHits, gmHits } = useSearchResults(term); + const { hits, vrHits, gmHits } = useSearchResults(term, activeResult); const showResults = hasHadInputFocus && (hasInputFocus || hasHitFocus || !breakpoints.md); @@ -176,6 +179,8 @@ function useSearchContextValue( ref: option.index === focusIndex ? focusRef : undefined, href: option.data.link, hasFocus: focusIndex === option.index, + isActiveResult: option.isActiveResult, + onClick: () => setHasHadInputFocus(false), onHover: () => setFocusIndex(option.index), onFocus: () => { setFocusIndex(option.index); diff --git a/packages/app/src/domain/topical/components/search/hit-list.tsx b/packages/app/src/domain/topical/components/search/hit-list.tsx index 53cd9649f0..70832207af 100644 --- a/packages/app/src/domain/topical/components/search/hit-list.tsx +++ b/packages/app/src/domain/topical/components/search/hit-list.tsx @@ -50,7 +50,9 @@ export function HitList({ scope }: HitListProps) { ))} ) : ( - {noHitsMessage} + + {noHitsMessage} + )} ); @@ -60,13 +62,18 @@ interface HitLinkProps { href: string; children: ReactNode; hasFocus: boolean; + onClick: () => void; onHover: () => void; onFocus: () => void; id: string; + isActiveResult: boolean; } const HitLink = forwardRef( - ({ href, children, hasFocus, onHover, onFocus, id }, ref) => { + ( + { href, children, hasFocus, onClick, onHover, onFocus, id, isActiveResult }, + ref + ) => { return ( ( role="option" id={id} aria-selected={hasFocus ? 'true' : 'false'} + aria-active={isActiveResult ? 'true' : 'false'} + onClick={onClick} > {children} @@ -85,16 +94,42 @@ const HitLink = forwardRef( } ); -const StyledHitLink = styled(Anchor)<{ hasFocus: boolean }>((x) => +const StyledHitLink = styled(Anchor)<{ + hasFocus: boolean; +}>((x) => css({ - p: 2, + padding: '0.5em 1.75em', display: 'block', textDecoration: 'none', color: 'black', width: '100%', - bg: x.hasFocus ? 'contextualContent' : 'transparant', transitionProperty: 'background', transitionDuration: x.hasFocus ? '0ms' : '120ms', + position: 'relative', + '&:before': { + content: 'attr(data-text)', + position: 'absolute', + left: 0, + top: 0, + height: '100%', + width: '5px', + backgroundColor: 'blue', + transform: 'scaleX(0)', + transformOrigin: 'left', + transition: '0.2s transform', + }, + '&[aria-active="true"]': { + color: 'blue', + fontWeight: 'bold', + '&:before': { + transform: 'scaleX(1)', + }, + }, + '&:hover, &[aria-selected="true"]': { + bg: 'blue', + color: 'white', + fontWeight: 'normal', + }, }) ); @@ -104,7 +139,7 @@ const HitListHeader = styled.span( textTransform: 'uppercase', fontSize: 1, fontWeight: 'bold', - px: 2, + px: '2em', }) ); @@ -116,3 +151,9 @@ const StyledHitList = styled.ol( width: ['100%', null], }) ); + +const NoResultMessage = styled.div( + css({ + px: '1.75em', + }) +); diff --git a/packages/app/src/domain/topical/components/search/search-results.tsx b/packages/app/src/domain/topical/components/search/search-results.tsx index 8589699b95..2185681384 100644 --- a/packages/app/src/domain/topical/components/search/search-results.tsx +++ b/packages/app/src/domain/topical/components/search/search-results.tsx @@ -2,49 +2,34 @@ import css from '@styled-system/css'; import styled from 'styled-components'; import { asResponsiveArray } from '~/style/utils'; import { useHotkey } from '~/utils/hotkey/use-hotkey'; -import { useBreakpoints } from '~/utils/use-breakpoints'; import { useSearchContext } from './context'; import { HitList } from './hit-list'; -import { paddedStyle } from './search-input'; export function SearchResults() { - const { id, hits, setHasHitFocus } = useSearchContext(); - const breakpoints = useBreakpoints(); + const { id, setHasHitFocus } = useSearchContext(); useHotkey('esc', () => setHasHitFocus(false), { preventDefault: false }); - /** - * On narrow devices we'll render the category with the best result on top - */ - const vrHasBestResult = - [...hits].sort((a, b) => b.score - a.score)[0]?.data.type === 'vr'; - - const col1Scope = breakpoints.sm ? 'gm' : vrHasBestResult ? 'vr' : 'gm'; - const col2Scope = breakpoints.sm ? 'vr' : vrHasBestResult ? 'gm' : 'vr'; - return ( setHasHitFocus(true)} > - - + + ); } const StyledSearchResults = styled.div( - paddedStyle, css({ + p: '1em 0', position: 'relative', - /** negative margin necessary for text alignment */ - mx: -2, display: 'flex', flexDirection: asResponsiveArray({ _: 'column', sm: 'row' }), - '& > *:not(:last-child)': { - marginRight: asResponsiveArray({ sm: 4 }), - marginBottom: asResponsiveArray({ _: 4, sm: 0 }), + '& > :not(:last-child)': { + marginBottom: '2em', }, }) ); diff --git a/packages/app/src/domain/topical/components/search/search.tsx b/packages/app/src/domain/topical/components/search/search.tsx index fbfbb3389d..bc8b12d2c0 100644 --- a/packages/app/src/domain/topical/components/search/search.tsx +++ b/packages/app/src/domain/topical/components/search/search.tsx @@ -12,9 +12,11 @@ import { SearchResults } from './search-results'; export function Search({ initialValue, title, + activeResult, }: { initialValue?: string; title: string; + activeResult?: string; }) { const [heightRef, { height }] = useResizeObserver(); const containerRef = useRef(null); @@ -23,6 +25,7 @@ export function Search({ {(context) => ( @@ -48,7 +51,7 @@ export function Search({ width={{ _: '100%', xs: '20rem', - sm: context.showResults ? '42rem' : '26rem', + sm: '42rem', }} px={{ sm: 4 }} bg={colors.white} diff --git a/packages/app/src/domain/topical/components/search/use-search-results.ts b/packages/app/src/domain/topical/components/search/use-search-results.ts index dadd89fbba..2f3749a929 100644 --- a/packages/app/src/domain/topical/components/search/use-search-results.ts +++ b/packages/app/src/domain/topical/components/search/use-search-results.ts @@ -27,10 +27,11 @@ export interface Hit { * The `id` is unique for every hit. */ id: string; + isActiveResult: boolean; data: T; } -export function useSearchResults(term: string) { +export function useSearchResults(term: string, activeResult?: string) { const reverseRouter = useReverseRouter(); const termTrimmed = term.trim(); @@ -47,6 +48,7 @@ export function useSearchResults(term: string) { ...x.data, link, }, + isActiveResult: activeResult === x.id, }; }); @@ -54,7 +56,7 @@ export function useSearchResults(term: string) { const vrHits = hits.filter((x) => x.data.type === 'vr'); return { hits, gmHits, vrHits }; - }, [termTrimmed, reverseRouter]); + }, [termTrimmed, reverseRouter, activeResult]); return { hits, gmHits, vrHits }; } diff --git a/packages/app/src/domain/topical/mini-tile-selector-layout.tsx b/packages/app/src/domain/topical/mini-tile-selector-layout.tsx index 43e39cedb0..5f77248f7d 100644 --- a/packages/app/src/domain/topical/mini-tile-selector-layout.tsx +++ b/packages/app/src/domain/topical/mini-tile-selector-layout.tsx @@ -20,6 +20,7 @@ import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; import { space } from '~/style/theme'; import { asResponsiveArray } from '~/style/utils'; +import { useBreakpoints } from '~/utils/use-breakpoints'; import { useCollapsible } from '~/utils/use-collapsible'; import { Bar } from '../vaccine/components/bar'; @@ -48,19 +49,20 @@ type MiniTileSelectorLayoutProps = { export function MiniTileSelectorLayout(props: MiniTileSelectorLayoutProps) { const { text } = props; + const breakpoints = useBreakpoints(); return ( <> - + {breakpoints.md ? ( - - - - - {text.tile_selector_uitleg} - - - + ) : ( + + + {text.tile_selector_uitleg} + + + + )} ); } diff --git a/packages/app/src/domain/vaccine/vaccinations-shot-kpi-section.tsx b/packages/app/src/domain/vaccine/vaccinations-shot-kpi-section.tsx index 8ac8288d2b..48f0a60d6f 100644 --- a/packages/app/src/domain/vaccine/vaccinations-shot-kpi-section.tsx +++ b/packages/app/src/domain/vaccine/vaccinations-shot-kpi-section.tsx @@ -1,10 +1,13 @@ -import { KpiTile } from '~/components/kpi-tile'; -import { KpiValue } from '~/components/kpi-value'; -import { Markdown } from '~/components/markdown'; -import { TwoKpiSection } from '~/components/two-kpi-section'; import { useIntl } from '~/intl'; -import { Metadata } from '~/components/metadata'; -import { Message } from '~/components/message'; +import { + KpiTile, + KpiValue, + Markdown, + TwoKpiSection, + Metadata, + Message, +} from '~/components'; +import { Box } from '~/components/base'; type SourceType = { text: string; @@ -33,8 +36,8 @@ export function VaccinationsShotKpiSection({ const { formatNumber } = useIntl(); return ( - - + + {text.warning && {text.warning}} @@ -47,7 +50,7 @@ export function VaccinationsShotKpiSection({ }} /> - + ); } diff --git a/packages/app/src/domain/vaccine/vaccine-booster-administrations-kpi-section.tsx b/packages/app/src/domain/vaccine/vaccine-booster-administrations-kpi-section.tsx index d48177f215..aaebd19467 100644 --- a/packages/app/src/domain/vaccine/vaccine-booster-administrations-kpi-section.tsx +++ b/packages/app/src/domain/vaccine/vaccine-booster-administrations-kpi-section.tsx @@ -1,14 +1,15 @@ import { Box } from '~/components/base'; -import { KpiValue } from '~/components/kpi-value'; -import { TwoKpiSection } from '~/components/two-kpi-section'; -import { Tile } from '~/components/tile'; import { InlineText, Text, Heading, BoldText } from '~/components/typography'; -import { Message } from '~/components/message'; -import { useIntl } from '~/intl'; import { replaceComponentsInText } from '~/utils/replace-components-in-text'; -import { Metadata, MetadataProps } from '~/components/metadata'; -import { replaceVariablesInText } from '~/utils/replace-variables-in-text'; -import { Markdown } from '~/components/markdown'; +import { + Metadata, + MetadataProps, + Message, + Tile, + TwoKpiSection, + KpiValue, +} from '~/components'; +import { useIntl } from '~/intl'; import { SiteText } from '~/locale'; interface VaccineBoosterAdministrationsKpiSectionProps { @@ -18,8 +19,6 @@ interface VaccineBoosterAdministrationsKpiSectionProps { metadateBoosterGgd: MetadataProps; boosterEstimatedValue: number; metadateBoosterEstimated: MetadataProps; - boosterShotLastSevenDays: number; - metadataBoosterShotLastSevenDays: MetadataProps; text: SiteText['pages']['vaccinationsPage']['nl']['booster_kpi']; } @@ -30,12 +29,8 @@ export function VaccineBoosterAdministrationsKpiSection({ metadateBoosterGgd, boosterEstimatedValue, metadateBoosterEstimated, - boosterShotLastSevenDays, - metadataBoosterShotLastSevenDays, text, }: VaccineBoosterAdministrationsKpiSectionProps) { - const { formatNumber } = useIntl(); - return ( @@ -54,16 +49,6 @@ export function VaccineBoosterAdministrationsKpiSection({ )} - - - diff --git a/packages/app/src/pages/actueel/gemeente/[code].tsx b/packages/app/src/pages/actueel/gemeente/[code].tsx index 58750df500..7ad46f394d 100644 --- a/packages/app/src/pages/actueel/gemeente/[code].tsx +++ b/packages/app/src/pages/actueel/gemeente/[code].tsx @@ -462,7 +462,10 @@ const TopicalMunicipality = (props: StaticProps) => { - + ) => { - + ) => { legend={{ title: textShared.chloropleth_legenda.titel, thresholds: thresholds.gm.admissions_on_date_of_admission, + type: 'default', }} > ) => { data={choropleth.gm.hospital_nice_choropleth} dataConfig={{ metricName: 'hospital_nice_choropleth', - metricProperty: 'admissions_on_date_of_admission', + metricProperty: 'admissions_on_date_of_admission_per_100000', }} dataOptions={{ selectedCode: data.code, diff --git a/packages/app/src/pages/landelijk/brononderzoek.tsx b/packages/app/src/pages/landelijk/brononderzoek.tsx index 66645c3ae5..a46be035a3 100644 --- a/packages/app/src/pages/landelijk/brononderzoek.tsx +++ b/packages/app/src/pages/landelijk/brononderzoek.tsx @@ -1,11 +1,12 @@ import { Gedrag } from '@corona-dashboard/icons'; +import { isEmpty } from 'lodash'; import { GetStaticPropsContext } from 'next'; -import { PageInformationBlock } from '~/components/page-information-block'; -import { TileList } from '~/components/tile-list'; +import { PageInformationBlock, TileList, WarningTile } from '~/components'; import { Layout } from '~/domain/layout/layout'; import { NlLayout } from '~/domain/layout/nl-layout'; import { SituationsDataCoverageChoroplethTile } from '~/domain/situations/situations-data-coverage-choropleth-tile'; import { SituationsOverviewChoroplethTile } from '~/domain/situations/situations-overview-choropleth-tile'; +import { useIntl } from '~/intl'; import { Languages } from '~/locale'; import { getArticleParts, @@ -63,6 +64,7 @@ export default function BrononderzoekPage( const { pageText, choropleth, lastGenerated, content } = props; const { caterogyTexts, metadataTexts, textShared, textChoroplethTooltips } = pageText; + const { commonTexts } = useIntl(); const metadata = { ...metadataTexts, @@ -77,7 +79,7 @@ export default function BrononderzoekPage( } @@ -95,6 +97,15 @@ export default function BrononderzoekPage( articles={content.articles} /> + {textShared.belangrijk_bericht && + !isEmpty(textShared.belangrijk_bericht) && ( + + )} + ) => { }} seriesConfig={[ { - type: 'gapped-area', + type: 'line', metricProperty: 'beds_occupied_covid', label: textNl.chart_bedbezetting.legend_trend_label, color: colors.data.primary, }, + { + type: 'scatter-plot', + metricProperty: 'beds_occupied_covid', + label: textNl.chart_bedbezetting.legend_dot_label, + color: colors.data.primary, + }, ]} /> )} diff --git a/packages/app/src/pages/landelijk/maatregelen.tsx b/packages/app/src/pages/landelijk/maatregelen.tsx index d10a4ca284..15969a915b 100644 --- a/packages/app/src/pages/landelijk/maatregelen.tsx +++ b/packages/app/src/pages/landelijk/maatregelen.tsx @@ -69,9 +69,7 @@ const NationalRestrictions = (props: StaticProps) => { - - {textNl.titel} - + {textNl.titel} {lockdown.message.description ? ( diff --git a/packages/app/src/pages/landelijk/vaccinaties.tsx b/packages/app/src/pages/landelijk/vaccinaties.tsx index 79ce9b315a..0c482688e4 100644 --- a/packages/app/src/pages/landelijk/vaccinaties.tsx +++ b/packages/app/src/pages/landelijk/vaccinaties.tsx @@ -293,7 +293,7 @@ const VaccinationPage = (props: StaticProps) => { ) => { )} ) => { } metadateBoosterShots={{ datumsText: textNl.booster_kpi.datums, - date: boosterShotAdministeredLastValue.date_end_unix, + date: boosterShotAdministeredLastValue.date_unix, source: { href: textNl.booster_kpi.sources.href, text: textNl.booster_kpi.sources.text, @@ -395,7 +395,7 @@ const VaccinationPage = (props: StaticProps) => { } metadateBoosterGgd={{ datumsText: textNl.booster_kpi.datums, - date: boosterShotAdministeredLastValue.date_end_unix, + date: boosterShotAdministeredLastValue.date_unix, source: { href: textNl.booster_kpi.sources.href, text: textNl.booster_kpi.sources.text, @@ -406,26 +406,12 @@ const VaccinationPage = (props: StaticProps) => { } metadateBoosterEstimated={{ datumsText: textNl.booster_kpi.datums, - date: boosterShotAdministeredLastValue.date_end_unix, + date: boosterShotAdministeredLastValue.date_unix, source: { href: textNl.booster_kpi.sources.href, text: textNl.booster_kpi.sources.text, }, }} - boosterShotLastSevenDays={ - boosterShotAdministeredLastValue.ggd_administered_last_7_days - } - metadataBoosterShotLastSevenDays={{ - datumsText: textNl.booster_ggd_kpi_section.datums, - date: [ - boosterShotAdministeredLastValue.date_start_unix, - boosterShotAdministeredLastValue.date_end_unix, - ], - source: { - href: textNl.booster_ggd_kpi_section.sources.href, - text: textNl.booster_ggd_kpi_section.sources.text, - }, - }} /> ) => { timeframe={timeframe} seriesConfig={[ { - type: 'gapped-area', + type: 'line', metricProperty: 'beds_occupied_covid', label: textNl.chart_bedbezetting.legend_trend_label, color: colors.data.primary, }, + { + type: 'scatter-plot', + metricProperty: 'beds_occupied_covid', + label: textNl.chart_bedbezetting.legend_dot_label, + color: colors.data.primary, + }, ]} dataOptions={{ timespanAnnotations: [ diff --git a/packages/app/src/pages/veiligheidsregio/[code]/brononderzoek.tsx b/packages/app/src/pages/veiligheidsregio/[code]/brononderzoek.tsx index 0162c2588e..ee0e99e112 100644 --- a/packages/app/src/pages/veiligheidsregio/[code]/brononderzoek.tsx +++ b/packages/app/src/pages/veiligheidsregio/[code]/brononderzoek.tsx @@ -1,13 +1,17 @@ import { TimeframeOption } from '@corona-dashboard/common'; import { Gedrag } from '@corona-dashboard/icons'; +import { isEmpty } from 'lodash'; import { GetStaticPropsContext } from 'next'; -import { ChartTile } from '~/components/chart-tile'; -import { KpiTile } from '~/components/kpi-tile'; -import { KpiValue } from '~/components/kpi-value'; -import { Markdown } from '~/components/markdown'; -import { PageInformationBlock } from '~/components/page-information-block'; -import { TileList } from '~/components/tile-list'; -import { TwoKpiSection } from '~/components/two-kpi-section'; +import { + ChartTile, + WarningTile, + KpiTile, + KpiValue, + Markdown, + PageInformationBlock, + TileList, + TwoKpiSection, +} from '~/components'; import { InlineText, BoldText } from '~/components/typography'; import { Layout } from '~/domain/layout/layout'; import { VrLayout } from '~/domain/layout/vr-layout'; @@ -110,7 +114,7 @@ export default function BrononderzoekPage( + {textShared.belangrijk_bericht && + !isEmpty(textShared.belangrijk_bericht) && ( + + )} + ) => { - + {replaceVariablesInText(textVr.titel, { safetyRegionName: vrName, })} diff --git a/packages/app/src/pages/veiligheidsregio/[code]/ziekenhuis-opnames.tsx b/packages/app/src/pages/veiligheidsregio/[code]/ziekenhuis-opnames.tsx index 159edab8d9..7631d64b49 100644 --- a/packages/app/src/pages/veiligheidsregio/[code]/ziekenhuis-opnames.tsx +++ b/packages/app/src/pages/veiligheidsregio/[code]/ziekenhuis-opnames.tsx @@ -249,6 +249,7 @@ const IntakeHospital = (props: StaticProps) => { legend={{ thresholds: thresholds.gm.admissions_on_date_of_admission, title: textShared.chloropleth_legenda.titel, + type: 'default', }} metadata={{ date: lastValueChoropleth.date_unix, @@ -263,7 +264,7 @@ const IntakeHospital = (props: StaticProps) => { data={choropleth.gm.hospital_nice_choropleth} dataConfig={{ metricName: 'hospital_nice_choropleth', - metricProperty: 'admissions_on_date_of_admission', + metricProperty: 'admissions_on_date_of_admission_per_100000', }} dataOptions={{ selectedCode: selectedMunicipalCode, diff --git a/packages/app/src/static-props/get-data.ts b/packages/app/src/static-props/get-data.ts index 15a170a005..433096e9ae 100644 --- a/packages/app/src/static-props/get-data.ts +++ b/packages/app/src/static-props/get-data.ts @@ -3,8 +3,6 @@ import { Gm, GmCollection, gmData, - In, - InCollection, Nl, sortTimeSeriesInDataInPlace, Vr, @@ -18,7 +16,6 @@ import { GetStaticPropsContext } from 'next'; import { isDefined } from 'ts-is-present'; import type { F, O, S, U } from 'ts-toolbelt'; import { AsyncWalkBuilder } from 'walkjs'; -import { CountryCode } from '~/domain/international/multi-select-countries'; import { getClient, localize } from '~/lib/sanity'; import { Languages, SiteText } from '~/locale'; import { @@ -73,10 +70,6 @@ const json = { loadJsonFromDataFile('GM_COLLECTION.json'), 'gm_collection' ), - inCollection: initializeFeatureFlaggedData( - loadJsonFromDataFile('IN_COLLECTION.json', undefined, true), - 'in_collection' - ), }; export function getLastGeneratedDate() { @@ -308,45 +301,23 @@ function getGmData(context: GetStaticPropsContext) { const NOOP = () => null; -export function createGetChoroplethData(settings?: { +export function createGetChoroplethData(settings?: { vr?: (collection: VrCollection, context: GetStaticPropsContext) => T1; gm?: (collection: GmCollection, context: GetStaticPropsContext) => T2; - in?: (collection: InCollection, context: GetStaticPropsContext) => T3; }) { return (context: GetStaticPropsContext) => { const filterVr = settings?.vr ?? NOOP; const filterGm = settings?.gm ?? NOOP; - const filterIn = settings?.in ?? NOOP; return { choropleth: { vr: filterVr(json.vrCollection, context) as T1, gm: filterGm(json.gmCollection, context) as T2, - in: filterIn(json.inCollection, context) as T3, }, }; }; } -export function getInData(countryCodes: CountryCode[]) { - return function () { - const internationalData: Record = {}; - countryCodes.forEach((countryCode) => { - const data = initializeFeatureFlaggedData( - loadJsonFromDataFile(`IN_${countryCode.toUpperCase()}.json`), - 'in' - ); - - sortTimeSeriesInDataInPlace(data); - - internationalData[countryCode] = data; - }); - return { internationalData } as { - internationalData: Record; - }; - }; -} - /** * This function makes sure that for metrics with inaccurate data for the last x * items, the last_value is replaced with the last accurate value. For now only diff --git a/packages/app/src/utils/__tests__/current-date-context.spec.tsx b/packages/app/src/utils/__tests__/current-date-context.spec.tsx index bd1faafa25..3c420a5a5c 100644 --- a/packages/app/src/utils/__tests__/current-date-context.spec.tsx +++ b/packages/app/src/utils/__tests__/current-date-context.spec.tsx @@ -2,7 +2,7 @@ import { cleanup, renderHook } from '@testing-library/react-hooks/server'; import { suite } from 'uvu'; import * as assert from 'uvu/assert'; import { CurrentDateProvider, useCurrentDate } from '../current-date-context'; -import { middleOfDayInSeconds } from '@corona-dashboard/common'; +import { endOfDayInSeconds } from '@corona-dashboard/common'; import injectJsDom from 'jsdom-global'; const UseCurrentDate = suite('useCurrentDate'); @@ -20,7 +20,7 @@ UseCurrentDate.after((context) => { }); UseCurrentDate('should return the passed date initially', () => { - const yesterday = middleOfDayInSeconds( + const yesterday = endOfDayInSeconds( new Date().setDate(new Date().getDate() - 1) / 1000 ); @@ -37,11 +37,11 @@ UseCurrentDate('should return the passed date initially', () => { }); UseCurrentDate('should return the current date after hydration', () => { - const yesterday = middleOfDayInSeconds( + const yesterday = endOfDayInSeconds( new Date().setDate(new Date().getDate() - 1) / 1000 ); - const now = middleOfDayInSeconds(Date.now() / 1000); + const now = endOfDayInSeconds(Date.now() / 1000); const { result, hydrate } = renderHook(() => useCurrentDate(), { wrapper: ({ children }) => ( diff --git a/packages/app/src/utils/__tests__/use-accessibility-features.spec.tsx b/packages/app/src/utils/__tests__/use-accessibility-features.spec.tsx index 33e38b9090..9837383d11 100644 --- a/packages/app/src/utils/__tests__/use-accessibility-features.spec.tsx +++ b/packages/app/src/utils/__tests__/use-accessibility-features.spec.tsx @@ -11,15 +11,27 @@ import { AccessibilityDefinition, useAccessibilityAnnotations, } from '../use-accessibility-annotations'; +import { useUniqueId } from '../use-unique-id'; const UseAccessibilityAnnotations = suite('useAccessibilityAnnotations'); +const originalUseUniqueId = useUniqueId.bind({}); // clones the hook + UseAccessibilityAnnotations.before((context) => { context.cleanupJsDom = injectJsDom(); + + // @TODO: Mocking a React Hook is not possible without installing another npm package. We might consider cleaning this up later + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/no-unused-vars + useUniqueId = () => 'uniqueId'; }); UseAccessibilityAnnotations.after((context) => { context.cleanupJsDom(); + + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/no-unused-vars + useUniqueId = originalUseUniqueId; }); UseAccessibilityAnnotations.after.each(() => { @@ -41,12 +53,12 @@ UseAccessibilityAnnotations( assert.equal(result.current.descriptionElement.type.name, 'VisuallyHidden'); assert.equal(result.current.descriptionElement.props, { - id: 'testKey_id', + id: 'testKey_uniqueId', children: 'test description', }); assert.equal(result.current.props, { 'aria-label': 'test label', - 'aria-describedby': 'testKey_id', + 'aria-describedby': 'testKey_uniqueId', }); } ); @@ -70,7 +82,7 @@ UseAccessibilityAnnotations( ); assert.equal(result.current.descriptionElement.props, { - id: 'testKey_id', + id: 'testKey_uniqueId', children: 'test description test keyboard series feature test keyboard bar feature test keyboard choropleth feature', }); diff --git a/packages/app/src/utils/current-date-context.tsx b/packages/app/src/utils/current-date-context.tsx index 2983e7aa69..2842ee8c85 100644 --- a/packages/app/src/utils/current-date-context.tsx +++ b/packages/app/src/utils/current-date-context.tsx @@ -1,4 +1,4 @@ -import { assert, middleOfDayInSeconds } from '@corona-dashboard/common'; +import { assert, endOfDayInSeconds } from '@corona-dashboard/common'; import { createContext, ReactNode, @@ -32,10 +32,10 @@ export function CurrentDateProvider({ children: ReactNode; }) { const [date, setDate] = useState( - new Date(middleOfDayInSeconds(dateInSeconds) * 1000) + new Date(endOfDayInSeconds(dateInSeconds) * 1000) ); useEffect( - () => setDate(new Date(middleOfDayInSeconds(Date.now() / 1000) * 1000)), + () => setDate(new Date(endOfDayInSeconds(Date.now() / 1000) * 1000)), [] ); diff --git a/packages/app/src/utils/use-accessibility-annotations.tsx b/packages/app/src/utils/use-accessibility-annotations.tsx index 8cc9624434..82862b7ffd 100644 --- a/packages/app/src/utils/use-accessibility-annotations.tsx +++ b/packages/app/src/utils/use-accessibility-annotations.tsx @@ -3,6 +3,7 @@ import { isDefined, isPresent } from 'ts-is-present'; import { VisuallyHidden } from '~/components/visually-hidden'; import { useIntl } from '~/intl'; import type { SiteText } from '~/locale'; +import { useUniqueId } from './use-unique-id'; export interface AccessibilityDefinition { key: keyof SiteText['common']['accessibility']['charts']; @@ -32,6 +33,7 @@ export function useAccessibilityAnnotations( definition: AccessibilityDefinition ) { const { commonTexts } = useIntl(); + const uniqueId = useUniqueId(); const { label, description: chartDescription } = commonTexts.accessibility.charts[ @@ -68,7 +70,7 @@ export function useAccessibilityAnnotations( ); } - const describedById = `${definition.key}_id`; + const describedById = `${definition.key}_${uniqueId}`; return { descriptionElement: ( diff --git a/packages/cms/package.json b/packages/cms/package.json index 9a6d9a1f41..f5d2a74daa 100644 --- a/packages/cms/package.json +++ b/packages/cms/package.json @@ -28,7 +28,7 @@ "dependencies": { "@corona-dashboard/icons": "0.0.0", "@sanity/base": "^2.29.3", - "@sanity/cli": "^2.29.3", + "@sanity/cli": "^2.30.0", "@sanity/components": "^2.14.0", "@sanity/core": "^2.29.3", "@sanity/dashboard": "^2.29.3", @@ -63,7 +63,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@sanity/cli": "^2.29.3", + "@sanity/cli": "^2.30.0", "@types/download": "^8.0.1", "@types/flat": "^5.0.2", "@types/fs-extra": "^9.0.13", diff --git a/packages/cms/src/lokalize/key-mutations.csv b/packages/cms/src/lokalize/key-mutations.csv index 40ea4a7677..d920e89a0e 100755 --- a/packages/cms/src/lokalize/key-mutations.csv +++ b/packages/cms/src/lokalize/key-mutations.csv @@ -31,3 +31,7 @@ timestamp,action,key,document_id,move_to 2022-05-09T09:27:24.544Z,move,choropleth_tooltip.gm.booster_shot_percentage.subject,VNAGnZtzuWCFY8gXn2zsT8,common.choropleth_tooltip.gm.booster_shot_percentage.subject 2022-05-09T08:58:28.088Z,move,accessibility.charts.hospital_admissions_region_choropleth.description,G1DXw0RdifOml06twMjbPq,common.accessibility.charts.hospital_admissions_region_choropleth.description 2022-05-12T07:55:42.658Z,delete,common.charts.time_controls.firstOfSeptember,A5Y41hFe5J3wNnB7O7FFlP,__ +2022-05-17T11:30:05.964Z,delete,pages.vaccinationsPage.nl.booster_kpi.booster_shot_last_seven_days.description,W42pYebYgNKSplnOwA9UMB,__ +2022-05-23T10:24:35.671Z,add,pages.situationsPage.shared.belangrijk_bericht,RQYRq9yqc5kuEd5capEHG3,__ +2022-05-25T12:52:50.949Z,add,pages.hospitalPage.nl.chart_bedbezetting.legend_dot_label,hErpiCVzoc9qP245irsdCS,__ +2022-05-25T13:25:56.013Z,add,pages.intensiveCarePage.nl.chart_bedbezetting.legend_dot_label,l9y47X7Mn753quuWoDXzrN,__ diff --git a/packages/cms/src/schemas/documents/lokalize-text.ts b/packages/cms/src/schemas/documents/lokalize-text.ts index cf7ed3f932..9eb56ec466 100644 --- a/packages/cms/src/schemas/documents/lokalize-text.ts +++ b/packages/cms/src/schemas/documents/lokalize-text.ts @@ -80,9 +80,16 @@ export const lokalizeText = { * list, but the path field is cleaner when browsing texts because it * avoids a lot of string duplication. */ - title: 'key', + key: 'key', subtitle: 'text.nl', }, + prepare({ key, subtitle}: { key: string, subtitle: string}) { + const title = key.split('.').slice(3).join('.'); + return { + title, + subtitle + } + }, }, }; diff --git a/packages/common/src/data/gm.ts b/packages/common/src/data/gm.ts index e0d4f21501..59fb549ec8 100644 --- a/packages/common/src/data/gm.ts +++ b/packages/common/src/data/gm.ts @@ -532,7 +532,7 @@ export const gmData: MunicipalityInfo[] = [ name: "'s-Gravenhage", vrCode: 'VR15', gemcode: 'GM0518', - displayName: "'s-Gravenhage", + displayName: 'Den Haag', searchTerms: ['Den Haag'], }, { @@ -659,7 +659,7 @@ export const gmData: MunicipalityInfo[] = [ name: "'s-Hertogenbosch", vrCode: 'VR21', gemcode: 'GM0796', - displayName: "'s-Hertogenbosch", + displayName: 'Den Bosch', searchTerms: ['Den Bosch'], }, { diff --git a/packages/common/src/types/data.ts b/packages/common/src/types/data.ts index 5b0a34bfdc..7775d801b3 100644 --- a/packages/common/src/types/data.ts +++ b/packages/common/src/types/data.ts @@ -356,11 +356,9 @@ export interface NlBoosterShotAdministered { } export interface NlBoosterShotAdministeredValue { administered_total: number; - ggd_administered_last_7_days: number; ggd_administered_total: number; others_administered_total: number; - date_start_unix: number; - date_end_unix: number; + date_unix: number; date_of_insertion_unix: number; } export interface NlRepeatingShotAdministered { diff --git a/packages/common/src/utils/timeframe/index.ts b/packages/common/src/utils/timeframe/index.ts index 45f39c0dbe..317342f58d 100644 --- a/packages/common/src/utils/timeframe/index.ts +++ b/packages/common/src/utils/timeframe/index.ts @@ -3,6 +3,7 @@ import { DateValue, isDateSeries, isDateSpanSeries, + startOfDayInSeconds, TimestampedValue, } from '../../data-sorting'; import { DAY_IN_SECONDS } from '../../time'; @@ -101,22 +102,29 @@ export function getValuesInTimeframe( const end = Math.ceil(endDate.getTime() / 1000); if (isDateSeries(values)) { - return values.filter((x: DateValue) => x.date_unix >= start && x.date_unix <= end) as T[]; + return values.filter((x: DateValue) => { + const correctedDateUnix = startOfDayInSeconds(x.date_unix); + return correctedDateUnix >= start && correctedDateUnix <= end; + }) as T[]; } if (isDateSpanSeries(values)) { - return values.filter( - (x: DateSpanValue) => x.date_end_unix >= start && x.date_end_unix <= end - ) as T[]; + return values.filter((x: DateSpanValue) => { + const correctedDateUnix = startOfDayInSeconds(x.date_end_unix); + return correctedDateUnix >= start && correctedDateUnix <= end; + }) as T[]; } throw new Error(`Incompatible timestamps are used in value ${values[0]}`); } -function getTimeframeBoundaryUnix(timeframe: TimeframeOption, endDate: Date): number { +function getTimeframeBoundaryUnix( + timeframe: TimeframeOption, + endDate: Date +): number { if (timeframe === TimeframeOption.ALL) { return 0; } const days = getDaysForTimeframe(timeframe); - return Math.floor(endDate.getTime() / 1000) - days * DAY_IN_SECONDS; + return startOfDayInSeconds(endDate.getTime() / 1000) - days * DAY_IN_SECONDS; } diff --git a/packages/icons/src/svg/afstand-sporten.svg b/packages/icons/src/svg/afstand-sporten.svg index 93d1367a2e..5aedbdc0b6 100644 --- a/packages/icons/src/svg/afstand-sporten.svg +++ b/packages/icons/src/svg/afstand-sporten.svg @@ -1,4 +1,4 @@ - + diff --git a/packages/icons/src/svg/afstand.svg b/packages/icons/src/svg/afstand.svg index a9ec8d8386..1220fc752a 100644 --- a/packages/icons/src/svg/afstand.svg +++ b/packages/icons/src/svg/afstand.svg @@ -1,4 +1,4 @@ -