Skip to content

Commit

Permalink
Merge pull request #44 from Vizzuality/table-design-data
Browse files Browse the repository at this point in the history
[SKY30-89] Fetch data to use in the table
  • Loading branch information
agnlez authored Nov 8, 2023
2 parents f6fd73a + d5b40e4 commit 43d0abc
Show file tree
Hide file tree
Showing 7 changed files with 327 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const DataToolDetails: React.FC = () => {
}, [location]);

return (
<div className="absolute h-full w-full overflow-scroll bg-white px-4 py-4 md:px-6">
<div className="overflow-none absolute h-full w-full bg-white px-4 py-4 md:px-6">
<div className="mb-8 flex gap-8 md:justify-between">
<span className="max-w-lg">
<h2 className="text-4xl font-extrabold">{table.title}</h2>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { PropsWithChildren } from 'react';

const HeaderItem: React.FC<PropsWithChildren> = ({ children }) => {
return <span className="flex items-center gap-0">{children}</span>;
};

export default HeaderItem;
19 changes: 19 additions & 0 deletions frontend/src/containers/data-tool/content/details/table/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { format } from 'd3-format';

const percentage = (value: number) => {
return format(',.2r')(value) == '0.0' ? '0' : format(',.2r')(value);
};

const area = (value: number) => {
return format(',.2r')(value);
};

const capitalize = (value: string) => {
return value.charAt(0).toUpperCase() + value.slice(1);
};

export const cellFormatter = {
percentage,
area,
capitalize,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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';

const ICON_CLASSNAMES = 'h-4 w-4';

type SortingButtonProps = {
column: Column<GlobalRegionalTableColumns, unknown>;
};

const SortingButton: React.FC<SortingButtonProps> = ({ column }) => {
const isSorted = column.getIsSorted();

return (
<>
{!isSorted && (
<Button size="icon" variant="ghost" onClick={() => column.toggleSorting(false)}>
<span className="sr-only">Sort ascending</span>
<ArrowUpDown className={ICON_CLASSNAMES} aria-hidden />
</Button>
)}
{isSorted === 'asc' && (
<Button size="icon" variant="ghost" onClick={() => column.toggleSorting(true)}>
<span className="sr-only">Sort descending</span>
<ArrowDownNarrowWide className={ICON_CLASSNAMES} aria-hidden />
</Button>
)}
{isSorted === 'desc' && (
<Button size="icon" variant="ghost" onClick={() => column.clearSorting()}>
<span className="sr-only">Clear sorting</span>
<ArrowUpNarrowWide className={ICON_CLASSNAMES} aria-hidden />
</Button>
)}
</>
);
};

export default SortingButton;
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
import { format } from 'd3-format';
import { ColumnDef } from '@tanstack/react-table';

// ! type me
const columns = [
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<GlobalRegionalTableColumns>[] = [
{
accessorKey: 'location',
header: 'Location',
Expand All @@ -12,13 +27,21 @@ const columns = [
},
{
accessorKey: 'coverage',
header: 'Coverage',
header: ({ column }) => (
<HeaderItem>
<SortingButton column={column} />
Coverage
</HeaderItem>
),
cell: ({ row }) => {
const { coverage: value } = row.original;
if (!value) return <>&mdash;</>;

const formattedCoverage = cellFormatter.percentage(value);

return (
<span className="text-4xl font-bold">
{value}
{formattedCoverage}
<span className="text-xs">%</span>
</span>
);
Expand All @@ -27,21 +50,41 @@ const columns = [
{
accessorKey: 'locationType',
header: 'Location type',
cell: ({ row }) => {
const { locationType: value } = row.original;
const formattedValue = cellFormatter.capitalize(value);
return <>{formattedValue}</>;
},
},
{
accessorKey: 'mpas',
header: 'MPAs',
header: ({ column }) => (
<HeaderItem>
<SortingButton column={column} />
MPAs
</HeaderItem>
),
},
{
accessorKey: 'oecms',
header: 'OECMs',
header: ({ column }) => (
<HeaderItem>
<SortingButton column={column} />
OECMs
</HeaderItem>
),
},
{
accessorKey: 'area',
header: 'Area',
header: ({ column }) => (
<HeaderItem>
<SortingButton column={column} />
Area
</HeaderItem>
),
cell: ({ row }) => {
const { area: value } = row.original;
const formattedValue = format(',.2r')(value);
const formattedValue = cellFormatter.area(value);
return (
<span>
{formattedValue} km<sup>2</sup>
Expand All @@ -51,44 +94,47 @@ const columns = [
},
{
accessorKey: 'fullyHighProtected',
header: 'Fully/Highly Protected',
header: ({ column }) => (
<HeaderItem>
<SortingButton column={column} />
Fully/Highly Protected
</HeaderItem>
),
cell: ({ row }) => {
const { fullyHighProtected: value } = row.original;
if (!value) return <>No data</>;
return (
<>
{value}
<span className="text-xs">%</span>
</>
);
const formattedValue = cellFormatter.percentage(value);
return <span className="text-xs">{formattedValue}%</span>;
},
},
{
accessorKey: 'highlyProtectedLFP',
header: 'Highly Protected LFP',
header: ({ column }) => (
<HeaderItem>
<SortingButton column={column} />
Highly Protected LFP
</HeaderItem>
),
cell: ({ row }) => {
const { highlyProtectedLFP: value } = row.original;
if (!value) return <>No data</>;
return (
<>
{value}
<span className="text-xs">%</span>
</>
);
const formattedValue = cellFormatter.percentage(value);
return <span className="text-xs">{formattedValue}%</span>;
},
},
{
accessorKey: 'globalContribution',
header: 'Global contribution',
header: ({ column }) => (
<HeaderItem>
<SortingButton column={column} />
Global contribution
</HeaderItem>
),
cell: ({ row }) => {
const { globalContribution: value } = row.original;
if (!value) return <>No data</>;
return (
<>
{value}
<span className="text-xs">%</span>
</>
);
const formattedValue = cellFormatter.percentage(value);
return <span className="text-xs">{formattedValue}%</span>;
},
},
];
Expand Down
Loading

0 comments on commit 43d0abc

Please sign in to comment.