Skip to content

Commit

Permalink
refact(search): hook for query state
Browse files Browse the repository at this point in the history
  • Loading branch information
davidlougheed committed Sep 30, 2024
1 parent 441b1f8 commit 023efe4
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 30 deletions.
21 changes: 12 additions & 9 deletions src/js/components/Beacon/BeaconQueryUi.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import type { ReactNode } from 'react';
import { useEffect, useState, useCallback, useMemo } from 'react';
import { useAppSelector, useAppDispatch, useTranslationDefault, useQueryWithAuthIfAllowed } from '@/hooks';
import { Button, Card, Col, Form, Row, Space, Tooltip, Typography } from 'antd';
import { InfoCircleOutlined } from '@ant-design/icons';
import { useIsAuthenticated } from 'bento-auth-js';
import Filters from './Filters';
import BeaconSearchResults from './BeaconSearchResults';
import BeaconErrorMessage from './BeaconErrorMessage';
import VariantsForm from './VariantsForm';
import { makeBeaconQuery } from '@/features/beacon/beaconQuery.store';
import type { BeaconQueryPayload, FormFilter, FormValues, PayloadFilter, PayloadVariantsQuery } from '@/types/beacon';

import {
WRAPPER_STYLE,
FORM_ROW_GUTTERS,
Expand All @@ -18,9 +12,18 @@ import {
BUTTON_STYLE,
CARD_STYLES,
} from '@/constants/beaconConstants';

import { BOX_SHADOW } from '@/constants/overviewConstants';
import { makeBeaconQuery } from '@/features/beacon/beaconQuery.store';
import { useSearchQuery } from '@/features/search/hooks';
import { useAppSelector, useAppDispatch, useTranslationDefault, useQueryWithAuthIfAllowed } from '@/hooks';
import type { BeaconQueryPayload, FormFilter, FormValues, PayloadFilter, PayloadVariantsQuery } from '@/types/beacon';

import Loader from '@/components/Loader';
import Filters from './Filters';
import BeaconSearchResults from './BeaconSearchResults';
import BeaconErrorMessage from './BeaconErrorMessage';
import VariantsForm from './VariantsForm';

const { Text, Title } = Typography;
// TODOs
// example searches, either hardcoded or configurable
Expand Down Expand Up @@ -58,7 +61,7 @@ const BeaconQueryUi = () => {

const isFetchingBeaconConfig = useAppSelector((state) => state.beaconConfig.isFetchingBeaconConfig);
const beaconAssemblyIds = useAppSelector((state) => state.beaconConfig.beaconAssemblyIds);
const querySections = useAppSelector((state) => state.query.querySections);
const { querySections } = useSearchQuery();
const hasApiError = useAppSelector((state) => state.beaconQuery.hasApiError);
const apiErrorMessage = useAppSelector((state) => state.beaconQuery.apiErrorMessage);

Expand Down
5 changes: 3 additions & 2 deletions src/js/components/Search/MakeQueryOption.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { useCallback } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { Row, Col, Checkbox } from 'antd';

import OptionDescription from './OptionDescription';
import SelectOption from './SelectOption';

import { useSearchQuery } from '@/features/search/hooks';
import { useAppSelector, useTranslationCustom, useTranslationDefault } from '@/hooks';
import type { Field } from '@/types/search';
import { useLocation, useNavigate } from 'react-router-dom';
import { buildQueryParamsUrl, queryParamsWithoutKey } from '@/utils/search';

const MakeQueryOption = ({ queryField }: MakeQueryOptionProps) => {
Expand All @@ -19,7 +20,7 @@ const MakeQueryOption = ({ queryField }: MakeQueryOptionProps) => {
const { title, id, description, config, options } = queryField;

const { maxQueryParameters } = useAppSelector((state) => state.config);
const { queryParamCount, queryParams } = useAppSelector((state) => state.query);
const { queryParamCount, queryParams } = useSearchQuery();

const isChecked = id in queryParams;

Expand Down
9 changes: 4 additions & 5 deletions src/js/components/Search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import { makeGetKatsuPublic, setQueryParams } from '@/features/search/query.stor
import { useAppDispatch, useAppSelector, useTranslationCustom } from '@/hooks';
import { buildQueryParamsUrl } from '@/utils/search';

import type { QueryParams } from '@/types/search';
import Loader from '@/components/Loader';
import { useSearchQuery } from '@/features/search/hooks';
import type { QueryParams } from '@/types/search';

const checkQueryParamsEqual = (qp1: QueryParams, qp2: QueryParams): boolean => {
const qp1Keys = Object.keys(qp1);
Expand All @@ -32,7 +33,7 @@ const RoutedSearch = () => {
isFetchingData: isFetchingSearchData,
attemptedFieldsFetch,
attemptedFetch,
} = useAppSelector((state) => state.query);
} = useSearchQuery();

// TODO: allow disabling max query parameters for authenticated and authorized users when Katsu has AuthZ
// const maxQueryParametersRequired = useAppSelector((state) => state.config.maxQueryParametersRequired);
Expand Down Expand Up @@ -117,9 +118,7 @@ const SEARCH_SECTION_STYLE = { maxWidth: 1200 };
const Search = () => {
const t = useTranslationCustom();

const { isFetchingFields: isFetchingSearchFields, querySections: searchSections } = useAppSelector(
(state) => state.query
);
const { isFetchingFields: isFetchingSearchFields, querySections: searchSections } = useSearchQuery();

return isFetchingSearchFields ? (
<Loader />
Expand Down
20 changes: 11 additions & 9 deletions src/js/components/Search/SearchResults.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { useAppSelector } from '@/hooks';
import { useSearchQuery } from '@/features/search/hooks';
import SearchResultsPane from './SearchResultsPane';

const SearchResults = () => {
const isFetchingData = useAppSelector((state) => state.query.isFetchingData);
const biosampleCount = useAppSelector((state) => state.query.biosampleCount);
const biosampleChartData = useAppSelector((state) => state.query.biosampleChartData);
const experimentCount = useAppSelector((state) => state.query.experimentCount);
const experimentChartData = useAppSelector((state) => state.query.experimentChartData);
const individualCount = useAppSelector((state) => state.query.individualCount);
const individualMatches = useAppSelector((state) => state.query.individualMatches);
const message = useAppSelector((state) => state.query.message);
const {
isFetchingData,
biosampleCount,
biosampleChartData,
experimentCount,
experimentChartData,
individualCount,
individualMatches,
message,
} = useSearchQuery();

// existing code treats non-empty message as sign of insufficient data
const hasInsufficientData = message !== '';
Expand Down
5 changes: 3 additions & 2 deletions src/js/components/Search/SelectOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { useCallback, useMemo } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { Select } from 'antd';

import { useAppSelector, useTranslationCustom } from '@/hooks';
import { useTranslationCustom } from '@/hooks';
import { useSearchQuery } from '@/features/search/hooks';
import { buildQueryParamsUrl } from '@/utils/search';

const SELECT_STYLE: CSSProperties = { width: '100%' };
Expand All @@ -14,7 +15,7 @@ const SelectOption = ({ id, isChecked, options }: SelectOptionProps) => {
const { pathname } = useLocation();
const navigate = useNavigate();

const { queryParams } = useAppSelector((state) => state.query);
const { queryParams } = useSearchQuery();
const defaultValue = queryParams[id] || options[0];

const handleValueChange = useCallback(
Expand Down
7 changes: 4 additions & 3 deletions src/js/components/SiteSider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import type { MenuProps, SiderProps } from 'antd';
import Icon, { PieChartOutlined, SearchOutlined, SolutionOutlined } from '@ant-design/icons';

import BeaconSvg from '@/components/Beacon/BeaconSvg';
import { useAppSelector, useTranslationDefault } from '@/hooks';
import { useSearchQuery } from '@/features/search/hooks';
import { useTranslationDefault } from '@/hooks';
import { BentoRoute } from '@/types/routes';
import { buildQueryParamsUrl } from '@/utils/search';
import { getCurrentPage } from '@/utils/router';
import { BentoRoute } from '@/types/routes';

const { Sider } = Layout;

Expand All @@ -27,7 +28,7 @@ const SiteSider: React.FC<{
const navigate = useNavigate();
const location = useLocation();
const td = useTranslationDefault();
const queryParams = useAppSelector((state) => state.query.queryParams);
const { queryParams } = useSearchQuery();
const currentPage = getCurrentPage();

const handleMenuClick: OnClick = useCallback(
Expand Down
3 changes: 3 additions & 0 deletions src/js/features/search/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { useAppSelector } from '@/hooks';

export const useSearchQuery = () => useAppSelector((state) => state.query);

0 comments on commit 023efe4

Please sign in to comment.