search.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { SWRResponse } from 'swr';
  2. import useSWRImmutable from 'swr/immutable';
  3. import { apiGet } from '~/client/util/apiv1-client';
  4. import { IFormattedSearchResult, SORT_AXIS, SORT_ORDER } from '~/interfaces/search';
  5. import { ITermNumberManagerUtil, useTermNumberManager } from './use-static-swr';
  6. export const useFullTextSearchTermManager = (isDisabled?: boolean) : SWRResponse<number, Error> & ITermNumberManagerUtil => {
  7. return useTermNumberManager(isDisabled === true ? null : 'fullTextSearchTermNumber');
  8. };
  9. export type ISearchConfigurations = {
  10. limit: number,
  11. offset?: number,
  12. sort?: SORT_AXIS,
  13. order?: SORT_ORDER,
  14. includeTrashPages?: boolean,
  15. includeUserPages?: boolean,
  16. }
  17. type ISearchConfigurationsFixed = {
  18. limit: number,
  19. offset: number,
  20. sort: SORT_AXIS,
  21. order: SORT_ORDER,
  22. includeTrashPages: boolean,
  23. includeUserPages: boolean,
  24. }
  25. export type ISearchConditions = ISearchConfigurationsFixed & {
  26. keyword: string | null,
  27. rawQuery: string,
  28. }
  29. const createSearchQuery = (keyword: string, includeTrashPages: boolean, includeUserPages: boolean): string => {
  30. let query = keyword;
  31. // pages included in specific path are not retrived when prefix is added
  32. if (!includeTrashPages) {
  33. query = `${query} -prefix:/trash`;
  34. }
  35. if (!includeUserPages) {
  36. query = `${query} -prefix:/user`;
  37. }
  38. return query;
  39. };
  40. export const useSWRxSearch = (
  41. keyword: string | null, nqName: string | null, configurations: ISearchConfigurations, disableTermManager = false,
  42. ): SWRResponse<IFormattedSearchResult, Error> & { conditions: ISearchConditions } => {
  43. const { data: termNumber } = useFullTextSearchTermManager(disableTermManager);
  44. const {
  45. limit, offset, sort, order, includeTrashPages, includeUserPages,
  46. } = configurations;
  47. const fixedConfigurations: ISearchConfigurationsFixed = {
  48. limit,
  49. offset: offset ?? 0,
  50. sort: sort ?? SORT_AXIS.RELATION_SCORE,
  51. order: order ?? SORT_ORDER.DESC,
  52. includeTrashPages: includeTrashPages ?? false,
  53. includeUserPages: includeUserPages ?? false,
  54. };
  55. const rawQuery = createSearchQuery(keyword ?? '', fixedConfigurations.includeTrashPages, fixedConfigurations.includeUserPages);
  56. const isKeywordValid = keyword != null && keyword.length > 0;
  57. const swrResult = useSWRImmutable(
  58. isKeywordValid ? ['/search', keyword, fixedConfigurations, termNumber] : null,
  59. (endpoint, keyword, fixedConfigurations) => {
  60. const {
  61. limit, offset, sort, order,
  62. } = fixedConfigurations;
  63. return apiGet(
  64. endpoint, {
  65. q: encodeURIComponent(rawQuery),
  66. nq: typeof nqName === 'string' ? encodeURIComponent(nqName) : null,
  67. limit,
  68. offset,
  69. sort,
  70. order,
  71. },
  72. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  73. ).then(result => result as IFormattedSearchResult);
  74. },
  75. );
  76. return {
  77. ...swrResult,
  78. conditions: {
  79. keyword,
  80. rawQuery,
  81. ...fixedConfigurations,
  82. },
  83. };
  84. };