From 3dc3733de055fdfc60714597bf7052cd0f674b54 Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 08:56:42 +0000 Subject: [PATCH 01/12] Add base Checkbox UI component --- frontend/package.json | 1 + frontend/src/components/ui/checkbox.tsx | 32 +++++++++++++++++++++++++ frontend/yarn.lock | 28 ++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 frontend/src/components/ui/checkbox.tsx diff --git a/frontend/package.json b/frontend/package.json index a5c437c7..42578d6c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -26,6 +26,7 @@ "@loaders.gl/zip": "^3.4.14", "@mapbox/mapbox-gl-draw": "^1.4.2", "@radix-ui/react-accordion": "^1.1.2", + "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-label": "^2.0.2", diff --git a/frontend/src/components/ui/checkbox.tsx b/frontend/src/components/ui/checkbox.tsx new file mode 100644 index 00000000..fd082a5c --- /dev/null +++ b/frontend/src/components/ui/checkbox.tsx @@ -0,0 +1,32 @@ +import * as React from 'react'; + +import * as CheckboxPrimitive from '@radix-ui/react-checkbox'; +import { cva, type VariantProps } from 'class-variance-authority'; +import { CheckIcon } from 'lucide-react'; + +import { cn } from '@/lib/classnames'; + +const checkboxVariants = cva(''); + +const Checkbox = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, name, ...props }, ref) => ( + + + + + +)); + +Checkbox.displayName = CheckboxPrimitive.Root.displayName; + +export { Checkbox }; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index c1e7daf1..ab42771d 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1388,6 +1388,33 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-checkbox@npm:^1.0.4": + version: 1.0.4 + resolution: "@radix-ui/react-checkbox@npm:1.0.4" + dependencies: + "@babel/runtime": ^7.13.10 + "@radix-ui/primitive": 1.0.1 + "@radix-ui/react-compose-refs": 1.0.1 + "@radix-ui/react-context": 1.0.1 + "@radix-ui/react-presence": 1.0.1 + "@radix-ui/react-primitive": 1.0.3 + "@radix-ui/react-use-controllable-state": 1.0.1 + "@radix-ui/react-use-previous": 1.0.1 + "@radix-ui/react-use-size": 1.0.1 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 6dac5bddd9e1c42b149555501440918d9eae70da13b6d8539c3bf46b6c07681119d865d2106a43f729884ae8e2043bedc34c4d00a09a527b3bf0feade088d188 + languageName: node + linkType: hard + "@radix-ui/react-collapsible@npm:1.0.3, @radix-ui/react-collapsible@npm:^1.0.3": version: 1.0.3 resolution: "@radix-ui/react-collapsible@npm:1.0.3" @@ -11653,6 +11680,7 @@ __metadata: "@loaders.gl/zip": ^3.4.14 "@mapbox/mapbox-gl-draw": ^1.4.2 "@radix-ui/react-accordion": ^1.1.2 + "@radix-ui/react-checkbox": ^1.0.4 "@radix-ui/react-collapsible": ^1.0.3 "@radix-ui/react-dialog": ^1.0.4 "@radix-ui/react-label": ^2.0.2 From f5a3052b0e81a511fe0028e4d92105580342c903 Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 08:58:22 +0000 Subject: [PATCH 02/12] Add filters-button component for use in the data-tool tables --- frontend/package.json | 1 + .../details/table/filters-button/index.tsx | 123 ++++++++++++++++++ frontend/yarn.lock | 10 ++ 3 files changed, 134 insertions(+) create mode 100644 frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx diff --git a/frontend/package.json b/frontend/package.json index 42578d6c..49a6c296 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -60,6 +60,7 @@ "postcss": "8.4.21", "react": "18.2.0", "react-dom": "18.2.0", + "react-hook-form": "^7.48.2", "react-icons": "4.11.0", "react-map-gl": "7.1.6", "recharts": "^2.9.0", diff --git a/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx b/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx new file mode 100644 index 00000000..41954714 --- /dev/null +++ b/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx @@ -0,0 +1,123 @@ +import { useEffect, useMemo, useState } from 'react'; + +import { useForm } from 'react-hook-form'; + +import { xor } from 'lodash-es'; +import { Filter } from 'lucide-react'; + +import { Button } from '@/components/ui/button'; +import { Checkbox } from '@/components/ui/checkbox'; +import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; + +const ICON_CLASSNAMES = 'h-4 w-4 fill-black'; + +type FiltersButtonProps = { + field: string; + options: { + name: string; + value: string; + }[]; + values: string[]; + onChange: (field: string, values: string[]) => void; +}; + +type FormValues = { + filters: string[]; +}; + +const FiltersButton: React.FC = ({ field, options, values, onChange }) => { + const allFilterValues = useMemo(() => options.map(({ value }) => value), [options]); + + const [isFiltersOpen, setIsFiltersOpen] = useState(false); + + const { watch, setValue } = useForm({ + mode: 'onChange', + defaultValues: { + filters: values, + }, + }); + + const filters = watch('filters'); + + useEffect(() => { + if (xor(filters, values).length > 0) { + onChange(field, filters); + } + }, [field, filters, values, onChange]); + + const handleSelectAll = () => { + setValue('filters', allFilterValues); + }; + + const handleClearAll = () => { + setValue('filters', []); + }; + + const handleOnCheckedChange = (type, checked) => { + if (checked) { + setValue('filters', [...filters, type]); + } else { + setValue( + 'filters', + filters.filter((entry) => entry !== type) + ); + } + }; + + return ( +
+ + + + + +
+ + +
+
+
+ {options.map(({ name, value }) => { + return ( +
+ handleOnCheckedChange(value, v)} + /> + +
+ ); + })} +
+
+
+
+
+ ); +}; + +export default FiltersButton; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index ab42771d..09f331d6 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -10888,6 +10888,15 @@ __metadata: languageName: node linkType: hard +"react-hook-form@npm:^7.48.2": + version: 7.48.2 + resolution: "react-hook-form@npm:7.48.2" + peerDependencies: + react: ^16.8.0 || ^17 || ^18 + checksum: 39652d08f78f16e5234049ceeb794d8bcd4d146772aca99c6db8c5aea8926cd4a230d02098886a441074deefbc24ffcb5ed57bc7cb0009d950115f5b3e627f12 + languageName: node + linkType: hard + "react-icons@npm:4.11.0": version: 4.11.0 resolution: "react-icons@npm:4.11.0" @@ -11730,6 +11739,7 @@ __metadata: prettier-plugin-tailwindcss: 0.2.1 react: 18.2.0 react-dom: 18.2.0 + react-hook-form: ^7.48.2 react-icons: 4.11.0 react-map-gl: 7.1.6 recharts: ^2.9.0 From bf1c2b496a0c3ca89bd7e4360f802aa8ef569842 Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 08:59:37 +0000 Subject: [PATCH 03/12] Add useColumns hook for the global-regional table, using the new filters button --- .../src/containers/data-tool/constants.ts | 19 ++ .../tables/global-regional/useColumns.tsx | 169 ++++++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 frontend/src/containers/data-tool/constants.ts create mode 100644 frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx diff --git a/frontend/src/containers/data-tool/constants.ts b/frontend/src/containers/data-tool/constants.ts new file mode 100644 index 00000000..f634ca26 --- /dev/null +++ b/frontend/src/containers/data-tool/constants.ts @@ -0,0 +1,19 @@ +// ? This should be a Collection Type on Strapi, relation with location, which we would then pull from the API +export const LOCATION_TYPES_FILTER_OPTIONS = [ + { + name: 'Country', + value: 'country', + }, + { + name: 'Worldwide', + value: 'worldwide', + }, + { + name: 'HighSeas', + value: 'highseas', + }, + { + name: 'Region', + value: 'region', + }, +]; diff --git a/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx b/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx new file mode 100644 index 00000000..68369706 --- /dev/null +++ b/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx @@ -0,0 +1,169 @@ +import { useMemo } from 'react'; + +import { ColumnDef } from '@tanstack/react-table'; + +import { LOCATION_TYPES_FILTER_OPTIONS } from '@/containers/data-tool/constants'; +import FiltersButton from '@/containers/data-tool/content/details/table/filters-button'; +import HeaderItem from '@/containers/data-tool/content/details/table/header-item'; +import { cellFormatter } from '@/containers/data-tool/content/details/table/helpers'; +import SortingButton from '@/containers/data-tool/content/details/table/sorting-button'; + +export type GlobalRegionalTableColumns = { + location: string; + coverage: number; + locationType: string; + mpas: number; + oecms: number; + area: number; + fullyHighProtected: number; + highlyProtectedLFP: number; + globalContribution: number; +}; + +type UseColumnsProps = { + filters: { [key: string]: string[] }; + onFiltersChange: (field: string, values: string[]) => void; +}; + +const useColumns = ({ filters, onFiltersChange }: UseColumnsProps) => { + const columns: ColumnDef[] = useMemo(() => { + return [ + { + accessorKey: 'location', + header: 'Location', + cell: ({ row }) => { + const { location } = row.original; + return {location}; + }, + }, + { + accessorKey: 'coverage', + header: ({ column }) => ( + + + Coverage + + ), + cell: ({ row }) => { + const { coverage: value } = row.original; + if (!value) return <>—; + + const formattedCoverage = cellFormatter.percentage(value); + + return ( + + {formattedCoverage} + % + + ); + }, + }, + { + accessorKey: 'locationType', + header: ({ column }) => ( + + + Location type + + ), + cell: ({ row }) => { + const { locationType: value } = row.original; + const formattedValue = cellFormatter.capitalize(value); + return <>{formattedValue}; + }, + }, + { + accessorKey: 'mpas', + header: ({ column }) => ( + + + MPAs + + ), + }, + { + accessorKey: 'oecms', + header: ({ column }) => ( + + + OECMs + + ), + }, + { + accessorKey: 'area', + header: ({ column }) => ( + + + Area + + ), + cell: ({ row }) => { + const { area: value } = row.original; + const formattedValue = cellFormatter.area(value); + return ( + + {formattedValue} km2 + + ); + }, + }, + { + accessorKey: 'fullyHighProtected', + header: ({ column }) => ( + + + Fully/Highly Protected + + ), + cell: ({ row }) => { + const { fullyHighProtected: value } = row.original; + if (!value) return <>No data; + const formattedValue = cellFormatter.percentage(value); + return {formattedValue}%; + }, + }, + { + accessorKey: 'highlyProtectedLFP', + header: ({ column }) => ( + + + Highly Protected LFP + + ), + cell: ({ row }) => { + const { highlyProtectedLFP: value } = row.original; + if (!value) return <>No data; + const formattedValue = cellFormatter.percentage(value); + return {formattedValue}%; + }, + }, + { + accessorKey: 'globalContribution', + header: ({ column }) => ( + + + Global contribution + + ), + cell: ({ row }) => { + const { globalContribution: value } = row.original; + if (!value) return <>No data; + const formattedValue = cellFormatter.percentage(value); + return {formattedValue}%; + }, + }, + ]; + + return columns; + }, [filters, onFiltersChange]); + + return columns; +}; + +export default useColumns; From 381032e6c50a51f66fd82cf1067fa134350e9190 Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Fri, 10 Nov 2023 09:48:24 +0000 Subject: [PATCH 04/12] Global/Regional table now filterable --- .../tables/global-regional/columns.tsx | 142 ------------------ .../details/tables/global-regional/index.tsx | 28 +++- 2 files changed, 25 insertions(+), 145 deletions(-) delete mode 100644 frontend/src/containers/data-tool/content/details/tables/global-regional/columns.tsx diff --git a/frontend/src/containers/data-tool/content/details/tables/global-regional/columns.tsx b/frontend/src/containers/data-tool/content/details/tables/global-regional/columns.tsx deleted file mode 100644 index 29cd0c0f..00000000 --- a/frontend/src/containers/data-tool/content/details/tables/global-regional/columns.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import { ColumnDef } from '@tanstack/react-table'; - -import HeaderItem from '@/containers/data-tool/content/details/table/header-item'; -import { cellFormatter } from '@/containers/data-tool/content/details/table/helpers'; -import SortingButton from '@/containers/data-tool/content/details/table/sorting-button'; - -export type GlobalRegionalTableColumns = { - location: string; - coverage: number; - locationType: string; - mpas: number; - oecms: number; - area: number; - fullyHighProtected: number; - highlyProtectedLFP: number; - globalContribution: number; -}; - -const columns: ColumnDef[] = [ - { - accessorKey: 'location', - header: 'Location', - cell: ({ row }) => { - const { location } = row.original; - return {location}; - }, - }, - { - accessorKey: 'coverage', - header: ({ column }) => ( - - - Coverage - - ), - cell: ({ row }) => { - const { coverage: value } = row.original; - if (!value) return <>—; - - const formattedCoverage = cellFormatter.percentage(value); - - return ( - - {formattedCoverage} - % - - ); - }, - }, - { - accessorKey: 'locationType', - header: 'Location type', - cell: ({ row }) => { - const { locationType: value } = row.original; - const formattedValue = cellFormatter.capitalize(value); - return <>{formattedValue}; - }, - }, - { - accessorKey: 'mpas', - header: ({ column }) => ( - - - MPAs - - ), - }, - { - accessorKey: 'oecms', - header: ({ column }) => ( - - - OECMs - - ), - }, - { - accessorKey: 'area', - header: ({ column }) => ( - - - Area - - ), - cell: ({ row }) => { - const { area: value } = row.original; - const formattedValue = cellFormatter.area(value); - return ( - - {formattedValue} km2 - - ); - }, - }, - { - accessorKey: 'fullyHighProtected', - header: ({ column }) => ( - - - Fully/Highly Protected - - ), - cell: ({ row }) => { - const { fullyHighProtected: value } = row.original; - if (!value) return <>No data; - const formattedValue = cellFormatter.percentage(value); - return {formattedValue}%; - }, - }, - { - accessorKey: 'highlyProtectedLFP', - header: ({ column }) => ( - - - Highly Protected LFP - - ), - cell: ({ row }) => { - const { highlyProtectedLFP: value } = row.original; - if (!value) return <>No data; - const formattedValue = cellFormatter.percentage(value); - return {formattedValue}%; - }, - }, - { - accessorKey: 'globalContribution', - header: ({ column }) => ( - - - Global contribution - - ), - cell: ({ row }) => { - const { globalContribution: value } = row.original; - if (!value) return <>No data; - const formattedValue = cellFormatter.percentage(value); - return {formattedValue}%; - }, - }, -]; - -export default columns; diff --git a/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx b/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx index 6224765e..63c308cf 100644 --- a/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx +++ b/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx @@ -1,9 +1,10 @@ -import { useMemo } from 'react'; +import { useMemo, useState } from 'react'; import { useAtomValue } from 'jotai'; import Table from '@/containers/data-tool/content/details/table'; -import columns from '@/containers/data-tool/content/details/tables/global-regional/columns'; +// import columns from '@/containers/data-tool/content/details/tables/global-regional/columns'; +import useColumns from '@/containers/data-tool/content/details/tables/global-regional/useColumns'; import { locationAtom } from '@/store/location'; import { useGetLocations } from '@/types/generated/location'; import type { LocationListResponseDataItem } from '@/types/generated/strapi.schemas'; @@ -13,6 +14,17 @@ const DATA_YEAR = 2023; const GlobalRegionalTable: React.FC = () => { const location = useAtomValue(locationAtom); + const [filters, setFilters] = useState({ + locationType: ['country', 'worldwide', 'highseas', 'region'], + }); + + const handleOnFiltersChange = (field, values) => { + setFilters({ ...filters, [field]: values }); + }; + + const columns = useColumns({ filters, onFiltersChange: handleOnFiltersChange }); + // console.log(columns); + // Get worldwide data in order to calculate contributions per location const { data: globalData }: { data: LocationListResponseDataItem[] } = useGetLocations( { @@ -120,7 +132,7 @@ const GlobalRegionalTable: React.FC = () => { }, [globalData]); // Calculate table data - const tableData = useMemo(() => { + const parsedData = useMemo(() => { return locationsData.map(({ attributes: location }) => { // Base stats needed for calculations const coverageStats = location?.protection_coverage_stats?.data; @@ -186,6 +198,16 @@ const GlobalRegionalTable: React.FC = () => { }); }, [globalStats, locationsData]); + const tableData = useMemo(() => { + const filteredData = parsedData.filter((item) => { + for (const key in filters) { + return filters[key].includes(item[key]); + } + return true; + }); + return filteredData; + }, [filters, parsedData]); + return ; }; From 602552e2726ba35b28f65e77581a006f0ea42c88 Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 08:54:57 +0000 Subject: [PATCH 05/12] Fixissue with data tool tables showing '0' when there is no data --- .../src/containers/data-tool/content/details/table/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/containers/data-tool/content/details/table/index.tsx b/frontend/src/containers/data-tool/content/details/table/index.tsx index 7020d445..dc45881f 100644 --- a/frontend/src/containers/data-tool/content/details/table/index.tsx +++ b/frontend/src/containers/data-tool/content/details/table/index.tsx @@ -31,7 +31,7 @@ const DataToolTable = ({ columns, data }) => { getSortedRowModel: getSortedRowModel(), }); - const hasData = table.getRowModel().rows?.length; + const hasData = table.getRowModel().rows?.length > 0; const firstColumn = columns[0]; const lastColumn = columns[columns.length - 1]; From 8b6b62e0a060411c6198befe455f650071a5939c Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 09:05:03 +0000 Subject: [PATCH 06/12] Fix linting issues --- .../data-tool/content/details/table/sorting-button/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/containers/data-tool/content/details/table/sorting-button/index.tsx b/frontend/src/containers/data-tool/content/details/table/sorting-button/index.tsx index 4eb2f419..9de2c95e 100644 --- a/frontend/src/containers/data-tool/content/details/table/sorting-button/index.tsx +++ b/frontend/src/containers/data-tool/content/details/table/sorting-button/index.tsx @@ -2,7 +2,7 @@ import { Column } from '@tanstack/react-table'; import { ArrowDownNarrowWide, ArrowUpNarrowWide, ArrowUpDown } from 'lucide-react'; import { Button } from '@/components/ui/button'; -import { GlobalRegionalTableColumns } from '@/containers/data-tool/content/details/tables/global-regional/columns'; +import { GlobalRegionalTableColumns } from '@/containers/data-tool/content/details/tables/global-regional/useColumns'; const ICON_CLASSNAMES = 'h-4 w-4'; From c3e2effb661699bd6e5cb455928247f5ea5ba980 Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 09:07:55 +0000 Subject: [PATCH 07/12] Remove unnecessary return from useColumns --- .../content/details/tables/global-regional/useColumns.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx b/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx index 68369706..ab942f73 100644 --- a/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx +++ b/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx @@ -159,8 +159,6 @@ const useColumns = ({ filters, onFiltersChange }: UseColumnsProps) => { }, }, ]; - - return columns; }, [filters, onFiltersChange]); return columns; From 23c335f5987812ffbfdf9a202c71bf9c3330cfb2 Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 09:10:26 +0000 Subject: [PATCH 08/12] Align DataTool filter/sorting buttons better --- .../details/table/filters-button/index.tsx | 2 +- .../details/table/sorting-button/index.tsx | 22 ++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx b/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx index 41954714..4de8b1c9 100644 --- a/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx +++ b/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx @@ -68,7 +68,7 @@ const FiltersButton: React.FC = ({ field, options, values, o
- diff --git a/frontend/src/containers/data-tool/content/details/table/sorting-button/index.tsx b/frontend/src/containers/data-tool/content/details/table/sorting-button/index.tsx index 9de2c95e..f593088d 100644 --- a/frontend/src/containers/data-tool/content/details/table/sorting-button/index.tsx +++ b/frontend/src/containers/data-tool/content/details/table/sorting-button/index.tsx @@ -4,6 +4,7 @@ import { ArrowDownNarrowWide, ArrowUpNarrowWide, ArrowUpDown } from 'lucide-reac import { Button } from '@/components/ui/button'; import { GlobalRegionalTableColumns } from '@/containers/data-tool/content/details/tables/global-regional/useColumns'; +const BUTTON_CLASSNAMES = '-ml-4'; const ICON_CLASSNAMES = 'h-4 w-4'; type SortingButtonProps = { @@ -16,19 +17,34 @@ const SortingButton: React.FC = ({ column }) => { return ( <> {!isSorted && ( - )} {isSorted === 'asc' && ( - )} {isSorted === 'desc' && ( - From 5c887d789f40d61611046543de2e48621db4c54d Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 09:54:16 +0000 Subject: [PATCH 09/12] Add 'Please select at least one option' error to the data-table filters --- .../data-tool/content/details/table/filters-button/index.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx b/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx index 4de8b1c9..d9d1a8e2 100644 --- a/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx +++ b/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx @@ -64,6 +64,8 @@ const FiltersButton: React.FC = ({ field, options, values, o } }; + const noFiltersSelected = filters.length === 0; + return (
@@ -114,6 +116,9 @@ const FiltersButton: React.FC = ({ field, options, values, o })}
+ {noFiltersSelected && ( +
Please, select at least one option
+ )}
From 2e88e64fed6ec0da7022341d3d82ec0f3a39063c Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 10:10:00 +0000 Subject: [PATCH 10/12] Remove unnecessary import in global-regional table --- .../data-tool/content/details/tables/global-regional/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx b/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx index 63c308cf..a3758010 100644 --- a/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx +++ b/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx @@ -3,7 +3,6 @@ import { useMemo, useState } from 'react'; import { useAtomValue } from 'jotai'; import Table from '@/containers/data-tool/content/details/table'; -// import columns from '@/containers/data-tool/content/details/tables/global-regional/columns'; import useColumns from '@/containers/data-tool/content/details/tables/global-regional/useColumns'; import { locationAtom } from '@/store/location'; import { useGetLocations } from '@/types/generated/location'; From 0f4c279ff58fa05477349d76b8b5684299a8d1fc Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 10:27:58 +0000 Subject: [PATCH 11/12] Fix issue with filters SelectAll button not working --- .../content/details/table/filters-button/index.tsx | 7 +++++-- .../content/details/tables/global-regional/useColumns.tsx | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx b/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx index d9d1a8e2..8905a113 100644 --- a/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx +++ b/frontend/src/containers/data-tool/content/details/table/filters-button/index.tsx @@ -40,10 +40,13 @@ const FiltersButton: React.FC = ({ field, options, values, o const filters = watch('filters'); useEffect(() => { - if (xor(filters, values).length > 0) { + const filtersChanged = xor(filters, values).length > 0; + const allFiltersSelected = filters.length === allFilterValues.length; + + if (filtersChanged || allFiltersSelected) { onChange(field, filters); } - }, [field, filters, values, onChange]); + }, [field, filters, values, onChange, allFilterValues.length]); const handleSelectAll = () => { setValue('filters', allFilterValues); diff --git a/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx b/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx index ab942f73..f0b3a404 100644 --- a/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx +++ b/frontend/src/containers/data-tool/content/details/tables/global-regional/useColumns.tsx @@ -159,7 +159,9 @@ const useColumns = ({ filters, onFiltersChange }: UseColumnsProps) => { }, }, ]; - }, [filters, onFiltersChange]); + // ! If we add dependencies, the columns will re-render and the popovers will close on updates / act funny + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); return columns; }; From 35fe5b6a6e2af92f713885f1858c1ed4f98be14a Mon Sep 17 00:00:00 2001 From: Simao Rodrigues Date: Mon, 13 Nov 2023 11:57:44 +0000 Subject: [PATCH 12/12] Remove commented out comment + add note for revision --- .../data-tool/content/details/tables/global-regional/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx b/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx index a3758010..420adc32 100644 --- a/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx +++ b/frontend/src/containers/data-tool/content/details/tables/global-regional/index.tsx @@ -14,6 +14,7 @@ const GlobalRegionalTable: React.FC = () => { const location = useAtomValue(locationAtom); const [filters, setFilters] = useState({ + // ! This shouldn't be hardcoded. The setup needs to be able to work the same without any default filters here. locationType: ['country', 'worldwide', 'highseas', 'region'], }); @@ -22,7 +23,6 @@ const GlobalRegionalTable: React.FC = () => { }; const columns = useColumns({ filters, onFiltersChange: handleOnFiltersChange }); - // console.log(columns); // Get worldwide data in order to calculate contributions per location const { data: globalData }: { data: LocationListResponseDataItem[] } = useGetLocations(