Skip to content

Commit

Permalink
Merge pull request #723 from Vizzuality/LET-1314-fe-improve-search-re…
Browse files Browse the repository at this point in the history
…sults-page-performance

FE - Improve search results page performance
  • Loading branch information
barbara-chaves authored Jan 18, 2023
2 parents 850864e + 2d718ce commit 806e328
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 61 deletions.
19 changes: 11 additions & 8 deletions frontend/containers/discover-map/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ import { ChangeEvent, FC, useCallback, useMemo, useState } from 'react';
import { useForm } from 'react-hook-form';
import { FormattedMessage } from 'react-intl';

import omit from 'lodash-es/omit';

import { useRouter } from 'next/router';

import MapboxGLPlugin from '@vizzuality/layer-manager-plugin-mapboxgl';
import CartoProvider from '@vizzuality/layer-manager-provider-carto';
import { LayerManager, Layer } from '@vizzuality/layer-manager-react';

import { useLayers } from 'hooks/useLayers';

import { useQueryParams } from 'helpers/pages';

import Map from 'components/map';
import Controls from 'components/map/controls';
import ZoomControl from 'components/map/controls/zoom';
Expand All @@ -36,11 +34,11 @@ const cartoProvider = new CartoProvider();

export const DiscoverMap: FC<DiscoverMapProps> = ({ onSelectProjectPin }) => {
const { layers } = useLayers();
const { query } = useRouter();
const { page, sorting, search, ...filters } = useQueryParams();

const { projectsMap } = useProjectsMap({
...(omit(query, 'search') as ProjectMapParams),
'filter[full_text]': query.search as string,
...filters,
'filter[full_text]': search as string,
});

const [viewport, setViewport] = useState({});
Expand Down Expand Up @@ -122,7 +120,12 @@ export const DiscoverMap: FC<DiscoverMapProps> = ({ onSelectProjectPin }) => {
return (
<>
<div className="relative w-full h-full">
<Map bounds={bounds} viewport={viewport} onMapViewportChange={handleViewportChange}>
<Map
bounds={bounds}
viewport={viewport}
onMapViewportChange={handleViewportChange}
reuseMaps
>
{(map) => (
<>
<LayerManager
Expand Down
6 changes: 3 additions & 3 deletions frontend/containers/open-call-card/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const OpenCallCard: FC<OpenCallCardProps> = ({ className, openCall }: Ope
data: { instrument_type: allInstrumentTypes, impact: allImpacts },
} = useEnums();

const [picture, setPicture] = useState<string>(investor.picture?.small || placeholderPicture);
const [picture, setPicture] = useState<string>(investor?.picture?.small || placeholderPicture);
const [isFocusWithin, setIsFocusWithin] = useState<boolean>(false);

const link = `${Paths.OpenCall}/${slug}`;
Expand Down Expand Up @@ -172,13 +172,13 @@ export const OpenCallCard: FC<OpenCallCardProps> = ({ className, openCall }: Ope
})}
>
<span className="flex flex-row-reverse items-center gap-2">
<span className="text-sm">{investor.name}</span>
<span className="text-sm">{investor?.name}</span>
<span className="relative flex-shrink-0 w-8 overflow-hidden rounded-full aspect-square">
<Image
src={picture}
alt={intl.formatMessage(
{ defaultMessage: '{name} picture', id: 'rLzWx9' },
{ name: investor.name }
{ name: investor?.name }
)}
layout="fill"
objectFit="contain"
Expand Down
54 changes: 9 additions & 45 deletions frontend/layouts/discover-page/component.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React, { FC, useEffect, useMemo, useRef, useState } from 'react';

import { UseQueryResult } from 'react-query';

import cx from 'classnames';

import { useRouter } from 'next/router';
Expand All @@ -16,14 +14,13 @@ import SortingButtons, { SortingOrderType } from 'components/sorting-buttons';
import { SortingOptionKey } from 'components/sorting-buttons/types';
import { Paths, Queries } from 'enums';

import { useInvestorsList } from 'services/investors/investorsService';
import { useOpenCallsList } from 'services/open-call/open-call-service';
import { useProjectDevelopersList } from 'services/project-developers/projectDevelopersService';
import { useProjectsList } from 'services/projects/projectService';
import { PagedResponse } from 'services/types';

import Header from './header';
import { useSortingByOptions, SortingByTargetType, defaultSorting } from './helpers';
import {
useSortingByOptions,
SortingByTargetType,
defaultSorting,
useDiscoverData,
} from './helpers';
import Navigation from './navigation';
import { DiscoverPageLayoutProps } from './types';

Expand All @@ -45,41 +42,6 @@ export const DiscoverPageLayout: FC<DiscoverPageLayoutProps> = ({
const sortingOptions = useSortingByOptions(sortingOptionsTarget);
const queryParams = useQueryParams();

const queryOptions = { keepPreviousData: true };

const projects = useProjectsList(
{ ...queryParams, includes: ['project_developer', 'involved_project_developers'] },
queryOptions
);
const projectDevelopers = useProjectDevelopersList({ ...queryParams, perPage: 9 }, queryOptions);
const investors = useInvestorsList({ ...queryParams, perPage: 9 }, queryOptions);
const openCalls = useOpenCallsList({ ...queryParams, includes: ['investor'] }, queryOptions);

const stats = useMemo(
() => ({
projects: projects?.data?.meta?.total,
projectDevelopers: projectDevelopers?.data?.meta?.total,
investors: investors?.data?.meta?.total,
openCalls: openCalls?.data?.meta?.total,
}),
[projects, investors, projectDevelopers, openCalls]
);

const getCurrentData = (data: UseQueryResult<PagedResponse<any>>) => {
return {
data: data.data?.data,
meta: data.data?.meta,
loading: data.isLoading || data?.isFetching || data?.isRefetching,
};
};

const searchResult = useMemo(() => {
if (pathname.startsWith(Paths.Projects)) return getCurrentData(projects);
if (pathname.startsWith(Paths.ProjectDevelopers)) return getCurrentData(projectDevelopers);
if (pathname.startsWith(Paths.Investors)) return getCurrentData(investors);
if (pathname.startsWith(Paths.OpenCalls)) return getCurrentData(openCalls);
}, [pathname, projects, projectDevelopers, investors, openCalls]) || { data: [], meta: [] };

useEffect(() => {
const [sortBy, sortOrder]: [SortingOptionKey, SortingOrderType] = queryParams?.sorting?.split(
' '
Expand Down Expand Up @@ -110,9 +72,11 @@ export const DiscoverPageLayout: FC<DiscoverPageLayoutProps> = ({
onChange: handleSorting,
};

const { data, stats } = useDiscoverData();

const childrenWithProps = React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child, searchResult);
return React.cloneElement(child, data);
}

return child;
Expand Down
94 changes: 92 additions & 2 deletions frontend/layouts/discover-page/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { useMemo } from 'react';

import { useIntl } from 'react-intl';

import { compact } from 'lodash-es';
import { useRouter } from 'next/router';

import { compact, pickBy } from 'lodash-es';

import { useQueryParams } from 'helpers/pages';

import { SortingOptionType } from 'components/sorting-buttons';
import { SortingOptionKey, SortingOrderType } from 'components/sorting-buttons/types';
import { Queries } from 'enums';
import { Paths, Queries } from 'enums';

import { useInvestorsList } from 'services/investors/investorsService';
import { useOpenCallsList } from 'services/open-call/open-call-service';
import { useProjectDevelopersList } from 'services/project-developers/projectDevelopersService';
import { useProjectsList } from 'services/projects/projectService';

export type SortingByTargetType = Queries.Project;

Expand Down Expand Up @@ -47,3 +58,82 @@ export const useSortingByOptions = (target?: SortingByTargetType): SortingOption
...(sortingOptions[target] || []),
]) as SortingOptionType[];
};

const getPathParams = (
path: string,
pathname: string,
queryParams: { [key: string]: string | string[] }
) => {
const { page, sorting, search, ...filters } = queryParams;

const params: { [key: string]: string | string[] } = { page, search, ...filters };

if (pathname !== path) {
return {
...params,
fields: ['name'],
perPage: 1,
};
}

params.sorting = sorting;

if (pathname === Paths.Projects) {
return {
...params,
includes: ['project_developer', 'involved_project_developers'],
'fields[project_developer]': 'picture,name,contact_phone,contact_email',
'fields[involved_project_developers]': 'picture,name,contact_phone,contact_email',
};
}
if (pathname === Paths.Investors || pathname === Paths.ProjectDevelopers) {
return { ...params, perPage: 9 };
}
if (pathname === Paths.OpenCalls) {
return { ...params, includes: ['investor'], 'fields[investor]': 'picture,name,impacts' };
}
};

/** Hook to use the stats and the search results on Discover pages */
export const useDiscoverData = () => {
const queryParams = useQueryParams();
const { pathname } = useRouter();
const getParams = (path: string) => getPathParams(path, pathname, queryParams);
const queryOptions = { keepPreviousData: true };

const projects = useProjectsList(getParams(Paths.Projects), queryOptions);
const projectDevelopers = useProjectDevelopersList(
getParams(Paths.ProjectDevelopers),
queryOptions
);
const investors = useInvestorsList(getParams(Paths.Investors), queryOptions);
const openCalls = useOpenCallsList(getParams(Paths.OpenCalls), queryOptions);

const stats = useMemo(
() => ({
projects: projects?.data?.meta?.total,
projectDevelopers: projectDevelopers?.data?.meta?.total,
investors: investors?.data?.meta?.total,
openCalls: openCalls?.data?.meta?.total,
}),
[investors?.data, openCalls?.data, projectDevelopers?.data, projects?.data]
);

const data = useMemo(() => {
const allPathsData = {
[Paths.Projects]: projects,
[Paths.ProjectDevelopers]: projectDevelopers,
[Paths.Investors]: investors,
[Paths.OpenCalls]: openCalls,
};
const currData = allPathsData[pathname];

return {
data: currData.data?.data,
meta: currData.data?.meta,
loading: currData?.isLoading || currData?.isFetching || currData?.isRefetching,
};
}, [investors, openCalls, pathname, projectDevelopers, projects]);

return { stats, data };
};
5 changes: 3 additions & 2 deletions frontend/services/open-call/open-call-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { ErrorResponse, PagedRequest, PagedResponse, ResponseData } from 'servic

/** Get a paged list of openCalls */
export const getOpenCalls = async (params?: PagedRequest): Promise<PagedResponse<OpenCall>> => {
const { search, page, includes, fields, ...rest } = params || {};
const { search, page, includes, fields, perPage, ...rest } = params || {};

const config: AxiosRequestConfig = {
url: '/api/v1/open_calls',
Expand All @@ -39,6 +39,7 @@ export const getOpenCalls = async (params?: PagedRequest): Promise<PagedResponse
'filter[full_text]': search,
'page[number]': page,
'fields[open_call]': fields?.join(','),
'page[size]': perPage,
},
};

Expand All @@ -52,7 +53,7 @@ export function useOpenCallsList(
params?: PagedRequest,
options?: UseQueryOptions<PagedResponse<OpenCall>>
): UseQueryResult<PagedResponse<OpenCall>> & { openCalls: OpenCall[] } {
const query = useLocalizedQuery([Queries.ProjectList, params], () => getOpenCalls(params), {
const query = useLocalizedQuery([Queries.OpenCallList, params], () => getOpenCalls(params), {
...staticDataQueryOptions,
...options,
});
Expand Down
6 changes: 5 additions & 1 deletion frontend/services/projects/projectService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const Point: 'Point' = 'Point';

/** Get a paged list of projects */
export const getProjects = async (params?: PagedRequest): Promise<PagedResponse<Project>> => {
const { search, page, includes, fields, ...rest } = params || {};
const { search, page, includes, fields, perPage, ...rest } = params || {};

const config: AxiosRequestConfig = {
url: '/api/v1/projects',
Expand All @@ -32,6 +32,7 @@ export const getProjects = async (params?: PagedRequest): Promise<PagedResponse<
'filter[full_text]': search,
'page[number]': page,
'fields[project]': fields?.join(','),
'page[size]': perPage,
},
};

Expand Down Expand Up @@ -118,6 +119,9 @@ export const useProjectsMap = (
placeholderData: {
data: [],
},
keepPreviousData: true,
refetchOnMount: false,
refetchOnWindowFocus: false,
});

return useMemo(() => {
Expand Down

0 comments on commit 806e328

Please sign in to comment.