Przeglądaj źródła

add SearchPage2

Yuki Takei 4 lat temu
rodzic
commit
aa4a02ba2c

+ 2 - 2
packages/app/src/client/app.jsx

@@ -13,7 +13,7 @@ import { swrGlobalConfiguration } from '~/utils/swr-utils';
 import InAppNotificationPage from '../components/InAppNotification/InAppNotificationPage';
 import ErrorBoundary from '../components/ErrorBoudary';
 import Sidebar from '../components/Sidebar';
-import SearchPage from '../components/SearchPage';
+import { SearchPage } from '../components/SearchPage2';
 import TagsList from '../components/TagsList';
 import DisplaySwitcher from '../components/Page/DisplaySwitcher';
 import { defaultEditorOptions, defaultPreviewOptions } from '../components/PageEditor/OptionsSelector';
@@ -85,7 +85,7 @@ logger.info('unstated containers have been initialized');
 Object.assign(componentMappings, {
   'grw-sidebar-wrapper': <Sidebar />,
 
-  'search-page': <SearchPage crowi={appContainer} />,
+  'search-page': <SearchPage appContainer={appContainer} />,
   'all-in-app-notifications': <InAppNotificationPage />,
   'identical-path-page': <IdenticalPathPage />,
 

+ 1 - 1
packages/app/src/components/Page/RevisionLoader.jsx

@@ -126,7 +126,7 @@ LegacyRevisionLoader.propTypes = {
   revisionId: PropTypes.string.isRequired,
   lazy: PropTypes.bool,
   onRevisionLoaded: PropTypes.func,
-  highlightKeywords: PropTypes.string,
+  highlightKeywords: PropTypes.arrayOf(PropTypes.string),
 };
 
 const RevisionLoader = (props) => {

+ 4 - 3
packages/app/src/components/Page/RevisionRenderer.jsx

@@ -68,7 +68,8 @@ class LegacyRevisionRenderer extends React.PureComponent {
     // Separate keywords
     // - Surrounded by double quotation
     // - Split by both full-width and half-width spaces
-    [...keywords.match(/"[^"]+"|[^\u{20}\u{3000}]+/ug)].forEach((keyword, i) => {
+    // [...keywords.match(/"[^"]+"|[^\u{20}\u{3000}]+/ug)].forEach((keyword, i) => {
+    keywords.forEach((keyword, i) => {
       if (keyword === '') {
         return;
       }
@@ -138,7 +139,7 @@ class LegacyRevisionRenderer extends React.PureComponent {
     await interceptorManager.process('prePostProcess', context);
     context.parsedHTML = growiRenderer.postProcess(context.parsedHTML);
 
-    if (highlightKeywords != null) {
+    if (highlightKeywords != null || highlightKeywords.length === 0) {
       context.parsedHTML = this.getHighlightedBody(context.parsedHTML, highlightKeywords);
     }
     await interceptorManager.process('postPostProcess', context);
@@ -185,7 +186,7 @@ const RevisionRenderer = (props) => {
 RevisionRenderer.propTypes = {
   growiRenderer: PropTypes.instanceOf(GrowiRenderer).isRequired,
   markdown: PropTypes.string.isRequired,
-  highlightKeywords: PropTypes.string,
+  highlightKeywords: PropTypes.arrayOf(PropTypes.string),
   additionalClassName: PropTypes.string,
 };
 

+ 1 - 1
packages/app/src/components/SearchPage/SearchResultContent.tsx

@@ -44,7 +44,7 @@ const AdditionalMenuItems = (props: AdditionalMenuItemsProps): JSX.Element => {
 type Props ={
   appContainer: AppContainer,
   pageWithMeta : IPageWithMeta<IPageSearchMeta>,
-  highlightKeywords?: string,
+  highlightKeywords?: string[],
   showPageControlDropdown?: boolean,
 }
 

+ 36 - 0
packages/app/src/components/SearchPage2.tsx

@@ -0,0 +1,36 @@
+import React from 'react';
+
+import AppContainer from '~/client/services/AppContainer';
+
+import { useSWRxFullTextSearch } from '~/stores/search';
+
+import SearchPageBase from './SearchPage2/SearchPageBase';
+
+
+type Props = {
+  appContainer: AppContainer,
+}
+
+export const SearchPage = (props: Props): JSX.Element => {
+
+  const {
+    appContainer,
+  } = props;
+
+  const { data } = useSWRxFullTextSearch('sand', {
+    limit: 20,
+  });
+
+  return (
+    <SearchPageBase
+      appContainer={appContainer}
+      pages={data?.data}
+      SearchControl={() => (
+        <></>
+      )}
+      SearchResultListHead={() => (
+        <></>
+      )}
+    />
+  );
+};

+ 48 - 23
packages/app/src/components/SearchPage2/SearchPageBase.tsx

@@ -5,52 +5,77 @@ 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<IPageSearchMeta>[],
+
   SearchControl: React.FunctionComponent,
-  SearchResultList: React.FunctionComponent,
   SearchResultListHead: React.FunctionComponent,
 }
 
 const SearchPageBase: FC<Props> = (props: Props) => {
   const {
     appContainer,
-    SearchResultList, SearchControl, SearchResultListHead,
+    pages,
+    SearchControl, SearchResultListHead,
   } = props;
 
   const { data: isGuestUser } = useIsGuestUser();
 
-  const [highlightKeywords, setHightlightKeywords] = useState('');
-  const [selectedPageWithMeta, setSelectedPageWithMeta] = useState<IPageWithMeta<IPageSearchMeta> | null>(null);
+  // TODO get search keywords and split
+  // ref: RevisionRenderer
+  //   [...keywords.match(/"[^"]+"|[^\u{20}\u{3000}]+/ug)].forEach((keyword, i) => {
+  const [highlightKeywords, setHightlightKeywords] = useState<string[]>([]);
+  const [selectedPageWithMeta, setSelectedPageWithMeta] = useState<IPageWithMeta<IPageSearchMeta> | undefined>();
+
+  const isLoading = pages == null;
 
   return (
     <div className="content-main">
       <div className="search-result d-flex" id="search-result">
-        <div className="mw-0 flex-grow-1 flex-basis-0 border boder-gray search-result-list" id="search-result-list">
 
-          <SearchControl></SearchControl>
+        { isLoading && (
+          <div className="mw-0 flex-grow-1 flex-basis-0 m-5 text-muted text-center">
+            <i className="fa fa-2x fa-spinner fa-pulse mr-1"></i>
+          </div>
+        ) }
+
+        { !isLoading && (
+          <>
+            <div className="mw-0 flex-grow-1 flex-basis-0 border boder-gray search-result-list" id="search-result-list">
+
+              <SearchControl></SearchControl>
+
+              <div className="search-result-list-scroll">
+                <div className="d-flex align-items-center justify-content-between my-3 ml-4">
+                  <SearchResultListHead />
+                </div>
+                <div className="page-list px-md-4">
+                  <SearchResultList
+                    pages={pages}
+                    onPageSelected={page => setSelectedPageWithMeta(page)}
+                  />
+                </div>
+              </div>
 
-          <div className="search-result-list-scroll">
-            <div className="d-flex align-items-center justify-content-between my-3 ml-4">
-              <SearchResultListHead />
             </div>
-            <div className="page-list px-md-4">
-              <SearchResultList></SearchResultList>
+
+            <div className="mw-0 flex-grow-1 flex-basis-0 d-none d-lg-block search-result-content">
+              { selectedPageWithMeta != null && (
+                <SearchResultContent
+                  appContainer={appContainer}
+                  pageWithMeta={selectedPageWithMeta}
+                  highlightKeywords={highlightKeywords}
+                  showPageControlDropdown={isGuestUser}
+                />
+              )}
             </div>
-          </div>
-        </div>
-        <div className="mw-0 flex-grow-1 flex-basis-0 d-none d-lg-block search-result-content">
-          { selectedPageWithMeta != null && (
-            <SearchResultContent
-              appContainer={appContainer}
-              pageWithMeta={selectedPageWithMeta}
-              highlightKeywords={highlightKeywords}
-              showPageControlDropdown={isGuestUser}
-            />
-          )}
-        </div>
+          </>
+        ) }
+
       </div>
     </div>
   );