SearchControl.tsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import React, { FC, useState } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import SearchPageForm from './SearchPageForm';
  4. import AppContainer from '../../client/services/AppContainer';
  5. import DeleteSelectedPageGroup from './DeleteSelectedPageGroup';
  6. import SearchOptionModal from './SearchOptionModal';
  7. import SortControl from './SortControl';
  8. import { CheckboxType, SORT_AXIS, SORT_ORDER } from '../../interfaces/search';
  9. type Props = {
  10. searchingKeyword: string,
  11. sort: SORT_AXIS,
  12. order: SORT_ORDER,
  13. appContainer: AppContainer,
  14. searchResultCount: number,
  15. selectAllCheckboxType: CheckboxType,
  16. onClickDeleteAllButton?: () => void
  17. onClickSelectAllCheckbox?: (nextSelectAllCheckboxType: CheckboxType) => void,
  18. excludeUserPages: boolean,
  19. excludeTrashPages: boolean,
  20. onSearchInvoked: (data: {keyword: string}) => boolean,
  21. onExcludeUserPagesSwitched?: () => void,
  22. onExcludeTrashPagesSwitched?: () => void,
  23. onChangeSortInvoked?: (nextSort: SORT_AXIS, nextOrder: SORT_ORDER) => void,
  24. }
  25. const SearchControl: FC <Props> = (props: Props) => {
  26. const [isFileterOptionModalShown, setIsFileterOptionModalShown] = useState(false);
  27. // Temporaly workaround for lint error
  28. // later needs to be fixed: SearchControl to typescript componet
  29. const SearchPageFormTypeAny : any = SearchPageForm;
  30. const { t } = useTranslation('');
  31. const { searchResultCount } = props;
  32. const switchExcludeUserPagesHandler = () => {
  33. if (props.onExcludeUserPagesSwitched != null) {
  34. props.onExcludeUserPagesSwitched();
  35. }
  36. };
  37. const switchExcludeTrashPagesHandler = () => {
  38. if (props.onExcludeTrashPagesSwitched != null) {
  39. props.onExcludeTrashPagesSwitched();
  40. }
  41. };
  42. const onChangeSortInvoked = (nextSort: SORT_AXIS, nextOrder:SORT_ORDER) => {
  43. if (props.onChangeSortInvoked != null) {
  44. props.onChangeSortInvoked(nextSort, nextOrder);
  45. }
  46. };
  47. const openSearchOptionModalHandler = () => {
  48. setIsFileterOptionModalShown(true);
  49. };
  50. const closeSearchOptionModalHandler = () => {
  51. setIsFileterOptionModalShown(false);
  52. };
  53. const onRetrySearchInvoked = () => {
  54. if (props.onSearchInvoked != null) {
  55. props.onSearchInvoked({ keyword: props.searchingKeyword });
  56. }
  57. };
  58. const rednerSearchOptionModal = () => {
  59. return (
  60. <SearchOptionModal
  61. isOpen={isFileterOptionModalShown || false}
  62. onClickFilteringSearchResult={onRetrySearchInvoked}
  63. onClose={closeSearchOptionModalHandler}
  64. onExcludeUserPagesSwitched={switchExcludeUserPagesHandler}
  65. onExcludeTrashPagesSwitched={switchExcludeTrashPagesHandler}
  66. excludeUserPages={props.excludeUserPages}
  67. excludeTrashPages={props.excludeTrashPages}
  68. />
  69. );
  70. };
  71. return (
  72. <div className="position-sticky fixed-top">
  73. <div className="search-page-nav d-flex py-3 align-items-center">
  74. <div className="flex-grow-1 mx-4">
  75. <SearchPageFormTypeAny
  76. keyword={props.searchingKeyword}
  77. appContainer={props.appContainer}
  78. onSearchFormChanged={props.onSearchInvoked}
  79. />
  80. </div>
  81. <div className="mr-4 d-flex">
  82. <SortControl
  83. sort={props.sort}
  84. order={props.order}
  85. onChangeSortInvoked={onChangeSortInvoked}
  86. />
  87. </div>
  88. </div>
  89. {/* TODO: replace the following elements deleteAll button , relevance button and include specificPath button component */}
  90. <div className="search-control d-flex align-items-center py-2 border-bottom border-gray">
  91. <div className="d-flex mr-auto ml-4">
  92. {/* Todo: design will be fixed in #80324. Function will be implemented in #77525 */}
  93. <DeleteSelectedPageGroup
  94. isSelectAllCheckboxDisabled={searchResultCount === 0}
  95. selectAllCheckboxType={props.selectAllCheckboxType}
  96. onClickDeleteAllButton={props.onClickDeleteAllButton}
  97. onClickSelectAllCheckbox={props.onClickSelectAllCheckbox}
  98. />
  99. </div>
  100. {/** filter option */}
  101. <div className="d-lg-none mr-4">
  102. <button
  103. type="button"
  104. className="btn"
  105. onClick={openSearchOptionModalHandler}
  106. >
  107. <i className="icon-equalizer"></i>
  108. </button>
  109. </div>
  110. <div className="d-none d-lg-flex align-items-center mr-4">
  111. <div className="border border-gray mr-3">
  112. <label className="px-3 py-2 mb-0 d-flex align-items-center text-secondary with-no-font-weight" htmlFor="flexCheckDefault">
  113. <input
  114. className="mr-2"
  115. type="checkbox"
  116. id="flexCheckDefault"
  117. onClick={switchExcludeUserPagesHandler}
  118. />
  119. {t('Include Subordinated Target Page', { target: '/user' })}
  120. </label>
  121. </div>
  122. <div className="border border-gray">
  123. <label className="px-3 py-2 mb-0 d-flex align-items-center text-secondary with-no-font-weight" htmlFor="flexCheckChecked">
  124. <input
  125. className="mr-2"
  126. type="checkbox"
  127. id="flexCheckChecked"
  128. onClick={switchExcludeTrashPagesHandler}
  129. />
  130. {t('Include Subordinated Target Page', { target: '/trash' })}
  131. </label>
  132. </div>
  133. </div>
  134. </div>
  135. {rednerSearchOptionModal()}
  136. </div>
  137. );
  138. };
  139. export default SearchControl;