import React, { forwardRef, ForwardRefRenderFunction, useEffect, useImperativeHandle, useRef, useState, } from 'react'; import { ISelectableAll } from '~/client/interfaces/selectable-all'; import AppContainer from '~/client/services/AppContainer'; import { IPageWithMeta } from '~/interfaces/page'; import { IPageSearchMeta } from '~/interfaces/search'; import { useIsGuestUser } from '~/stores/context'; import { SearchResultContent } from '../SearchPage/SearchResultContent'; import { SearchResultList } from '../SearchPage/SearchResultList'; type Props = { appContainer: AppContainer, pages?: IPageWithMeta[], onSelectedPagesByCheckboxesChanged?: (selectedCount: number, totalCount: number) => void, searchControl: React.ReactNode, searchResultListHead: React.ReactNode, searchPager: React.ReactNode, } const SearchPageBaseSubstance: ForwardRefRenderFunction = (props:Props, ref) => { const { appContainer, pages, onSelectedPagesByCheckboxesChanged, searchControl, searchResultListHead, searchPager, } = props; const searchResultListRef = useRef(null); const { data: isGuestUser } = useIsGuestUser(); // TODO get search keywords and split // ref: RevisionRenderer // [...keywords.match(/"[^"]+"|[^\u{20}\u{3000}]+/ug)].forEach((keyword, i) => { const [highlightKeywords, setHightlightKeywords] = useState([]); const [selectedPageIdsByCheckboxes] = useState>(new Set()); // const [allPageIds] = useState>(new Set()); const [selectedPageWithMeta, setSelectedPageWithMeta] = useState | undefined>(); // publish selectAll() useImperativeHandle(ref, () => ({ selectAll: () => { const instance = searchResultListRef.current; if (instance != null) { instance.selectAll(); } if (pages != null) { pages.forEach(page => selectedPageIdsByCheckboxes.add(page.pageData._id)); } }, deselectAll: () => { const instance = searchResultListRef.current; if (instance != null) { instance.deselectAll(); } selectedPageIdsByCheckboxes.clear(); }, })); const checkboxChangedHandler = (isChecked: boolean, pageId: string) => { if (pages == null || pages.length === 0) { return; } if (isChecked) { selectedPageIdsByCheckboxes.add(pageId); } else { selectedPageIdsByCheckboxes.delete(pageId); } if (onSelectedPagesByCheckboxesChanged != null) { onSelectedPagesByCheckboxesChanged(selectedPageIdsByCheckboxes.size, pages.length); } }; // select first item on load useEffect(() => { if (selectedPageWithMeta == null && pages != null && pages.length > 0) { setSelectedPageWithMeta(pages[0]); } }, [pages, selectedPageWithMeta]); // reset selectedPageIdsByCheckboxes useEffect(() => { if (pages == null) { return; } if (pages.length > 0) { selectedPageIdsByCheckboxes.clear(); } if (onSelectedPagesByCheckboxesChanged != null) { onSelectedPagesByCheckboxesChanged(selectedPageIdsByCheckboxes.size, pages.length); } }, [onSelectedPagesByCheckboxesChanged, pages, selectedPageIdsByCheckboxes]); const isLoading = pages == null; return (
{searchControl}
{ isLoading && (
) } { !isLoading && ( <>
{searchResultListHead}
setSelectedPageWithMeta(page)} onCheckboxChanged={checkboxChangedHandler} />
{searchPager}
) }
{ selectedPageWithMeta != null && ( )}
); }; export const SearchPageBase = forwardRef(SearchPageBaseSubstance);