From 61a55eda497e5f0a32645087b100c24714d47536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Prod=27homme?= Date: Fri, 22 Nov 2024 16:21:07 +0100 Subject: [PATCH] feat(client): Display all selected location levels --- client/src/components/dataset-card/index.tsx | 18 ++++-- .../navigation/navigation-desktop/index.tsx | 8 +-- client/src/hooks/use-location-by-code.ts | 45 --------------- client/src/hooks/use-location-by-codes.ts | 56 +++++++++++++++++++ 4 files changed, 72 insertions(+), 55 deletions(-) delete mode 100644 client/src/hooks/use-location-by-code.ts create mode 100644 client/src/hooks/use-location-by-codes.ts diff --git a/client/src/components/dataset-card/index.tsx b/client/src/components/dataset-card/index.tsx index f1fd957..b0722b6 100644 --- a/client/src/components/dataset-card/index.tsx +++ b/client/src/components/dataset-card/index.tsx @@ -24,7 +24,7 @@ import { Switch } from "@/components/ui/switch"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import YearChart from "@/components/year-chart"; import useLocation from "@/hooks/use-location"; -import { useLocationByCode } from "@/hooks/use-location-by-code"; +import { useLocationByCodes } from "@/hooks/use-location-by-codes"; import useMapLayers from "@/hooks/use-map-layers"; import useYearChartData from "@/hooks/use-year-chart-data"; import { cn } from "@/lib/utils"; @@ -120,8 +120,8 @@ const DatasetCard = ({ selectedDate, ); - const { data: locationData, isLoading: locationIsLoading } = useLocationByCode( - location.code.slice(-1)[0], + const { data: locationData, isLoading: locationIsLoading } = useLocationByCodes( + location.code.slice(-1), ); const onToggleAnimation = useCallback(() => { @@ -231,7 +231,13 @@ const DatasetCard = ({ ); const onClickSaveChartData = useCallback(() => { - if (chartIsLoading || !chartData || locationIsLoading || !locationData || !selectedDate) { + if ( + chartIsLoading || + !chartData || + locationIsLoading || + !locationData?.length || + !selectedDate + ) { return; } @@ -248,14 +254,14 @@ const DatasetCard = ({ }; }, {}), year: getYear(selectedDate), - location: locationData.name, + location: locationData[0].name, ...chartData, }; const blob = new Blob([JSON.stringify(data)], { type: "application/json" }); const link = document.createElement("a"); - link.download = `${name} - ${locationData.name}.json`; + link.download = `${name} - ${locationData[0].name}.json`; link.href = URL.createObjectURL(blob); link.click(); link.remove(); diff --git a/client/src/components/navigation/navigation-desktop/index.tsx b/client/src/components/navigation/navigation-desktop/index.tsx index b8e8419..56ae985 100644 --- a/client/src/components/navigation/navigation-desktop/index.tsx +++ b/client/src/components/navigation/navigation-desktop/index.tsx @@ -9,7 +9,7 @@ import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; import { Sidebar, SidebarContent, SidebarHeader, SidebarTrigger } from "@/components/ui/sidebar"; import useLocation from "@/hooks/use-location"; -import { useLocationByCode } from "@/hooks/use-location-by-code"; +import { useLocationByCodes } from "@/hooks/use-location-by-codes"; import MapPinIcon from "@/svgs/map-pin.svg"; import Logo from "../logo"; @@ -18,7 +18,7 @@ const NavigationDesktop = () => { const [locationDialogOpen, setLocationDialogOpen] = useState(false); const [location] = useLocation(); - const { data, isLoading } = useLocationByCode(location.code.slice(-1)[0]); + const { data, isLoading } = useLocationByCodes([...location.code].reverse()); const onExitLocationDialog = useCallback(() => { setLocationDialogOpen(false); @@ -41,8 +41,8 @@ const NavigationDesktop = () => { variant="ghost" className="relative -left-4 mt-2 gap-4 text-white/60 hover:text-white focus-visible:text-white" > - {(!!isLoading || !data) && "Select location"} - {!isLoading && !!data && data.name} + {(isLoading || !data) && "Select location"} + {!isLoading && !!data && data.map(({ name }) => name).join(", ")} diff --git a/client/src/hooks/use-location-by-code.ts b/client/src/hooks/use-location-by-code.ts deleted file mode 100644 index e8a836f..0000000 --- a/client/src/hooks/use-location-by-code.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { useGetLocations } from "@/types/generated/location"; - -type LocationByCode = { - id: number; - name: string; - code: string; -}; - -export function useLocationByCode(code: string | undefined) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error - const { data, isLoading } = useGetLocations( - { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error - fields: ["name", "code"], - filters: { - code: { - $eq: code, - }, - }, - sort: "name", - "pagination[limit]": 1, - }, - { - query: { - enabled: code !== undefined, - placeholderData: { data: undefined }, - select: (data) => { - if (!data?.data || data.data.length === 0) { - return undefined; - } - - return { - id: data.data[0].id, - name: data.data[0].attributes!.name!, - code: data.data[0].attributes!.code!, - }; - }, - }, - }, - ); - - return { data, isLoading }; -} diff --git a/client/src/hooks/use-location-by-codes.ts b/client/src/hooks/use-location-by-codes.ts new file mode 100644 index 0000000..c3a4c4e --- /dev/null +++ b/client/src/hooks/use-location-by-codes.ts @@ -0,0 +1,56 @@ +import { useQueries } from "@tanstack/react-query"; + +import { getGetLocationsQueryKey, getLocations } from "@/types/generated/location"; +import { GetLocationsParams, LocationListResponse } from "@/types/generated/strapi.schemas"; + +type LocationByCode = { + id: number; + name: string; + code: string; +}; + +export function useLocationByCodes(codes: string[]) { + const { data, isLoading } = useQueries({ + queries: codes.map((code) => { + const queryParams: GetLocationsParams = { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-error + fields: ["name", "code"], + filters: { + code: { + $eq: code, + }, + }, + sort: "name", + "pagination[limit]": 1, + }; + + return { + queryKey: getGetLocationsQueryKey(queryParams), + queryFn: () => getLocations(queryParams), + placeholderData: { data: undefined }, + select: (data: LocationListResponse) => { + if (!data?.data || data.data.length === 0) { + return undefined; + } + + return { + id: data.data[0].id, + name: data.data[0].attributes!.name!, + code: data.data[0].attributes!.code!, + } as LocationByCode; + }, + }; + }), + combine: (results) => { + const isLoading = results.some(({ isPending }) => isPending); + + return { + data: isLoading ? undefined : results.map(({ data }) => data!), + isLoading, + }; + }, + }); + + return { data, isLoading }; +}