Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] (feat): Inventory panel: Cost surface [MRXN23-303] #1463

Merged
merged 11 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions app/hooks/cost-surface/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { useQuery, QueryObserverOptions, useMutation } from 'react-query';

import { useSession } from 'next-auth/react';

import { CostSurface } from 'types/api/cost-surface';
import { Project } from 'types/api/project';

import { API } from 'services/api';
import UPLOADS from 'services/uploads';

export function useProjectCostSurfaces<T = CostSurface[]>(
pid: Project['id'],
params: { search?: string; sort?: string } = {},
queryOptions: QueryObserverOptions<CostSurface[], Error, T> = {}
) {
const { data: session } = useSession();

const mockData: CostSurface[] = [
{
id: 'b7454579-c48e-4e2f-8438-833280cb65d8',
name: 'Brazil 15 k Cost Surface',
isCustom: true,
scenarioUsageCount: 3,
},
{
id: 'rfjghhrtersdtbkjshfw',
name: 'Cost Surface Rwanda B',
isCustom: true,
scenarioUsageCount: 0,
},
{
id: '23275455HGVVCMSJHDFk',
name: 'Cost Surface Rwanda C',
isCustom: true,
scenarioUsageCount: 0,
},
];

return useQuery({
queryKey: ['cost-surfaces', pid],
queryFn: async () =>
API.request<CostSurface[]>({
method: 'GET',
// !TODO: change this to the correct endpoint
url: `/projects/${pid}/protected-areas`,
headers: {
Authorization: `Bearer ${session.accessToken}`,
},
params,
}).then(({ data }) => mockData),
enabled: Boolean(pid),
...queryOptions,
});
}

export function useEditProjectCostSurface() {
const { data: session } = useSession();

const editCostSurface = ({
costSurfaceId,
projectId,
body = {},
}: {
costSurfaceId: CostSurface['id'];
projectId: Project['id'];
body: Record<string, unknown>;
}) => {
// TODO: change this to the correct endpoint
return API.patch<CostSurface>(
`projects/${projectId}/cost-surfaces/${costSurfaceId}`,
{
...body,
},
{
headers: {
Authorization: `Bearer ${session.accessToken}`,
},
}
);
};

return useMutation(editCostSurface);
}

export function useUploadProjectCostSurface() {
const { data: session } = useSession();

const uploadProjectCostSurface = ({ id, data }: { id: CostSurface['id']; data: FormData }) => {
return UPLOADS.request({
method: 'POST',
// TODO: change this to the correct endpoint
url: `/projects/${id}/cost-surface/shapefile`,
data,
headers: {
Authorization: `Bearer ${session.accessToken}`,
'Content-Type': 'multipart/form-data',
},
});
};

return useMutation(uploadProjectCostSurface);
}
16 changes: 16 additions & 0 deletions app/hooks/cost-surface/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { AxiosRequestConfig } from 'axios';

export interface UseWDPACategoriesProps {
adminAreaId?: string;
customAreaId?: string;
scenarioId: string[] | string;
}

export interface UseSaveScenarioProtectedAreasProps {
requestConfig?: AxiosRequestConfig;
}

export interface SaveScenarioProtectedAreasProps {
data: unknown;
id: string[] | string;
}
2 changes: 1 addition & 1 deletion app/hooks/map/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export const LEGEND_LAYERS = {

return {
id: 'cost',
name: 'Cost surface',
name: options.cost.name,
type: 'gradient',
settingsManager: {
opacity: true,
Expand Down
1 change: 1 addition & 0 deletions app/hooks/map/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export interface UseLegend {
wdpaIucnCategories?: string[];
wdpaThreshold?: number;
cost?: {
name: string;
min: number;
max: number;
};
Expand Down
10 changes: 10 additions & 0 deletions app/layout/info/upload-cost-surface.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const UploadCostSurfaceInfoButtonContent = (): JSX.Element => {
return (
<div className="space-y-2.5 text-xs">
<h4 className="font-heading">List of supported file formats:</h4>
<p>Zipped: .shp (zipped shapefiles must include .shp, .shx, .dbf, and .prj files)</p>
</div>
);
};

export default UploadCostSurfaceInfoButtonContent;
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,16 @@ import { cn } from 'utils/cn';

import { HeaderItem } from './types';

const HeaderItem = ({
className,
text,
name,
columns,
sorting,
onClick,
}: HeaderItem): JSX.Element => {
const HeaderItem = ({ className, text, name, sorting, onClick }: HeaderItem): JSX.Element => {
const sortingMatches = /^(-?)(.+)$/.exec(sorting);
const sortField = sortingMatches[2];
const sortOrder = sortingMatches[1] === '-' ? 'desc' : 'asc';

const isActive = columns[name] === sortField;
const isActive = name === sortField;

const handleClick = useCallback(() => {
onClick(columns[name]);
}, [onClick, columns, name]);
onClick(name);
}, [onClick, name]);

return (
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ export type HeaderItem = {
className?: string;
text: string;
name: string;
columns: {
[key: string]: string;
};
sorting: string;
onClick?: (field: string) => void;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Checkbox from 'components/forms/checkbox';
import Loading from 'components/loading';
import { ScrollArea } from 'components/scroll-area';
import { cn } from 'utils/cn';

import HeaderItem from './header-item';
import RowItem from './row-item';
Expand Down Expand Up @@ -44,25 +45,24 @@ const InventoryTable = ({
onChange={onSelectAll}
/>
</th>
<th className="flex-1 pl-2">
<HeaderItem
text={'Name'}
name={'name'}
columns={columns}
sorting={sorting}
onClick={onSortChange}
/>
</th>
<th className="flex flex-1 justify-start py-2 pl-14">
<HeaderItem
className="justify-center"
text={'Type'}
name={'tag'}
columns={columns}
sorting={sorting}
onClick={onSortChange}
/>
</th>
{columns.map((column) => {
return (
<th
key={column.name}
className={cn({
'flex-1 pl-2': true,
[column.className]: !!column.className,
})}
>
<HeaderItem
text={column.text}
name={column.name}
sorting={sorting}
onClick={onSortChange}
/>
</th>
);
})}
</tr>
</thead>
<ScrollArea className="h-full">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const RowItem = ({
const { id, name, scenarios, tag, isVisibleOnMap, isCustom } = item;

return (
<tr key={id} className="align-top">
<tr key={id} className="flex w-full align-top">
<td className="pb-2 pr-1 pt-5">
<Checkbox
id={`select-${id}`}
Expand All @@ -32,7 +32,12 @@ const RowItem = ({
disabled={!isCustom}
/>
</td>
<td className="px-1 pb-2 pt-5">
<td
className={cn({
'flex flex-col px-1 pb-2 pt-5': true,
'w-52': tag,
})}
>
<span className="inline-flex">{name}</span>
<div className="mt-1.5 text-xs text-gray-300">
Currently in use in
Expand All @@ -42,16 +47,16 @@ const RowItem = ({
scenarios.
</div>
</td>
<td className="px-6 pb-2 pt-5 text-xs">
{tag && (
{tag && (
<td className="w-28 px-6 pb-2 pt-5 text-xs">
<div className="flex justify-center">
<span className="whitespace-nowrap rounded-full bg-yellow-600 bg-opacity-10 px-2 py-1 text-yellow-600">
{tag}
</span>
</div>
)}
</td>
<td className="pb-2 pl-1 pr-2 pt-5">
</td>
)}
<td className="w-22 ml-auto pb-2 pl-1 pr-2 pt-5">
<div className="flex gap-6">
<button type="button" onClick={() => onToggleSeeOnMap(id)}>
<Icon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ export type DataItem = {
id: string;
name: string;
scenarios: number;
tag: string;
tag?: string;
isVisibleOnMap: boolean;
isCustom: boolean;
isCustom?: boolean;
};

export type InventoryTable = {
loading: boolean;
data: DataItem[];
noDataMessage: string;
columns: {
[key: string]: string;
};
name: string;
text: string;
className?: string;
}[];
sorting: string;
selectedIds: string[];
onSortChange: (field: string) => void;
Expand Down
10 changes: 6 additions & 4 deletions app/layout/project/sidebar/project/inventory-panel/constants.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { NavigationInventoryTabs } from 'layout/project/navigation/types';

import CostSurfaceTable from './cost-surface';
import CostSurfaceInfo from './cost-surface/info';
import CostSurfaceTable from './cost-surfaces';
import CostSurfaceInfo from './cost-surfaces/info';
import CostSurfaceUploadModal from './cost-surfaces/modals/upload';
import FeaturesTable from './features';
import FeaturesInfo from './features/info';
import FeatureUploadModal from './features/modals/upload';
import ProtectedAreasTable from './protected-areas';
import ProtectedAreasFooter from './protected-areas/footer';
import { InventoryPanel } from './types';
import ProtectedAreasTable from './wdpas';
import ProtectedAreasFooter from './wdpas/footer';

export const INVENTORY_TABS = {
'protected-areas': {
Expand All @@ -22,6 +23,7 @@ export const INVENTORY_TABS = {
search: 'Search cost surfaces',
noData: 'No cost surfaces found.',
InfoComponent: CostSurfaceInfo,
UploadModalComponent: CostSurfaceUploadModal,
TableComponent: CostSurfaceTable,
},
features: {
Expand Down

This file was deleted.

This file was deleted.

Loading
Loading