Skip to content

Commit

Permalink
Merge pull request #2529 from NDLANO/feat/delayed-query
Browse files Browse the repository at this point in the history
feat: introduce a delayed query helper and use it in combobox queries.
  • Loading branch information
Jonas-C authored Oct 17, 2024
2 parents c20a8f4 + 9b9fe24 commit ce62611
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { getArticle } from "../../../../modules/article/articleApi";
import { useArticleSearch } from "../../../../modules/article/articleQueries";
import { plainTextToEditorValue, editorValueToPlainText } from "../../../../util/articleContentConverter";
import { routes } from "../../../../util/routeHelpers";
import useDebounce from "../../../../util/useDebounce";
import { usePaginatedQuery } from "../../../../util/usePaginatedQuery";
import { GenericComboboxInput, GenericComboboxItemContent } from "../../../abstractions/Combobox";
import { GenericSearchCombobox } from "../../../Form/GenericSearchCombobox";
import { FormField } from "../../../FormField";
Expand Down Expand Up @@ -82,10 +82,7 @@ const DisclaimerForm = ({ initialData, onOpenChange, onSave }: DisclaimerFormPro
const initialValues = useMemo(() => toInitialValues(initialData), [initialData]);
const initialErrors = useMemo(() => validateFormik(initialValues, rules, t), [initialValues, t]);
const [selectedArticle, setSelectedArticle] = useState<IArticleV2 | IArticleSummaryV2 | undefined>(undefined);

const [query, setQuery] = useState("");
const [page, setPage] = useState(1);
const delayedQuery = useDebounce(query, 300);
const { query, delayedQuery, setQuery, page, setPage } = usePaginatedQuery();

const searchQuery = useArticleSearch({ query: delayedQuery, page: page }, { placeholderData: (prev) => prev });

Expand Down
6 changes: 2 additions & 4 deletions src/containers/ArticlePage/components/ConceptsField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { FormContent } from "../../../components/FormikForm";
import { postSearchConcepts } from "../../../modules/concept/conceptApi";
import { useSearchConcepts } from "../../../modules/concept/conceptQueries";
import { routes } from "../../../util/routeHelpers";
import useDebounce from "../../../util/useDebounce";
import { usePaginatedQuery } from "../../../util/usePaginatedQuery";
import { ArticleFormType } from "../../FormikForm/articleFormHooks";

const StyledList = styled("ul", {
Expand All @@ -35,9 +35,7 @@ interface Props {
}

const ConceptsField = ({ field, form }: Props) => {
const [query, setQuery] = useState("");
const [page, setPage] = useState(1);
const delayedQuery = useDebounce(query, 300);
const { query, delayedQuery, setQuery, page, setPage } = usePaginatedQuery();
const { t, i18n } = useTranslation();
const [concepts, setConcepts] = useState<IConceptSummary[]>([]);

Expand Down
7 changes: 2 additions & 5 deletions src/containers/FrontpageEditPage/FrontpageArticleSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ import {
PopoverTrigger,
Text,
} from "@ndla/primitives";
import { styled } from "@ndla/styled-system/jsx";
import { IArticleSummaryV2 } from "@ndla/types-backend/article-api";
import { useComboboxTranslations } from "@ndla/ui";
import { extractArticleIds } from "./frontpageHelpers";
import { MenuWithArticle } from "./types";
import { GenericComboboxInput, GenericComboboxItemContent } from "../../components/abstractions/Combobox";
import Pagination from "../../components/abstractions/Pagination";
import { useArticleSearch } from "../../modules/article/articleQueries";
import useDebounce from "../../util/useDebounce";
import { usePaginatedQuery } from "../../util/usePaginatedQuery";

interface Props {
articleId?: number;
Expand All @@ -39,10 +38,8 @@ interface Props {
const FrontpageArticleSearch = ({ articleId, children, onChange }: Props) => {
const { t } = useTranslation();
const { values } = useFormikContext<MenuWithArticle>();
const [page, setPage] = useState(1);
const [query, setQuery] = useState("");
const [open, setOpen] = useState(false);
const delayedQuery = useDebounce(query);
const { query, setQuery, page, setPage, delayedQuery } = usePaginatedQuery();
const comboboxTranslations = useComboboxTranslations();

const articleQuery = useArticleSearch(
Expand Down
19 changes: 10 additions & 9 deletions src/containers/NdlaFilm/components/NdlaFilmArticle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { getArticle } from "../../../modules/article/articleApi";
import { useArticleSearch } from "../../../modules/article/articleQueries";
import { getUrnFromId, getIdFromUrn } from "../../../util/ndlaFilmHelpers";
import { routes } from "../../../util/routeHelpers";
import useDebounce from "../../../util/useDebounce";
import { usePaginatedQuery } from "../../../util/usePaginatedQuery";

interface Props {
fieldName: string;
Expand All @@ -28,15 +28,16 @@ const NdlaFilmArticle = ({ fieldName }: Props) => {
const { t } = useTranslation();
const [field, _, helpers] = useField<string | null>(fieldName);
const [selectedArticle, setSelectedArticle] = useState<undefined | IArticleV2>(undefined);
const [query, setQuery] = useState("");
const [page, setPage] = useState(1);
const delayedQuery = useDebounce(query, 300);
const { query, page, setPage, delayedQuery, setQuery } = usePaginatedQuery();

const searchQuery = useArticleSearch({
articleTypes: ["frontpage-article"],
page,
query: delayedQuery,
});
const searchQuery = useArticleSearch(
{
articleTypes: ["frontpage-article"],
page,
query: delayedQuery,
},
{ placeholderData: (prev) => prev },
);

useEffect(() => {
const initSelectedArticle = async () => {
Expand Down
7 changes: 2 additions & 5 deletions src/containers/Podcast/components/PodcastSeries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*
*/

import { useState } from "react";
import { useTranslation } from "react-i18next";
import styled from "@emotion/styled";
import { IconButtonV2 } from "@ndla/button";
Expand All @@ -20,7 +19,7 @@ import { GenericSearchCombobox } from "../../../components/Form/GenericSearchCom
import { FormField } from "../../../components/FormField";
import { useSearchSeries } from "../../../modules/audio/audioQueries";
import { toEditPodcastSeries } from "../../../util/routeHelpers";
import useDebounce from "../../../util/useDebounce";
import { usePaginatedQuery } from "../../../util/usePaginatedQuery";
import ElementImage from "../../FormikForm/components/ElementImage";

const StyledWrapper = styled.div`
Expand All @@ -44,9 +43,7 @@ const StyledSafeLink = styled(SafeLink)`

const PodcastSeries = () => {
const { t, i18n } = useTranslation();
const [query, setQuery] = useState("");
const [page, setPage] = useState(1);
const delayedQuery = useDebounce(query, 300);
const { query, delayedQuery, page, setPage, setQuery } = usePaginatedQuery();

const searchQuery = useSearchSeries({ query: delayedQuery, page: page }, { placeholderData: (prev) => prev });

Expand Down
34 changes: 34 additions & 0 deletions src/util/usePaginatedQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) 2024-present, NDLA.
*
* This source code is licensed under the GPLv3 license found in the
* LICENSE file in the root directory of this source tree.
*
*/

import { useEffect, useState } from "react";
import useDebounce from "./useDebounce";

interface UseDelayedQuery {
defaultQuery?: string;
defaultPage?: number;
debounceTime?: number;
}

export const usePaginatedQuery = ({ defaultQuery = "", defaultPage = 1, debounceTime = 300 }: UseDelayedQuery = {}) => {
const [query, setQuery] = useState(defaultQuery);
const [page, setPage] = useState(defaultPage);
const delayedQuery = useDebounce(query, debounceTime);

useEffect(() => {
setPage(1);
}, [delayedQuery]);

return {
page,
setPage,
query,
delayedQuery,
setQuery,
};
};

0 comments on commit ce62611

Please sign in to comment.