diff --git a/app/pathogen/arbovirus/dashboard/(map)/ArbovirusMap.tsx b/app/pathogen/arbovirus/dashboard/(map)/ArbovirusMap.tsx index 286be3f0..7c634101 100644 --- a/app/pathogen/arbovirus/dashboard/(map)/ArbovirusMap.tsx +++ b/app/pathogen/arbovirus/dashboard/(map)/ArbovirusMap.tsx @@ -25,7 +25,6 @@ import { CountryPaintChangeSetting, useArbovirusMapCustomizationModal } from "./ import { ArbovirusEnvironmentalSuitabilityCountryDataContext } from "@/contexts/pathogen-context/pathogen-contexts/arbovirus/arbo-environmental-suitability-country-data-context"; import { CountryDataContext } from "@/contexts/pathogen-context/country-information-context"; import { ArbovirusOropoucheCasesDataContext } from "@/contexts/pathogen-context/pathogen-contexts/arbovirus/arbo-oropouche-cases-data-context"; -import { Layer, Source } from "react-map-gl"; import { mapColourBucketsToLinearGradientConfiguration } from "@/components/ui/pathogen-map/country-highlight-layers/map-colour-buckets-to-linear-gradient-configuration"; import { useGroupedArbovirusEstimateData } from "../../use-arbo-primary-estimate-data"; import { MapSectionComponentProps } from "@/app/pathogen/generic-pathogen-dashboard-page"; diff --git a/app/pathogen/arbovirus/dashboard/(table)/ArboDataTable.tsx b/app/pathogen/arbovirus/dashboard/(table)/ArboDataTable.tsx index 250130c3..5fb74ba6 100644 --- a/app/pathogen/arbovirus/dashboard/(table)/ArboDataTable.tsx +++ b/app/pathogen/arbovirus/dashboard/(table)/ArboDataTable.tsx @@ -9,7 +9,7 @@ import { DataTableColumnConfigurationEntryType } from "@/components/ui/data-tabl import { ToastId } from "@/contexts/toast-provider"; import { RechartsVisualization } from "@/components/customs/visualizations/recharts-visualization"; import { ArbovirusVisualizationId, getUrlParameterFromVisualizationId, useVisualizationPageConfiguration } from "../../visualizations/visualization-page-config"; -import { useMap } from "react-map-gl"; +import { useMap } from "react-map-gl/mapbox"; import { ArboTrackerCitationButtonContent, shortenedArboTrackerCitationText, suggestedArboTrackerCitationText } from "../../arbotracker-citations"; import { ArbovirusEstimateType, ArbovirusStudyGeographicScope } from "@/gql/graphql"; import { assertNever } from "assert-never"; diff --git a/app/pathogen/generic-pathogen-dashboard-page.tsx b/app/pathogen/generic-pathogen-dashboard-page.tsx index 97d04e2d..96bfdf7a 100644 --- a/app/pathogen/generic-pathogen-dashboard-page.tsx +++ b/app/pathogen/generic-pathogen-dashboard-page.tsx @@ -5,7 +5,7 @@ import { cn } from "@/lib/utils"; import { useIsLargeScreen } from "@/hooks/useIsLargeScreen"; import { FiltersButton } from "./filters-button"; import { DashboardSectionId, DashboardType, dashboardTypeToMapIdMap } from "./dashboard-enums"; -import { useMap } from "react-map-gl"; +import { useMap } from "react-map-gl/mapbox"; interface FiltersComponentProps { className?: string; diff --git a/app/pathogen/mers/dashboard/(map)/animal-mers-seroprevalence-estimate-pop-up-content.tsx b/app/pathogen/mers/dashboard/(map)/animal-mers-seroprevalence-estimate-pop-up-content.tsx index d922f44b..f4e19771 100644 --- a/app/pathogen/mers/dashboard/(map)/animal-mers-seroprevalence-estimate-pop-up-content.tsx +++ b/app/pathogen/mers/dashboard/(map)/animal-mers-seroprevalence-estimate-pop-up-content.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useMemo } from 'react'; +import { MouseEventHandler, useContext, useMemo } from 'react'; import { GenericMapPopUp, GenericMapPopUpWidth, HeaderConfigurationTextAlignment } from "@/components/ui/pathogen-map/map-pop-up/generic-map-pop-up"; import { AnimalMersSeroprevalenceEstimateMapMarkerData, @@ -9,6 +9,7 @@ import { generateMersEstimateTableConfigurations, useMersEstimateRows } from "./shared-mers-map-pop-up-variables"; +import { MersFilterMetadataContext } from '@/contexts/pathogen-context/pathogen-contexts/mers/mers-filter-metadata-context'; interface AnimalMersSeroprevalenceEstimatePopupContentProps { estimate: AnimalMersSeroprevalenceEstimateMapMarkerData; @@ -28,6 +29,8 @@ export const AnimalMersSeroprevalenceEstimatePopupContent = (props: AnimalMersSe return `${seroprevalencePercentageText}` }, [ estimate ]); + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); + const tableConfigurations = useMemo(() => generateMersEstimateTableConfigurations({ type: GenerateMersEstimateTableConfigurationsType.SEROPREVALENCE_ESTIMATES, estimate @@ -37,7 +40,9 @@ export const AnimalMersSeroprevalenceEstimatePopupContent = (props: AnimalMersSe { const { estimate } = props; - + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); const { getSharedMersEstimateRows } = useMersEstimateRows(); const topBannerText = useMemo(() => { @@ -37,7 +38,9 @@ export const AnimalMersViralEstimatePopupContent = (props: AnimalMersViralEstima element.country.alphaThreeCode === alpha3CountryCode) ?.positiveCasesReported ?? 0 - }, [ mersWhoCaseData, alpha3CountryCode ]) + }, [ mersWhoCaseData, alpha3CountryCode ]); + + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); return ( & Re "HumanMersEvent": 5, "AnimalMersEvent": 6 }; -export const mersDataTypeToLabelMap = { - "PrimaryHumanMersSeroprevalenceEstimateInformation": "Human Seroprevalence Estimate", - "PrimaryAnimalMersSeroprevalenceEstimateInformation": "Animal Seroprevalence Estimate", - "PrimaryHumanMersViralEstimateInformation": "Human Viral Estimate", - "PrimaryAnimalMersViralEstimateInformation": "Animal Viral Estimate", - "AnimalMersEvent": "Animal Case", - "HumanMersEvent": "Human Case", + +export const useMersDataTypeToLabelMap = () => { + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); + + const mersDataTypeToLabelMap = { + "PrimaryHumanMersSeroprevalenceEstimateInformation": "Human Seroprevalence Estimate", + "PrimaryAnimalMersSeroprevalenceEstimateInformation": areNonCamelAnimalsIncluded + ? "Animal Seroprevalence Estimate" + : "Camel Seroprevalence Estimate", + "PrimaryHumanMersViralEstimateInformation": "Human Viral Estimate", + "PrimaryAnimalMersViralEstimateInformation": areNonCamelAnimalsIncluded + ? "Animal Viral Estimate" + : "Camel Viral Estimate", + "AnimalMersEvent": areNonCamelAnimalsIncluded + ? "Animal Case" + : "Camel Case", + "HumanMersEvent": "Human Case", + }; + + return { + mersDataTypeToLabelMap + }; }; export const mersMapPointVisibilitySettingToHiddenOptionsMap = { @@ -429,9 +445,19 @@ export const mersDataTypeToSuperOptionMap = { "AnimalMersEvent": MersDataTypeSuperOption.ANIMAL } -export const mersDataTypeSuperOptionToLabelMap = { - [MersDataTypeSuperOption.HUMAN]: "Human Data", - [MersDataTypeSuperOption.ANIMAL]: "Animal Data" +export const useMersDataTypeSuperOptionToLabelMap = () => { + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); + + const mersDataTypeSuperOptionToLabelMap = { + [MersDataTypeSuperOption.HUMAN]: "Human Data", + [MersDataTypeSuperOption.ANIMAL]: areNonCamelAnimalsIncluded + ? "Animal Data" + : "Camel Data", + } + + return { + mersDataTypeSuperOptionToLabelMap + } } export const mersDataTypeToColourClassnameMap = { diff --git a/app/pathogen/mers/dashboard/(map)/use-mers-map-data-type-legend-entries.tsx b/app/pathogen/mers/dashboard/(map)/use-mers-map-data-type-legend-entries.tsx index c66af736..07c12854 100644 --- a/app/pathogen/mers/dashboard/(map)/use-mers-map-data-type-legend-entries.tsx +++ b/app/pathogen/mers/dashboard/(map)/use-mers-map-data-type-legend-entries.tsx @@ -10,6 +10,7 @@ import { } from "@/contexts/pathogen-context/pathogen-contexts/mers/mers-context"; import { MapDataPointVisibilityOptions } from "./use-mers-map-customization-modal"; import { MapPinColours } from "./mers-map"; +import { MersFilterMetadataContext } from "@/contexts/pathogen-context/pathogen-contexts/mers/mers-filter-metadata-context"; const CamelIcon = () => ( isMersEventTypename(typename) ? mersDataTypeToLabelMap[typename] : typename, - valueToColourSchemeClassnameMap: mersDataTypeToColourClassnameMap, - defaultColourSchemeClassname: "bg-sky-100", - label: 'Event Type' -}, { - type: DataTableColumnConfigurationEntryType.COLOURED_PILL as const, - fieldName: 'whoRegion', - label: 'WHO Region', - valueToColourSchemeClassnameMap: { - [WhoRegion.Afr]: "bg-who-region-afr", - [WhoRegion.Amr]: "bg-who-region-amr", - [WhoRegion.Emr]: "bg-who-region-emr", - [WhoRegion.Eur]: "bg-who-region-eur", - [WhoRegion.Sear]: "bg-who-region-sear", - [WhoRegion.Wpr]: "bg-who-region-wpr text-white" - }, - defaultColourSchemeClassname: 'bg-sky-100' -}, { - type: DataTableColumnConfigurationEntryType.STANDARD as const, - fieldName: 'city', - label: 'City' -}, { - type: DataTableColumnConfigurationEntryType.STANDARD as const, - fieldName: 'state', - label: 'State' -}, { - type: DataTableColumnConfigurationEntryType.STANDARD as const, - fieldName: 'country', - label: 'Country or Area' -}, { - type: DataTableColumnConfigurationEntryType.STANDARD as const, - fieldName: 'latitude', - label: 'Latitude' -}, { - type: DataTableColumnConfigurationEntryType.STANDARD as const, - fieldName: 'longitude', - label: 'Longitude' -}, { - type: DataTableColumnConfigurationEntryType.COLOURED_PILL as const, - fieldName: 'diagnosisStatus', - valueToDisplayLabel: (diagnosisStatus: string) => isMersDiagnosisStatus(diagnosisStatus) ? diagnosisStatusToStringMap[diagnosisStatus] : diagnosisStatus, - valueToColourSchemeClassnameMap: diagnosisStatusToColourClassnameMap, - defaultColourSchemeClassname: "bg-sky-100", - label: 'Diagnosis Status' -}, { - type: DataTableColumnConfigurationEntryType.COLOURED_PILL as const, - fieldName: 'diagnosisSource', - valueToDisplayLabel: (diagnosisSource: string) => isMersDiagnosisSource(diagnosisSource) ? diagnosisSourceToStringMap[diagnosisSource] : diagnosisSource, - valueToColourSchemeClassnameMap: diagnosisSourceToColourClassnameMap, - defaultColourSchemeClassname: "bg-sky-100", - label: 'Diagnosis Source' -}, { - type: DataTableColumnConfigurationEntryType.DATE as const, - fieldName: 'observationDate', - label: 'Observation Date' -}, { - type: DataTableColumnConfigurationEntryType.COLOURED_PILL as const, - fieldName: 'animalType', - valueToDisplayLabel: (animalType: string) => isMersEventAnimalType(animalType) ? animalTypeToStringMap[animalType] : animalType, - valueToColourSchemeClassnameMap: animalTypeToColourClassnameMap, - defaultColourSchemeClassname: "bg-sky-100", - label: 'Animal Type' -}, { - type: DataTableColumnConfigurationEntryType.COLOURED_PILL_LIST as const, - fieldName: 'animalSpecies', - valueToDisplayLabel: (animalSpecies: string) => isMersAnimalSpecies(animalSpecies) ? animalSpeciesToStringMap[animalSpecies] : animalSpecies, - valueToColourSchemeClassnameMap: animalSpeciesToColourClassnameMap, - defaultColourSchemeClassname: "bg-sky-100", - label: 'Animal Species' -}, { - type: DataTableColumnConfigurationEntryType.STANDARD as const, - fieldName: 'humansAffected', - label: 'Humans Affected' -}, { - type: DataTableColumnConfigurationEntryType.STANDARD as const, - fieldName: 'humanDeaths', - label: 'Humans Deaths' -}, { - type: DataTableColumnConfigurationEntryType.STANDARD as const, - fieldName: 'id', - label: 'ID', - isHideable: false, - initiallyVisible: false -}]; +const useMersCasesColumnConfiguration = () => { + const { mersDataTypeToLabelMap } = useMersDataTypeToLabelMap(); + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); + + const mersCasesColumnConfiguration = [{ + type: DataTableColumnConfigurationEntryType.DATE as const, + fieldName: 'reportDate', + label: 'Report Date', + isFixed: true, + isHideable: false, + size: 200 + }, { + type: DataTableColumnConfigurationEntryType.COLOURED_PILL as const, + fieldName: '__typename', + valueToDisplayLabel: (typename: string) => isMersEventTypename(typename) ? mersDataTypeToLabelMap[typename] : typename, + valueToColourSchemeClassnameMap: mersDataTypeToColourClassnameMap, + defaultColourSchemeClassname: "bg-sky-100", + label: 'Event Type' + }, { + type: DataTableColumnConfigurationEntryType.COLOURED_PILL as const, + fieldName: 'whoRegion', + label: 'WHO Region', + valueToColourSchemeClassnameMap: { + [WhoRegion.Afr]: "bg-who-region-afr", + [WhoRegion.Amr]: "bg-who-region-amr", + [WhoRegion.Emr]: "bg-who-region-emr", + [WhoRegion.Eur]: "bg-who-region-eur", + [WhoRegion.Sear]: "bg-who-region-sear", + [WhoRegion.Wpr]: "bg-who-region-wpr text-white" + }, + defaultColourSchemeClassname: 'bg-sky-100' + }, { + type: DataTableColumnConfigurationEntryType.STANDARD as const, + fieldName: 'city', + label: 'City' + }, { + type: DataTableColumnConfigurationEntryType.STANDARD as const, + fieldName: 'state', + label: 'State' + }, { + type: DataTableColumnConfigurationEntryType.STANDARD as const, + fieldName: 'country', + label: 'Country or Area' + }, { + type: DataTableColumnConfigurationEntryType.STANDARD as const, + fieldName: 'latitude', + label: 'Latitude' + }, { + type: DataTableColumnConfigurationEntryType.STANDARD as const, + fieldName: 'longitude', + label: 'Longitude' + }, { + type: DataTableColumnConfigurationEntryType.COLOURED_PILL as const, + fieldName: 'diagnosisStatus', + valueToDisplayLabel: (diagnosisStatus: string) => isMersDiagnosisStatus(diagnosisStatus) ? diagnosisStatusToStringMap[diagnosisStatus] : diagnosisStatus, + valueToColourSchemeClassnameMap: diagnosisStatusToColourClassnameMap, + defaultColourSchemeClassname: "bg-sky-100", + label: 'Diagnosis Status' + }, { + type: DataTableColumnConfigurationEntryType.COLOURED_PILL as const, + fieldName: 'diagnosisSource', + valueToDisplayLabel: (diagnosisSource: string) => isMersDiagnosisSource(diagnosisSource) ? diagnosisSourceToStringMap[diagnosisSource] : diagnosisSource, + valueToColourSchemeClassnameMap: diagnosisSourceToColourClassnameMap, + defaultColourSchemeClassname: "bg-sky-100", + label: 'Diagnosis Source' + }, { + type: DataTableColumnConfigurationEntryType.DATE as const, + fieldName: 'observationDate', + label: 'Observation Date' + }, { + type: DataTableColumnConfigurationEntryType.COLOURED_PILL as const, + fieldName: 'animalType', + valueToDisplayLabel: (animalType: string) => isMersEventAnimalType(animalType) ? animalTypeToStringMap[animalType] : animalType, + valueToColourSchemeClassnameMap: animalTypeToColourClassnameMap, + defaultColourSchemeClassname: "bg-sky-100", + label: areNonCamelAnimalsIncluded + ? 'Animal Type' + : 'Camel Type', + }, { + type: DataTableColumnConfigurationEntryType.COLOURED_PILL_LIST as const, + fieldName: 'animalSpecies', + valueToDisplayLabel: (animalSpecies: string) => isMersAnimalSpecies(animalSpecies) ? animalSpeciesToStringMap[animalSpecies] : animalSpecies, + valueToColourSchemeClassnameMap: animalSpeciesToColourClassnameMap, + defaultColourSchemeClassname: "bg-sky-100", + label: 'Animal Species' + }, { + type: DataTableColumnConfigurationEntryType.STANDARD as const, + fieldName: 'humansAffected', + label: 'Humans Affected' + }, { + type: DataTableColumnConfigurationEntryType.STANDARD as const, + fieldName: 'humanDeaths', + label: 'Humans Deaths' + }, { + type: DataTableColumnConfigurationEntryType.STANDARD as const, + fieldName: 'id', + label: 'ID', + isHideable: false, + initiallyVisible: false + }]; + + return { + mersCasesColumnConfiguration, + } +} interface MersCasesDataTableProps { tableData: FaoMersEventForTable[]; @@ -187,6 +198,8 @@ export const MersCasesDataTable = (props: MersCasesDataTableProps) => { viewOnMapHandler }), [ viewOnMapHandler, mersVisualizationInformation ]); + const { mersCasesColumnConfiguration } = useMersCasesColumnConfiguration(); + return ( ; @@ -280,6 +281,7 @@ interface GetMersSeroprevalenceAndViralEstimateSharedColumnConfigurationInput { export const useMersEstimateColumnConfiguration = () => { const { countryNameToColourClassnameMap } = useContext(CountryInformationContext); + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); const getMersSeroprevalenceAndViralEstimateSharedColumnConfiguration = useCallback(( input: GetMersSeroprevalenceAndViralEstimateSharedColumnConfigurationInput @@ -429,7 +431,9 @@ export const useMersEstimateColumnConfiguration = () => { valueToDisplayLabel: (animalType: string) => isMersAnimalType(animalType) ? animalTypeToStringMap[animalType] : animalType, valueToColourSchemeClassnameMap: animalTypeToColourClassnameMap, defaultColourSchemeClassname: "bg-sky-100", - label: 'Animal Type' + label: areNonCamelAnimalsIncluded + ? 'Animal Type' + : 'Camel Type' }, { type: DataTableColumnConfigurationEntryType.COLOURED_PILL_LIST as const, fieldName: 'primaryEstimateAnimalSpecies', diff --git a/app/pathogen/mers/dashboard/(table)/use-data-table-map-viewing-handler.tsx b/app/pathogen/mers/dashboard/(table)/use-data-table-map-viewing-handler.tsx index 7df06e1b..2f523364 100644 --- a/app/pathogen/mers/dashboard/(table)/use-data-table-map-viewing-handler.tsx +++ b/app/pathogen/mers/dashboard/(table)/use-data-table-map-viewing-handler.tsx @@ -1,4 +1,4 @@ -import { useMap } from "react-map-gl"; +import { useMap } from "react-map-gl/mapbox"; import { useRouter } from "next/navigation"; import { useCallback } from "react"; import { Row } from "@tanstack/react-table"; diff --git a/app/pathogen/mers/dashboard/(visualizations)/estimates-by-region/animal-seroprevalence-by-region.tsx b/app/pathogen/mers/dashboard/(visualizations)/estimates-by-region/animal-seroprevalence-by-region.tsx index 04a9fc3e..04f273fa 100644 --- a/app/pathogen/mers/dashboard/(visualizations)/estimates-by-region/animal-seroprevalence-by-region.tsx +++ b/app/pathogen/mers/dashboard/(visualizations)/estimates-by-region/animal-seroprevalence-by-region.tsx @@ -1,4 +1,4 @@ -import { MouseEventHandler, useMemo, useState } from "react"; +import { MouseEventHandler, useContext, useMemo, useState } from "react"; import { AnimalMersSeroprevalenceEstimate, MersEstimate, isAnimalMersSeroprevalenceEstimate } from "@/contexts/pathogen-context/pathogen-contexts/mers/mers-context"; import { UnRegion, WhoRegion } from "@/gql/graphql"; import { FaoMersEvent } from "@/hooks/mers/useFaoMersEventDataPartitioned"; @@ -22,6 +22,7 @@ import { AnimalMersSeroprevalenceEstimatePopupContent } from "../../(map)/animal import { useBarColourAndLegendProps } from "@/components/customs/visualizations/use-bar-colour-and-legend-props"; import { generateConciseEstimateId, generateConciseSourceId } from "../../(table)/mers-seroprevalence-and-viral-estimates-shared-column-configuration"; import { EstimatesByRegionYAxisTick } from "../estimates-by-region"; +import { MersFilterMetadataContext } from "@/contexts/pathogen-context/pathogen-contexts/mers/mers-filter-metadata-context"; const AnimalSeroprevalenceByRegionTooltip = < TValueType extends number | string | Array, @@ -64,7 +65,7 @@ interface AnimalSeroprevalenceByRegionProps { export const AnimalSeroprevalenceByRegion = (props: AnimalSeroprevalenceByRegionProps) => { const { animalMersSeroprevalenceEstimates, regionGroupingFunction, regionToLegendLabel, legendConfiguration, regionToDotColour: regionToDotColourDefault, regionSortingFunction } = props; const [ isMouseOnTooltip, setIsMouseOnTooltip ] = useState(false); - + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); const { getColourForSecondaryKey, legendProps @@ -153,7 +154,7 @@ export const AnimalSeroprevalenceByRegion = (props: AnimalSeroprevalenceByRegion textAnchor="middle" dominantBaseline="central" > - Animal Seroprevalence + {areNonCamelAnimalsIncluded ? 'Animal Seroprevalence' : 'Camel Seroprevalence'} , @@ -62,7 +63,7 @@ interface AnimalViralPositivePrevalenceByRegionProps { export const AnimalViralPositivePrevalenceByRegion = (props: AnimalViralPositivePrevalenceByRegionProps) => { const { animalMersViralEstimates, regionGroupingFunction, regionToLegendLabel, legendConfiguration, regionToDotColour: regionToDotColourDefault, regionSortingFunction } = props; const [ isMouseOnTooltip, setIsMouseOnTooltip ] = useState(false); - + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); const { getColourForSecondaryKey, legendProps @@ -151,7 +152,7 @@ export const AnimalViralPositivePrevalenceByRegion = (props: AnimalViralPositive textAnchor="middle" dominantBaseline="central" > - Animal Viral Prevalence + {areNonCamelAnimalsIncluded ? 'Animal Viral Prevalence' : 'Camel Viral Prevalence'} { ) || currentMapCountryHighlightingSettings === MersMapCountryHighlightingSettings.MERS_ANIMAL_CASES ), [ currentMapCountryHighlightingSettings, selectedDataTypes, mapDataPointVisibilitySetting ]); + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); + const filterSections = useMemo(() => { const filterSectionsArray: FilterSectionConfiguration[] = []; @@ -147,7 +150,9 @@ export const MersFilters = (props: MersFiltersProps) => { if(areAnimalEstimatesVisibleOnMap) { filterSectionsArray.push({ - headerText: 'Animal Estimates', + headerText: areNonCamelAnimalsIncluded + ? 'Animal Estimates' + : 'Camel Estimates', headerTooltipText: 'Filters that only apply to animal seroprevalence and viral estimates.', includedFilters: areAnimalEventsVisibleOnMap ? animalEstimatesFilters @@ -171,14 +176,16 @@ export const MersFilters = (props: MersFiltersProps) => { areAnimalEventsVisibleOnMap ) { filterSectionsArray.push({ - headerText: 'Animal Data', + headerText: areNonCamelAnimalsIncluded + ? 'Animal Data' + : 'Camel Data', headerTooltipText: 'Filters that only apply to animal seroprevalence and viral estimates as well as animal cases.', includedFilters: animalCaseFilters }); } return filterSectionsArray; - }, [ areAnimalEstimatesVisibleOnMap, areAnimalEventsVisibleOnMap, areHumanEstimatesVisibleOnMap, areHumanEventsVisibleOnMap ]); + }, [ areAnimalEstimatesVisibleOnMap, areAnimalEventsVisibleOnMap, areHumanEstimatesVisibleOnMap, areHumanEventsVisibleOnMap, areNonCamelAnimalsIncluded ]); return ( { : ' '; }, [ numberOfNonTypenameFiltersApplied, cleanedChosenDropdownOption ]) + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); const getDisplayNameForEstimatesByRegion: MersVisualizationInformation< string, @@ -239,9 +240,13 @@ export const useEstimatesByRegionVisualizationPageConfig = () => { chosenDropdownOption: cleanedChosenDropdownOption, dropdownOptionToLabelMap: { [EstimatesByRegionVariableOfInterestDropdownOption.HUMAN_SEROPREVALENCE]: "Human Seroprevalence Estimates", - [EstimatesByRegionVariableOfInterestDropdownOption.ANIMAL_SEROPREVALENCE]: "Animal Seroprevalence Estimates", + [EstimatesByRegionVariableOfInterestDropdownOption.ANIMAL_SEROPREVALENCE]: areNonCamelAnimalsIncluded + ? "Animal Seroprevalence Estimates" + : "Camel Seroprevalence Estimates", [EstimatesByRegionVariableOfInterestDropdownOption.HUMAN_VIRAL_PREVALENCE]: "Human Viral Prevalence Estimates", - [EstimatesByRegionVariableOfInterestDropdownOption.ANIMAL_VIRAL_PREVALENCE]: "Animal Viral Prevalence Estimates", + [EstimatesByRegionVariableOfInterestDropdownOption.ANIMAL_VIRAL_PREVALENCE]: areNonCamelAnimalsIncluded + ? "Animal Viral Prevalence Estimates" + : "Camel Viral Prevalence Estimates", }, onDropdownOptionChange: (option) => { setEstimatesByRegionVariableOfInterest(option); @@ -308,7 +313,7 @@ export const useEstimatesByRegionVisualizationPageConfig = () => { } }, afterAllDropdownsHeaderText: " With 95% Confidence Intervals" - }), [ cleanedChosenDropdownOption, setEstimatesByRegionVariableOfInterest, estimatesByRegionSelectedRegion, setEstimatesByRegionSelectedRegion, availableDropdownOptionGroups, estimatesByRegionSelectedAssayClassification, assayClassificationOptions, availableSampleFrames, estimatesByRegionSelectedAnimalSampleFrameOrMacroSampleFrame ]) + }), [ cleanedChosenDropdownOption, setEstimatesByRegionVariableOfInterest, estimatesByRegionSelectedRegion, setEstimatesByRegionSelectedRegion, availableDropdownOptionGroups, estimatesByRegionSelectedAssayClassification, assayClassificationOptions, availableSampleFrames, estimatesByRegionSelectedAnimalSampleFrameOrMacroSampleFrame, areNonCamelAnimalsIncluded ]) const renderVisualizationForEstimatesByRegion: MersVisualizationInformation< string, diff --git a/app/pathogen/mers/visualizations/visualization-page-config/use-summary-by-region-visualization-page-config.tsx b/app/pathogen/mers/visualizations/visualization-page-config/use-summary-by-region-visualization-page-config.tsx index 61a89f53..04bb2072 100644 --- a/app/pathogen/mers/visualizations/visualization-page-config/use-summary-by-region-visualization-page-config.tsx +++ b/app/pathogen/mers/visualizations/visualization-page-config/use-summary-by-region-visualization-page-config.tsx @@ -138,6 +138,8 @@ export const useSummaryByRegionVisualizationPageConfig = () => { setCurrentPageIndex(newCurrentPageIndex); }, [ _setNumberOfPagesAvailable, setCurrentPageIndex, currentPageIndex ]); + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); + const getDisplayNameForSummaryByWhoRegion: MersVisualizationInformation< string, SummaryByRegionVariableOfInterestDropdownOption, @@ -177,9 +179,13 @@ export const useSummaryByRegionVisualizationPageConfig = () => { chosenDropdownOption: summaryByRegionVariableOfInterestSelectedDropdownOption, dropdownOptionToLabelMap: { [SummaryByRegionVariableOfInterestDropdownOption.HUMAN_MEDIAN_SEROPREVALENCE]: "Median Human Seroprevalence", - [SummaryByRegionVariableOfInterestDropdownOption.ANIMAL_MEDIAN_SEROPREVALENCE]: "Median Animal Seroprevalence", + [SummaryByRegionVariableOfInterestDropdownOption.ANIMAL_MEDIAN_SEROPREVALENCE]: areNonCamelAnimalsIncluded + ? "Median Animal Seroprevalence" + : "Median Camel Seroprevalence", [SummaryByRegionVariableOfInterestDropdownOption.HUMAN_MEDIAN_VIRAL_PREVALENCE]: "Median Human Viral Prevalence", - [SummaryByRegionVariableOfInterestDropdownOption.ANIMAL_MEDIAN_VIRAL_PREVALENCE]: "Median Animal Viral Prevalence", + [SummaryByRegionVariableOfInterestDropdownOption.ANIMAL_MEDIAN_VIRAL_PREVALENCE]: areNonCamelAnimalsIncluded + ? "Median Animal Viral Prevalence" + : "Median Camel Viral Prevalence", [SummaryByRegionVariableOfInterestDropdownOption.MERS_ANIMAL_CASES]: "Confirmed Animal Cases", [SummaryByRegionVariableOfInterestDropdownOption.MERS_HUMAN_CASES]: "Confirmed Human Cases", [SummaryByRegionVariableOfInterestDropdownOption.MERS_HUMAN_DEATHS]: "Confirmed Human Deaths" @@ -239,7 +245,8 @@ export const useSummaryByRegionVisualizationPageConfig = () => { setSummaryByRegionSelectedDropdownOption, availableSampleFrames, summaryByRegionSelectedAnimalSampleFrameOrMacroSampleFrame, - setSummaryByRegionSelectedAnimalSampleFrameOrMacroSampleFrame + setSummaryByRegionSelectedAnimalSampleFrameOrMacroSampleFrame, + areNonCamelAnimalsIncluded, ]) const customizationModalConfigurationForSummaryByRegion: MersVisualizationInformation< diff --git a/app/pathogen/sarscov2/dashboard/(table)/use-data-table-map-viewing-handler.tsx b/app/pathogen/sarscov2/dashboard/(table)/use-data-table-map-viewing-handler.tsx index d672aaeb..47f99311 100644 --- a/app/pathogen/sarscov2/dashboard/(table)/use-data-table-map-viewing-handler.tsx +++ b/app/pathogen/sarscov2/dashboard/(table)/use-data-table-map-viewing-handler.tsx @@ -1,4 +1,4 @@ -import { useMap } from "react-map-gl"; +import { useMap } from "react-map-gl/mapbox"; import { useRouter } from "next/navigation"; import { useCallback } from "react"; import { Row } from "@tanstack/react-table"; diff --git a/components/customs/filters/available-filters.tsx b/components/customs/filters/available-filters.tsx index 7107d6f6..c6e76b33 100644 --- a/components/customs/filters/available-filters.tsx +++ b/components/customs/filters/available-filters.tsx @@ -9,16 +9,31 @@ import { SendFilterChangeDispatch } from "../filters"; import { BooleanSelectFilter } from "./boolean-select-filter"; import { BooleanSelectOptionString } from "./select-filter"; import { CountryInformationContext } from "@/contexts/pathogen-context/country-information-context"; -import { Arbovirus, ArbovirusEstimateType, ArbovirusStudyPopulation } from "@/gql/graphql"; +import { Arbovirus, ArbovirusEstimateType, ArbovirusStudyPopulation, MersAnimalSpecies } from "@/gql/graphql"; import { arboShortformToFullNamePlusVirusMap } from "@/app/pathogen/arbovirus/dashboard/(visualizations)/recharts"; import { ColouredCheckboxFilter } from "./coloured-checkbox-filter"; -import { animalSpeciesToStringMap, animalTypeToStringMap, diagnosisSourceToStringMap, isMersDataType, isMersDataTypeSuperOption, mersDataTypeSuperOptionToLabelMap, mersDataTypeToColourClassnameMapForCheckbox, mersDataTypeToLabelMap, mersDataTypeToSortOrderMap, mersDataTypeToSuperOptionMap, mersMapPointVisibilitySettingToHiddenOptionsMap } from "@/app/pathogen/mers/dashboard/(map)/shared-mers-map-pop-up-variables"; +import { + animalSpeciesToStringMap, + animalTypeToStringMap, + diagnosisSourceToStringMap, + isMersDataType, + isMersDataTypeSuperOption, + useMersDataTypeSuperOptionToLabelMap, + mersDataTypeToColourClassnameMapForCheckbox, + mersDataTypeToSortOrderMap, + mersDataTypeToSuperOptionMap, + mersMapPointVisibilitySettingToHiddenOptionsMap, + useMersDataTypeToLabelMap, + isMersAnimalSpecies +} from "@/app/pathogen/mers/dashboard/(map)/shared-mers-map-pop-up-variables"; import { UNRegionsTooltip, WHORegionsTooltip } from "../tooltip-content"; import { GroupedColouredCheckboxFilter } from "./grouped-coloured-checkbox-filter"; import { MersMapCustomizationsContext } from "@/contexts/pathogen-context/pathogen-contexts/mers/map-customizations-context"; import { isMersMacroSampleFrameType, MersMacroSampleFramesContext, MersMacroSampleFrameType, mersMacroSampleFrameTypeToTextMap } from "@/contexts/pathogen-context/pathogen-contexts/mers/mers-macro-sample-frames-context"; import { isMersAssayClassification, MersAssayClassification, MersAssayClassificationContext, mersAssayClassificationToTextMap } from "@/contexts/pathogen-context/pathogen-contexts/mers/mers-assay-classification-content"; import { PositivePrevalenceFilterOptions } from "@/contexts/pathogen-context/pathogen-contexts/mers/mers-data-filtering"; +import { MersFilterMetadataContext } from "@/contexts/pathogen-context/pathogen-contexts/mers/mers-filter-metadata-context"; +import { isMersAnimalSpeciesGroup, MersAnimalSpeciesGroup, MersAnimalSpeciesGroupContext } from "@/contexts/pathogen-context/pathogen-contexts/mers/mers-animal-species-group-context"; export interface FieldInformation { field: FilterableField; @@ -252,13 +267,17 @@ const scopeToLabelForFilter: Record = { export const useAvailableFilters = () => { const { countryAlphaTwoCodeToCountryNameMap } = useContext(CountryInformationContext); - const { - mapDataPointVisibilitySetting, - setMapDataPointVisibilitySetting - } = useContext(MersMapCustomizationsContext); - + const { mapDataPointVisibilitySetting } = useContext(MersMapCustomizationsContext); + const { mersDataTypeToLabelMap } = useMersDataTypeToLabelMap(); const { getMacroSampleFramesForSampleFrame } = useContext(MersMacroSampleFramesContext); const { getAssayClassificationsForAssay } = useContext(MersAssayClassificationContext); + const { areNonCamelAnimalsIncluded } = useContext(MersFilterMetadataContext); + const { mersDataTypeSuperOptionToLabelMap } = useMersDataTypeSuperOptionToLabelMap(); + const { + mersAnimalSpeciesToAnimalSpeciesGroupMap, + mersAnimalSpeciesGroupToSortOrderMap, + mersAnimalSpeciesGroupToLabelMap, + } = useContext(MersAnimalSpeciesGroupContext); const availableFilters: {[key in FilterableField]: FieldInformation } = { [FilterableField.pathogen]: { @@ -575,7 +594,9 @@ export const useAvailableFilters = () => { }, [FilterableField.animalType]: { field: FilterableField.animalType, - label: "Animal Type", + label: areNonCamelAnimalsIncluded + ? "Animal Type" + : "Camel Type", valueToLabelMap: animalTypeToStringMap, filterRenderingFunction: MultiSelectFilter }, @@ -583,6 +604,22 @@ export const useAvailableFilters = () => { field: FilterableField.animalSpecies, label: "Animal Species", valueToLabelMap: animalSpeciesToStringMap, + optionToSuperOptionFunction: (option: string) => isMersAnimalSpecies(option) + ? mersAnimalSpeciesToAnimalSpeciesGroupMap[option] + : MersAnimalSpeciesGroup.UNCATEGORIZED, + superOptionSortingFunction: (superOptionA, superOptionB) => { + const valueForOptionA = isMersAnimalSpeciesGroup(superOptionA) + ? mersAnimalSpeciesGroupToSortOrderMap[superOptionA] + : mersAnimalSpeciesGroupToSortOrderMap[MersAnimalSpeciesGroup.UNCATEGORIZED]; + const valueForOptionB = isMersAnimalSpeciesGroup(superOptionB) + ? mersAnimalSpeciesGroupToSortOrderMap[superOptionB] + : mersAnimalSpeciesGroupToSortOrderMap[MersAnimalSpeciesGroup.UNCATEGORIZED]; + + return valueForOptionA - valueForOptionB; + }, + superOptionToLabelMap: (superOption: string) => isMersAnimalSpeciesGroup(superOption) + ? mersAnimalSpeciesGroupToLabelMap[superOption] + : mersAnimalSpeciesGroupToLabelMap[MersAnimalSpeciesGroup.UNCATEGORIZED], filterRenderingFunction: MultiSelectFilter }, positivePrevalence: { diff --git a/components/customs/filters/select-filter.tsx b/components/customs/filters/select-filter.tsx index 81e8cbc7..424d70ee 100644 --- a/components/customs/filters/select-filter.tsx +++ b/components/customs/filters/select-filter.tsx @@ -32,6 +32,7 @@ export interface SelectFilterProps< optionToSuperOptionFunction?: (option: string) => string; sorted?: boolean; superOptionToLabelMap?: (superOption: string) => string; + superOptionSortingFunction?: (superOptionA: string, superOptionB: string) => number; } export const SelectFilter = < @@ -77,6 +78,15 @@ export const SelectFilter = < ? pipe( props.filterOptions, (data) => data.filter((filterOption: T | undefined | null): filterOption is T => filterOption !== undefined && filterOption !== null), + (data) => data.filter((option) => { + const selected = props.state.selectedFilters[props.filter]; + + if(!selected) { + return true; + } + + return !selected.includes(option); + }), props.sorted === undefined || props.sorted === true ? (data) => data.sort() : (data) => data ) : [BooleanSelectOptionString.TRUE, BooleanSelectOptionString.FALSE] } @@ -84,6 +94,7 @@ export const SelectFilter = < singleSelect={[SelectFilterType.SINGLE_SELECT, SelectFilterType.BOOLEAN_SELECT].includes(props.selectFilterType)} optionToSuperOptionFunction={props.optionToSuperOptionFunction} superOptionToLabelMap={props.superOptionToLabelMap} + superOptionSortingFunction={props.superOptionSortingFunction} /> ) \ No newline at end of file diff --git a/components/customs/select-inner-multiple-command-group.tsx b/components/customs/select-inner-multiple-command-group.tsx index bb350a7c..18d76693 100644 --- a/components/customs/select-inner-multiple-command-group.tsx +++ b/components/customs/select-inner-multiple-command-group.tsx @@ -41,12 +41,15 @@ export const SelectInnerMultipleCommandGroup = (props: SelectInnerMultipleComman const allSuperOptions = useMemo(() => { return uniq( selectablesWithSuperOptions.map((selectable) => selectable.superOption) - ).sort((superOptionA, superOptionB) => superOptionSortingFunction - ? superOptionSortingFunction(superOptionA, superOptionA) - : 0 - ) - }, [ selectablesWithSuperOptions, superOptionSortingFunction ]); + ).sort((superOptionA, superOptionB) => { + if(superOptionSortingFunction) { + return superOptionSortingFunction(superOptionA, superOptionB) + } + return 0; + }) + }, [ selectablesWithSuperOptions, superOptionSortingFunction ]); + return (
string; superOptionToLabelMap?: (superOption: string) => string; + superOptionSortingFunction?: (superOptionA: string, superOptionB: string) => number; } const createSelectOptionList = (options: (string)[], optionToLabelMap: Record) => { @@ -38,7 +39,7 @@ const createSelectOptionList = (options: (string)[], optionToLabelMap: Record selectedOption === true ? BooleanSelectOptionString.TRUE : selectedOption) @@ -147,6 +148,7 @@ export function Select(props: SelectProps) { className={!optionToSuperOptionFunction ? 'hidden' : ''} optionToSuperOptionFunction={optionToSuperOptionFunction} superOptionToLabelMap={superOptionToLabelMap} + superOptionSortingFunction={superOptionSortingFunction} />
) : null} diff --git a/components/ui/pathogen-map/disputed-border-layer.tsx b/components/ui/pathogen-map/disputed-border-layer.tsx index 4aa5dc22..57834ead 100644 --- a/components/ui/pathogen-map/disputed-border-layer.tsx +++ b/components/ui/pathogen-map/disputed-border-layer.tsx @@ -1,5 +1,5 @@ import { useMemo } from "react"; -import { Layer, Source } from "react-map-gl"; +import { Layer, Source } from "react-map-gl/mapbox"; import { MapSymbology } from "@/app/pathogen/sarscov2/dashboard/(map)/map-config"; import { PaintForCountries } from "./pathogen-map"; diff --git a/components/ui/pathogen-map/esm-maps.tsx b/components/ui/pathogen-map/esm-maps.tsx index fa5adaef..3041bbd7 100644 --- a/components/ui/pathogen-map/esm-maps.tsx +++ b/components/ui/pathogen-map/esm-maps.tsx @@ -1,6 +1,6 @@ import { ArboContext } from "@/contexts/pathogen-context/pathogen-contexts/arbovirus/arbo-context"; import { useContext } from "react"; -import { Layer, Source } from "react-map-gl"; +import { Layer, Source } from "react-map-gl/mapbox"; type Esms = "zika" | "dengue2015" | "dengue2050"; diff --git a/components/ui/pathogen-map/map-aksai-chin-area-layer.tsx b/components/ui/pathogen-map/map-aksai-chin-area-layer.tsx index 3b43ed2a..7ba1763c 100644 --- a/components/ui/pathogen-map/map-aksai-chin-area-layer.tsx +++ b/components/ui/pathogen-map/map-aksai-chin-area-layer.tsx @@ -1,4 +1,4 @@ -import { Source, Layer, LayerProps } from "react-map-gl"; +import { Source, Layer, LayerProps } from "react-map-gl/mapbox"; import { PaintForCountries } from "./pathogen-map"; import { useEffect, useState } from "react"; import { getEsriVectorSourceStyle } from "@/utils/mapping-util"; diff --git a/components/ui/pathogen-map/map-download-button.tsx b/components/ui/pathogen-map/map-download-button.tsx index 6b0b96e3..1895790c 100644 --- a/components/ui/pathogen-map/map-download-button.tsx +++ b/components/ui/pathogen-map/map-download-button.tsx @@ -2,7 +2,7 @@ import { DashboardType, dashboardTypeToHoverColourClassnameMap, dashboardTypeToM import { cn } from "@/lib/utils"; import { CloudDownload } from "lucide-react"; import { useMemo, useCallback } from "react"; -import { useMap } from "react-map-gl"; +import { useMap } from "react-map-gl/mapbox"; import { Card } from "../card"; interface MapDownloadButtonProps { diff --git a/components/ui/pathogen-map/map-jammu-kashmir-area-layer.tsx b/components/ui/pathogen-map/map-jammu-kashmir-area-layer.tsx index f61c56a0..b33c1dc5 100644 --- a/components/ui/pathogen-map/map-jammu-kashmir-area-layer.tsx +++ b/components/ui/pathogen-map/map-jammu-kashmir-area-layer.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from "react"; import { MapResources } from "@/app/pathogen/sarscov2/dashboard/(map)/map-config"; import { getEsriVectorSourceStyle } from "@/utils/mapping-util"; -import { Source, Layer, LayerProps } from "react-map-gl"; +import { Source, Layer, LayerProps } from "react-map-gl/mapbox"; export interface MapJammuKashmirAreaLayerProps { positionedUnderLayerWithId: string | undefined; diff --git a/components/ui/pathogen-map/pathogen-country-highlight-layer.tsx b/components/ui/pathogen-map/pathogen-country-highlight-layer.tsx index b0f135cb..ef586519 100644 --- a/components/ui/pathogen-map/pathogen-country-highlight-layer.tsx +++ b/components/ui/pathogen-map/pathogen-country-highlight-layer.tsx @@ -1,8 +1,6 @@ -import { Layer, Source } from "react-map-gl"; +import { Layer } from "react-map-gl/mapbox"; import { PaintForCountries, PATHOGEN_MAP_WHO_ADMIN_O_SOURCE_LAYER_ID, PathogenDataPointPropertiesBase } from "./pathogen-map"; -import { useEffect, useState, useMemo } from "react"; -import { getEsriVectorSourceStyle } from "@/utils/mapping-util"; -import { MapResources } from "@/app/pathogen/sarscov2/dashboard/(map)/map-config"; +import { useMemo } from "react"; interface PathogenCountryHighlightLayerProps { positionedUnderLayerWithId: string | undefined; diff --git a/components/ui/pathogen-map/pathogen-map-cluster-utils.tsx b/components/ui/pathogen-map/pathogen-map-cluster-utils.tsx index affec641..102ea6f6 100644 --- a/components/ui/pathogen-map/pathogen-map-cluster-utils.tsx +++ b/components/ui/pathogen-map/pathogen-map-cluster-utils.tsx @@ -3,7 +3,7 @@ import { MarkerCollection } from "@/components/ui/pathogen-map/pathogen-map"; import { Browser, detectBrowser } from "@/lib/detect-browser"; import mapboxgl from "mapbox-gl"; import React from "react"; -import { Marker } from "react-map-gl"; +import { Marker } from "react-map-gl/mapbox"; // code for creating an SVG donut chart from feature properties export function createDonutChartAndHoverPopup< diff --git a/components/ui/pathogen-map/pathogen-map-layer.tsx b/components/ui/pathogen-map/pathogen-map-layer.tsx index 2c76dc25..10cd3776 100644 --- a/components/ui/pathogen-map/pathogen-map-layer.tsx +++ b/components/ui/pathogen-map/pathogen-map-layer.tsx @@ -1,7 +1,6 @@ -import { Layer, Source } from "react-map-gl"; +import { Layer, Source } from "react-map-gl/mapbox"; import { ClusteringSettings, PathogenDataPointPropertiesBase } from "./pathogen-map"; import { PathogenMapCursor } from "./use-pathogen-map-mouse"; -import cluster from "cluster"; export interface PathogenMapLayerInfo { id: string; diff --git a/components/ui/pathogen-map/pathogen-map-popup.tsx b/components/ui/pathogen-map/pathogen-map-popup.tsx index c6c5d79f..2bcb0599 100644 --- a/components/ui/pathogen-map/pathogen-map-popup.tsx +++ b/components/ui/pathogen-map/pathogen-map-popup.tsx @@ -1,5 +1,5 @@ import validator from "validator"; -import { MapRef, Popup, useMap } from "react-map-gl"; +import { MapRef, Popup, useMap } from "react-map-gl/mapbox"; import { PathogenDataPointPropertiesBase } from "./pathogen-map"; import { Browser, detectBrowser } from "@/lib/detect-browser"; import { useMemo } from "react"; diff --git a/components/ui/pathogen-map/pathogen-map.tsx b/components/ui/pathogen-map/pathogen-map.tsx index 9f509b94..580b5b47 100644 --- a/components/ui/pathogen-map/pathogen-map.tsx +++ b/components/ui/pathogen-map/pathogen-map.tsx @@ -1,5 +1,5 @@ import { useState, useContext, useCallback } from "react"; -import { Map, MapProps, NavigationControl, ViewStateChangeEvent } from "react-map-gl"; +import { Map, MapProps, NavigationControl, ViewStateChangeEvent } from "react-map-gl/mapbox"; import { PathogenMapCursor, usePathogenMapMouse, diff --git a/contexts/pathogen-context/filter-update-steps.tsx b/contexts/pathogen-context/filter-update-steps.tsx index 4ae1f7c5..c8a1727d 100644 --- a/contexts/pathogen-context/filter-update-steps.tsx +++ b/contexts/pathogen-context/filter-update-steps.tsx @@ -1,4 +1,4 @@ -import { MapRef } from "react-map-gl" +import { MapRef } from "react-map-gl/mapbox" import { pipe } from "fp-ts/lib/function.js"; import { adjustMapPosition } from "./filter-update-steps/adjust-map-position"; import { updatePediatricAgeGroupFilter } from "./filter-update-steps/update-pediatric-age-group-filter"; diff --git a/contexts/pathogen-context/pathogen-context.tsx b/contexts/pathogen-context/pathogen-context.tsx index 2dfff9fd..5859fd97 100644 --- a/contexts/pathogen-context/pathogen-context.tsx +++ b/contexts/pathogen-context/pathogen-context.tsx @@ -1,7 +1,7 @@ "use client"; import { QueryClient, QueryClientProvider, UseQueryResult } from "@tanstack/react-query"; import { ToastProvider } from "../toast-provider"; -import { MapProvider, MapRef, useMap } from "react-map-gl"; +import { MapProvider, MapRef, useMap } from "react-map-gl/mapbox"; import React, { Context, Dispatch, useReducer } from "react"; import { filterData } from "./filter-update-steps/apply-new-selected-filters"; import { handleFilterUpdate } from "./filter-update-steps"; diff --git a/contexts/pathogen-context/pathogen-contexts/arbovirus/arbo-oropouche-cases-data-context.tsx b/contexts/pathogen-context/pathogen-contexts/arbovirus/arbo-oropouche-cases-data-context.tsx index df711d69..8464a630 100644 --- a/contexts/pathogen-context/pathogen-contexts/arbovirus/arbo-oropouche-cases-data-context.tsx +++ b/contexts/pathogen-context/pathogen-contexts/arbovirus/arbo-oropouche-cases-data-context.tsx @@ -1,6 +1,6 @@ import { ColourBucket, generateMapColourBuckets } from "@/components/ui/pathogen-map/country-highlight-layers/generate-map-colour-buckets"; import { createContext, useEffect, useState, useMemo } from "react"; -import { Layer, Source } from "react-map-gl"; +import { Layer, Source } from "react-map-gl/mapbox"; import { rose } from "tailwindcss/colors"; type OropoucheCaseGeoJsonFeature = { @@ -56,7 +56,7 @@ export const ArbovirusOropoucheCasesDataProvider = (props: ArbovirusOropoucheCas .then((response): Promise => response.json()) .then((responseJson) => setOropoucheCasesGeoJSONData(responseJson)) } - }, [ oropoucheCasesGeoJSONData, setOropoucheCasesGeoJSONData, process ]); + }, [ oropoucheCasesGeoJSONData, setOropoucheCasesGeoJSONData ]); const { mapColourBuckets: oropoucheCaseLayerColourBuckets } = useMemo(() => { if(!oropoucheCasesGeoJSONData) { diff --git a/contexts/pathogen-context/pathogen-contexts/mers/mers-animal-species-group-context.tsx b/contexts/pathogen-context/pathogen-contexts/mers/mers-animal-species-group-context.tsx new file mode 100644 index 00000000..d1c7f208 --- /dev/null +++ b/contexts/pathogen-context/pathogen-contexts/mers/mers-animal-species-group-context.tsx @@ -0,0 +1,77 @@ +import { MersAnimalSpecies } from "@/gql/graphql" +import { createContext, useMemo } from "react"; + +export enum MersAnimalSpeciesGroup { + CAMELS = 'CAMELS', + OTHER_ANIMAL_SPECIES = 'OTHER_ANIMAL_SPECIES', + UNCATEGORIZED = 'UNCATEGORIZED' +} + +export const isMersAnimalSpeciesGroup = (animalSpeciesGroup: string): animalSpeciesGroup is MersAnimalSpeciesGroup => Object.values(MersAnimalSpeciesGroup).some((element) => element === animalSpeciesGroup); + +interface MersAnimalSpeciesGroupContextType { + mersAnimalSpeciesToAnimalSpeciesGroupMap: Record; + mersAnimalSpeciesGroupToSortOrderMap: Record; + mersAnimalSpeciesGroupToLabelMap: Record; +} + +const initialMersAnimalSpeciesGroupContext: MersAnimalSpeciesGroupContextType = { + mersAnimalSpeciesToAnimalSpeciesGroupMap: { + [MersAnimalSpecies.Baboon]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + [MersAnimalSpecies.BactrianCamel]: MersAnimalSpeciesGroup.CAMELS, + [MersAnimalSpecies.Bat]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + [MersAnimalSpecies.Buffalo]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + [MersAnimalSpecies.Cattle]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + [MersAnimalSpecies.Donkey]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + [MersAnimalSpecies.DromedaryCamel]: MersAnimalSpeciesGroup.CAMELS, + [MersAnimalSpecies.Goat]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + [MersAnimalSpecies.Horse]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + [MersAnimalSpecies.Mule]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + [MersAnimalSpecies.Sheep]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + [MersAnimalSpecies.WaterBuffalo]: MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES, + }, + mersAnimalSpeciesGroupToSortOrderMap: { + [MersAnimalSpeciesGroup.CAMELS]: 1, + [MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES]: 2, + [MersAnimalSpeciesGroup.UNCATEGORIZED]: 3, + }, + mersAnimalSpeciesGroupToLabelMap: { + [MersAnimalSpeciesGroup.CAMELS]: 'Camels', + [MersAnimalSpeciesGroup.OTHER_ANIMAL_SPECIES]: 'Other animal species', + [MersAnimalSpeciesGroup.UNCATEGORIZED]: 'Uncategorized', + } +}; + +export const MersAnimalSpeciesGroupContext = createContext< + MersAnimalSpeciesGroupContextType +>(initialMersAnimalSpeciesGroupContext); + +interface MersAnimalSpeciesGroupProviderProps { + children: React.ReactNode; +} + +export const MersAnimalSpeciesGroupProvider = (props: MersAnimalSpeciesGroupProviderProps) => { + const mersAnimalSpeciesToAnimalSpeciesGroupMap = useMemo(() => { + return initialMersAnimalSpeciesGroupContext['mersAnimalSpeciesToAnimalSpeciesGroupMap']; + }, []); + + const mersAnimalSpeciesGroupToSortOrderMap = useMemo(() => { + return initialMersAnimalSpeciesGroupContext['mersAnimalSpeciesGroupToSortOrderMap']; + }, []); + + const mersAnimalSpeciesGroupToLabelMap = useMemo(() => { + return initialMersAnimalSpeciesGroupContext['mersAnimalSpeciesGroupToLabelMap']; + }, []); + + return ( + + {props.children} + + ); +} \ No newline at end of file diff --git a/contexts/pathogen-context/pathogen-contexts/mers/mers-context.tsx b/contexts/pathogen-context/pathogen-contexts/mers/mers-context.tsx index b5cba78a..2452b29f 100644 --- a/contexts/pathogen-context/pathogen-contexts/mers/mers-context.tsx +++ b/contexts/pathogen-context/pathogen-contexts/mers/mers-context.tsx @@ -11,7 +11,7 @@ import { filterData } from "../../filter-update-steps/apply-new-selected-filters import { addActionToSelectedFilters } from "../../filter-update-steps/add-action-to-selected-filters"; import { adjustMapPosition } from "../../filter-update-steps/adjust-map-position"; import { useMersPrimaryEstimates } from "@/hooks/mers/useMersPrimaryEstimates"; -import { MersPrimaryEstimatesQuery, PartitionedFaoMersEventsQuery } from "@/gql/graphql"; +import { MersAnimalSpecies, MersPrimaryEstimatesQuery, PartitionedFaoMersEventsQuery } from "@/gql/graphql"; import { filterMersEstimates } from "./mers-data-filtering"; import { MersMapCustomizationsProvider } from "./map-customizations-context"; import { MersMacroSampleFramesProvider } from "./mers-macro-sample-frames-context"; @@ -31,6 +31,7 @@ const initialMersContextState = { "AnimalMersEvent", "HumanMersEvent" ], + ['animalSpecies']: [MersAnimalSpecies.BactrianCamel, MersAnimalSpecies.DromedaryCamel], }, dataFiltered: false, } @@ -188,71 +189,82 @@ const MersDataFetcher = (props: PathogenDataFetcherProps ({ + ...primaryEstimate, + geographicalAreaSubestimates: primaryEstimate.geographicalAreaSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + sexSubestimates: primaryEstimate.sexSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + ageGroupSubestimates: primaryEstimate.ageGroupSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + animalSpeciesSubestimates: primaryEstimate.animalSpeciesSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + testUsedSubestimates: primaryEstimate.testUsedSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + timeFrameSubestimates: primaryEstimate.timeFrameSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + sampleTypeSubestimates: primaryEstimate.sampleTypeSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + animalSourceLocationSubestimates: primaryEstimate.animalSourceLocationSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + animalSamplingContextSubestimates: primaryEstimate.animalSamplingContextSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + occupationSubestimates: primaryEstimate.occupationSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + camelExposureLevelSubestimates: primaryEstimate.camelExposureLevelSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + nomadismSubestimates: primaryEstimate.nomadismSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + humanCountriesOfTravelSubestimates: primaryEstimate.humanCountriesOfTravelSubestimates.map((subestimate) => ({ + ...subestimate, + markedAsFiltered: false, + })), + })), + faoMersEventData: faoMersEvents + }; + props.dispatch({ type: PathogenContextActionType.INITIAL_DATA_FETCH, payload: { - data: { - mersEstimates: data.mersPrimaryEstimates.map((primaryEstimate) => ({ - ...primaryEstimate, - geographicalAreaSubestimates: primaryEstimate.geographicalAreaSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - sexSubestimates: primaryEstimate.sexSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - ageGroupSubestimates: primaryEstimate.ageGroupSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - animalSpeciesSubestimates: primaryEstimate.animalSpeciesSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - testUsedSubestimates: primaryEstimate.testUsedSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - timeFrameSubestimates: primaryEstimate.timeFrameSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - sampleTypeSubestimates: primaryEstimate.sampleTypeSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - animalSourceLocationSubestimates: primaryEstimate.animalSourceLocationSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - animalSamplingContextSubestimates: primaryEstimate.animalSamplingContextSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - occupationSubestimates: primaryEstimate.occupationSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - camelExposureLevelSubestimates: primaryEstimate.camelExposureLevelSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - nomadismSubestimates: primaryEstimate.nomadismSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - humanCountriesOfTravelSubestimates: primaryEstimate.humanCountriesOfTravelSubestimates.map((subestimate) => ({ - ...subestimate, - markedAsFiltered: false, - })), - })), - faoMersEventData: faoMersEvents - } + data: dataForAction, } }); + + props.dispatch({ + type: PathogenContextActionType.UPDATE_FILTER, + payload: { + filter: 'animalSpecies', + value: [MersAnimalSpecies.BactrianCamel, MersAnimalSpecies.DromedaryCamel], + data: dataForAction, + }, + }); } - }, [ data, faoMersEvents ]); + }, [ data, faoMersEvents, props ]); return ( <> @@ -360,7 +372,7 @@ export const MersProviders = (props: MersProvidersProps) => { initialMersContextState.selectedFilters ), selectedFilters: initialMersContextState.selectedFilters, - dataFiltered: false, + dataFiltered: true, })} dataFetcher={MersDataFetcher} > diff --git a/contexts/pathogen-context/pathogen-contexts/mers/mers-data-filtering.tsx b/contexts/pathogen-context/pathogen-contexts/mers/mers-data-filtering.tsx index c3eebd15..1f83c8de 100644 --- a/contexts/pathogen-context/pathogen-contexts/mers/mers-data-filtering.tsx +++ b/contexts/pathogen-context/pathogen-contexts/mers/mers-data-filtering.tsx @@ -473,7 +473,7 @@ const allMersEstimateHandlers: Record dispatch({ type: PathogenContextActionType.RESET_FILTERS, payload: { @@ -65,7 +85,7 @@ export const MersFilterMetadataProvider = (props: MersFilterMetadataProviderProp } }) } - }, [ numberOfNonTypenameFiltersApplied ]) + }, [ numberOfNonTypenameFiltersApplied, data?.mersPrimaryEstimates, dispatch, faoMersEvents, selectedFilters ]); const visualizationFootnote = useMemo(() => { return numberOfNonTypenameFiltersApplied !== 0 @@ -81,13 +101,28 @@ export const MersFilterMetadataProvider = (props: MersFilterMetadataProviderProp return 'SeroTracker Research Group (2024); MERSTracker Dashboard. Website, accessible via https://new.serotracker.com/' }, []) + const areNonCamelAnimalsIncluded = useMemo(() => { + const selectedAnimalSpecies: string[] | undefined = selectedFilters['animalSpecies']; + + if(!selectedAnimalSpecies || selectedAnimalSpecies.length === 0) { + return true; + } + + if(selectedAnimalSpecies.some((element) => element !== MersAnimalSpecies.BactrianCamel && element !== MersAnimalSpecies.DromedaryCamel)) { + return true; + } + + return false; + }, [ selectedFilters ]); + return ( {props.children} diff --git a/package-lock.json b/package-lock.json index fff9c24c..53cc2895 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "@tanstack/react-query": "^5.90.12", "@tanstack/react-table": "^8.21.3", "assert-never": "^1.4.0", - "autoprefixer": "10.4.22", + "autoprefixer": "10.4.23", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^0.2.0", @@ -53,7 +53,7 @@ "react-day-picker": "^8.10.1", "react-dom": "18.3.1", "react-fast-marquee": "^1.6.5", - "react-map-gl": "^7.1.7", + "react-map-gl": "^8.1.0", "react-slick": "^0.31.0", "recharts": "^2.15.0", "regression": "^2.0.1", @@ -3609,6 +3609,7 @@ "version": "19.3.3", "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.3.tgz", "integrity": "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==", + "license": "ISC", "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/unitbezier": "^0.0.1", @@ -6078,6 +6079,7 @@ "version": "3.4.1", "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.4.1.tgz", "integrity": "sha512-NsGKKtgW93B+UaLPti6B7NwlxYlES5DpV5Gzj9F75rK5ALKsqSk15CiEHbOnTr09RGbr6ZYiCdI+59NNNcAImg==", + "dev": true, "dependencies": { "@types/geojson": "*" } @@ -6398,6 +6400,41 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@vis.gl/react-mapbox": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@vis.gl/react-mapbox/-/react-mapbox-8.1.0.tgz", + "integrity": "sha512-FwvH822oxEjWYOr+pP2L8hpv+7cZB2UsQbHHHT0ryrkvvqzmTgt7qHDhamv0EobKw86e1I+B4ojENdJ5G5BkyQ==", + "license": "MIT", + "peerDependencies": { + "mapbox-gl": ">=3.5.0", + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + }, + "peerDependenciesMeta": { + "mapbox-gl": { + "optional": true + } + } + }, + "node_modules/@vis.gl/react-maplibre": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@vis.gl/react-maplibre/-/react-maplibre-8.1.0.tgz", + "integrity": "sha512-PkAK/gp3mUfhCLhUuc+4gc3PN9zCtVGxTF2hB6R5R5yYUw+hdg84OZ770U5MU4tPMTCG6fbduExuIW6RRKN6qQ==", + "license": "MIT", + "dependencies": { + "@maplibre/maplibre-gl-style-spec": "^19.2.1" + }, + "peerDependencies": { + "maplibre-gl": ">=4.0.0", + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + }, + "peerDependenciesMeta": { + "maplibre-gl": { + "optional": true + } + } + }, "node_modules/@vitejs/plugin-react": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.2.tgz", @@ -6798,6 +6835,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6958,6 +6996,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6991,9 +7030,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.22", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.22.tgz", - "integrity": "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==", + "version": "10.4.23", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", + "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", "funding": [ { "type": "opencollective", @@ -7010,10 +7049,9 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.27.0", - "caniuse-lite": "^1.0.30001754", + "browserslist": "^4.28.1", + "caniuse-lite": "^1.0.30001760", "fraction.js": "^5.3.4", - "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, @@ -7063,9 +7101,9 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.25", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz", - "integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==", + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", + "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" @@ -7111,9 +7149,9 @@ } }, "node_modules/browserslist": { - "version": "4.27.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", - "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "funding": [ { "type": "opencollective", @@ -7130,11 +7168,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.19", - "caniuse-lite": "^1.0.30001751", - "electron-to-chromium": "^1.5.238", - "node-releases": "^2.0.26", - "update-browserslist-db": "^1.1.4" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -7168,6 +7206,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", "integrity": "sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==", + "license": "MIT", "dependencies": { "bytewise-core": "^1.2.2", "typewise": "^1.0.3" @@ -7177,6 +7216,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", "integrity": "sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==", + "license": "MIT", "dependencies": { "typewise-core": "^1.2" } @@ -7229,9 +7269,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001754", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", - "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", "funding": [ { "type": "opencollective", @@ -8634,9 +8674,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.5.249", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz", - "integrity": "sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==", + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -9378,6 +9418,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", "dependencies": { "is-extendable": "^0.1.0" }, @@ -9792,6 +9833,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10429,6 +10471,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10555,6 +10598,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -10760,6 +10804,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10969,7 +11014,8 @@ "node_modules/json-stringify-pretty-compact": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz", - "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==" + "integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==", + "license": "MIT" }, "node_modules/json-to-pretty-yaml": { "version": "1.2.2", @@ -11797,14 +11843,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", @@ -12529,12 +12567,13 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-map-gl": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-7.1.7.tgz", - "integrity": "sha512-mwjc0obkBJOXCcoXQr3VoLqmqwo9vS4bXfbGsdxXzEgVCv/PM0v+1QggL7W0d/ccIy+VCjbXNlGij+PENz6VNg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-8.1.0.tgz", + "integrity": "sha512-vDx/QXR3Tb+8/ap/z6gdMjJQ8ZEyaZf6+uMSPz7jhWF5VZeIsKsGfPvwHVPPwGF43Ryn+YR4bd09uEFNR5OPdg==", + "license": "MIT", "dependencies": { - "@maplibre/maplibre-gl-style-spec": "^19.2.1", - "@types/mapbox-gl": ">=1.0.0" + "@vis.gl/react-mapbox": "8.1.0", + "@vis.gl/react-maplibre": "8.1.0" }, "peerDependencies": { "mapbox-gl": ">=1.13.0", @@ -13163,6 +13202,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "license": "MIT", "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -13383,6 +13423,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.2.0.tgz", "integrity": "sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13391,6 +13432,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.2.0.tgz", "integrity": "sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13399,6 +13441,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-3.0.3.tgz", "integrity": "sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==", + "license": "MIT", "dependencies": { "bytewise": "^1.1.0", "get-value": "^2.0.2", @@ -13429,6 +13472,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "license": "MIT", "dependencies": { "extend-shallow": "^3.0.0" }, @@ -13440,6 +13484,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -13452,6 +13497,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -14214,6 +14260,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", "integrity": "sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==", + "license": "MIT", "dependencies": { "typewise-core": "^1.2.0" } @@ -14221,7 +14268,8 @@ "node_modules/typewise-core": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", - "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==" + "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==", + "license": "MIT" }, "node_modules/ua-parser-js": { "version": "1.0.41", @@ -14286,6 +14334,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "license": "MIT", "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -14321,9 +14370,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", + "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index 54871005..8033daa9 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@tanstack/react-query": "^5.90.12", "@tanstack/react-table": "^8.21.3", "assert-never": "^1.4.0", - "autoprefixer": "10.4.22", + "autoprefixer": "10.4.23", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^0.2.0", @@ -56,7 +56,7 @@ "react-day-picker": "^8.10.1", "react-dom": "18.3.1", "react-fast-marquee": "^1.6.5", - "react-map-gl": "^7.1.7", + "react-map-gl": "^8.1.0", "react-slick": "^0.31.0", "recharts": "^2.15.0", "regression": "^2.0.1",