Przeglądaj źródła

Merge branch 'master' into support/143856-bookmark-sidebar-rayout

satof3 2 lat temu
rodzic
commit
1ec9b840af

+ 8 - 2
apps/app/src/components/Navbar/GrowiNavbarBottom.tsx

@@ -1,4 +1,6 @@
-import React from 'react';
+import React, {
+  useCallback,
+} from 'react';
 
 import { useSearchModal } from '~/features/search/client/stores/search';
 import { useIsSearchPage } from '~/stores/context';
@@ -19,6 +21,10 @@ export const GrowiNavbarBottom = (): JSX.Element => {
   const { data: isSearchPage } = useIsSearchPage();
   const { open: openSearchModal } = useSearchModal();
 
+  const searchButtonClickHandler = useCallback(() => {
+    openSearchModal();
+  }, [openSearchModal]);
+
   return (
     <GroundGlassBar className={`
       ${styles['grw-navbar-bottom']}
@@ -54,7 +60,7 @@ export const GrowiNavbarBottom = (): JSX.Element => {
                 <a
                   role="button"
                   className="nav-link btn-lg"
-                  onClick={openSearchModal}
+                  onClick={searchButtonClickHandler}
                 >
                   <span className="material-symbols-outlined fs-2">search</span>
                 </a>

+ 1 - 0
apps/app/src/components/PageEditor/Preview.tsx

@@ -32,6 +32,7 @@ const Preview = (props: Props): JSX.Element => {
 
   return (
     <div
+      data-testid="page-editor-preview-body"
       className={`${moduleClass} ${fluidLayoutClass} ${pagePath === '/Sidebar' ? 'preview-sidebar' : ''}`}
       style={style}
     >

+ 1 - 1
apps/app/src/components/SavePageControls/GrantSelector/GrantSelector.tsx

@@ -171,7 +171,7 @@ export const GrantSelector = (props: Props): JSX.Element => {
           >
             {dropdownToggleLabelElm}
           </DropdownToggle>
-          <DropdownMenu container={openInModal ? '' : 'body'}>
+          <DropdownMenu data-testid="grw-grant-selector-dropdown-menu" container={openInModal ? '' : 'body'}>
             {dropdownMenuElems}
           </DropdownMenu>
         </UncontrolledDropdown>

+ 2 - 6
apps/app/src/components/SearchPage/SearchControl.tsx

@@ -7,8 +7,7 @@ import { useTranslation } from 'next-i18next';
 import { SORT_AXIS, SORT_ORDER } from '~/interfaces/search';
 import type { ISearchConditions, ISearchConfigurations } from '~/stores/search';
 
-import SearchForm from '../SearchForm';
-
+import { SearchModalTriggerinput } from './SearchModalTriggerinput';
 import SearchOptionModal from './SearchOptionModal';
 import SortControl from './SortControl';
 
@@ -88,11 +87,8 @@ const SearchControl = React.memo((props: Props): JSX.Element => {
     <div className="shadow-sm">
       <div className="grw-search-page-nav d-flex py-3 align-items-center">
         <div className="flex-grow-1 mx-4">
-          <SearchForm
-            isSearchServiceReachable={isSearchServiceReachable}
+          <SearchModalTriggerinput
             keywordOnInit={keyword}
-            disableIncrementalSearch
-            onSubmit={searchFormSubmittedHandler}
           />
         </div>
       </div>

+ 31 - 0
apps/app/src/components/SearchPage/SearchModalTriggerinput.tsx

@@ -0,0 +1,31 @@
+import React, {
+  useCallback,
+} from 'react';
+
+import { useSearchModal } from '../../features/search/client/stores/search';
+
+type Props = {
+  keywordOnInit: string,
+};
+
+export const SearchModalTriggerinput: React.FC<Props> = (props: Props) => {
+  const { keywordOnInit } = props;
+
+  const { open: openSearchModal } = useSearchModal();
+
+  const inputClickHandler = useCallback(() => {
+    openSearchModal(keywordOnInit);
+  }, [openSearchModal, keywordOnInit]);
+
+  return (
+    <div>
+      <input
+        className="form-control"
+        type="input"
+        value={keywordOnInit}
+        onClick={inputClickHandler}
+        readOnly
+      />
+    </div>
+  );
+};

+ 7 - 1
apps/app/src/features/search/client/components/SearchModal.tsx

@@ -50,9 +50,15 @@ const SearchModal = (): JSX.Element => {
 
   useEffect(() => {
     if (!searchModalData?.isOpened) {
+      return;
+    }
+    if (searchModalData?.searchKeyword == null) {
       setSearchKeyword('');
     }
-  }, [searchModalData?.isOpened]);
+    else {
+      setSearchKeyword(searchModalData.searchKeyword);
+    }
+  }, [searchModalData?.isOpened, searchModalData?.searchKeyword]);
 
   return (
     <Modal size="lg" isOpen={searchModalData?.isOpened ?? false} toggle={closeSearchModal} data-testid="search-modal">

+ 9 - 4
apps/app/src/features/search/client/stores/search.ts

@@ -1,13 +1,16 @@
-import { SWRResponse } from 'swr';
+import { useCallback } from 'react';
+
+import type { SWRResponse } from 'swr';
 
 import { useStaticSWR } from '~/stores/use-static-swr';
 
 type SearchModalStatus = {
   isOpened: boolean,
+  searchKeyword?: string,
 }
 
 type SearchModalUtils = {
-  open(): void
+  open(keywordOnInit?: string): void
   close(): void
 }
 export const useSearchModal = (status?: SearchModalStatus): SWRResponse<SearchModalStatus, Error> & SearchModalUtils => {
@@ -16,7 +19,9 @@ export const useSearchModal = (status?: SearchModalStatus): SWRResponse<SearchMo
 
   return {
     ...swrResponse,
-    open: () => swrResponse.mutate({ isOpened: true }),
-    close: () => swrResponse.mutate({ isOpened: false }),
+    open: useCallback((keywordOnInit?: string) => {
+      swrResponse.mutate({ isOpened: true, searchKeyword: keywordOnInit });
+    }, [swrResponse]),
+    close: useCallback(() => swrResponse.mutate({ isOpened: false }), [swrResponse]),
   };
 };

+ 13 - 36
apps/app/test/cypress/e2e/23-editor/23-editor--template-modal.cy.ts

@@ -15,30 +15,18 @@ context('TemplateModal', () => {
 
     // move to edit mode
     cy.get('#grw-page-editor-mode-manager').as('pageEditorModeManager').should('be.visible');
-    cy.waitUntil(() => {
-      // do
-      cy.get('@pageEditorModeManager').within(() => {
-        cy.get('button:nth-child(2)').click();
-      });
-      // until
-      return cy.get('.layout-root').then($elem => $elem.hasClass('editing'));
-    })
-    cy.get('.grw-editor-navbar-bottom').should('be.visible');
+    cy.getByTestid('editor-button').click();
+    cy.getByTestid('grw-editor-navbar-bottom').should('be.visible');
 
-    // show TemplateModal
-    cy.waitUntil(() => {
-      // do
-      cy.get('.navbar-editor > ul > li:nth-child(16) > button').click({force: true});
-      // wait until
-      return cy.getByTestid('template-modal').then($elem => $elem.is(':visible'));
-    });
+    // open TemplateModal
+    cy.getByTestid('open-template-button').click();
+    cy.getByTestid('template-modal').should('be.visible');
+    cy.screenshot(`${ssPrefix}opened`);
 
     // close TemplateModal
     cy.getByTestid('template-modal').should('be.visible').within(() => {
-      cy.screenshot(`${ssPrefix}opened`);
-      cy.get('button.close').click();
+      cy.get('.btn-close').click();
     });
-
     cy.screenshot(`${ssPrefix}close`);
   });
 
@@ -48,30 +36,19 @@ context('TemplateModal', () => {
 
     // move to edit mode
     cy.get('#grw-page-editor-mode-manager').as('pageEditorModeManager').should('be.visible');
-    cy.waitUntil(() => {
-      // do
-      cy.get('@pageEditorModeManager').within(() => {
-        cy.get('button:nth-child(2)').click();
-      });
-      // until
-      return cy.get('.layout-root').then($elem => $elem.hasClass('editing'));
-    })
-    cy.get('.grw-editor-navbar-bottom').should('be.visible');
+    cy.getByTestid('editor-button').click();
+    cy.getByTestid('grw-editor-navbar-bottom').should('be.visible');
 
-    // show TemplateModal
-    cy.waitUntil(() => {
-      // do
-      cy.get('.navbar-editor > ul > li:nth-child(16) > button').click({force: true});
-      // wait until
-      return cy.getByTestid('template-modal').then($elem => $elem.is(':visible'));
-    });
+    // open TemplateModal
+    cy.getByTestid('open-template-button').click();
+    cy.getByTestid('template-modal').should('be.visible');
 
     // select template and template locale
     cy.getByTestid('template-modal').should('be.visible').within(() => {
       // select first template
       cy.get('.list-group > .list-group-item:nth-child(1)').click();
       // check preview exist
-      cy.get('.card-body > .page-editor-preview-body > .wiki').should('exist');
+      cy.get('.card-body').should('be.visible');
       cy.screenshot(`${ssPrefix}select-template`);
 
       // change template locale

+ 27 - 41
apps/app/test/cypress/e2e/23-editor/23-editor--with-navigation.cy.ts

@@ -2,15 +2,9 @@ import path from 'path-browserify';
 
 function openEditor() {
   cy.get('#grw-page-editor-mode-manager').as('pageEditorModeManager').should('be.visible');
-  cy.waitUntil(() => {
-    // do
-    cy.get('@pageEditorModeManager').within(() => {
-      cy.get('button:nth-child(2)').click();
-    });
-    // until
-    return cy.get('.layout-root').then($elem => $elem.hasClass('editing'));
-  })
-  cy.get('.CodeMirror').should('be.visible');
+  cy.getByTestid('editor-button').click();
+  cy.getByTestid('grw-editor-navbar-bottom').should('be.visible');
+  cy.get('.cm-content').should('be.visible');
 }
 
 context('Editor while uploading to a new page', () => {
@@ -38,8 +32,8 @@ context('Editor while uploading to a new page', () => {
 
     // input the body
     const body = 'Hello World!';
-    cy.get('.CodeMirror textarea').type(body + '\n\n', { force: true });
-    cy.get('.CodeMirror-code').should('contain.text', body);
+    cy.get('.cm-content').should('be.visible').type(body, { force: true });
+    cy.getByTestid('page-editor-preview-body').should('contain.text', body);
 
     // open GrantSelector
     cy.waitUntil(() => {
@@ -48,18 +42,14 @@ context('Editor while uploading to a new page', () => {
         cy.get('button.dropdown-toggle').click({force: true});
       });
       // wait until
-      return cy.getByTestid('grw-grant-selector').within(() => {
-        return Cypress.$('.dropdown-menu.show').is(':visible');
-      });
+      return cy.getByTestid('grw-grant-selector-dropdown-menu').then($elem => $elem.is(':visible'))
     });
 
     // Select "Only me"
-    cy.getByTestid('grw-grant-selector').within(() => {
+    cy.getByTestid('grw-grant-selector-dropdown-menu').find('.dropdown-item').should('have.length', 4).then((menuItems) => {
       // click "Only me"
-      cy.get('.dropdown-menu.show').find('.dropdown-item').should('have.length', 4).then((menuItems) => {
-        menuItems[2].click();
-      });
-    });
+      menuItems[2].click();
+    })
 
     cy.getByTestid('grw-grant-selector').find('.dropdown-toggle').should('contain.text', 'Only me');
     cy.screenshot(`${ssPrefix}-prevent-grantselector-modified-2`);
@@ -67,7 +57,7 @@ context('Editor while uploading to a new page', () => {
     // intercept API req/res for fixing labels
     const dummyAttachmentId = '64b000000000000000000000';
     let uploadedAttachmentId = '';
-    cy.intercept('POST', '/_api/attachments.add', (req) => {
+    cy.intercept('POST', '/_api/v3/attachment', (req) => {
       req.continue((res) => {
         // store the attachment id
         uploadedAttachmentId = res.body.attachment._id;
@@ -86,20 +76,20 @@ context('Editor while uploading to a new page', () => {
 
     // drag-drop a file
     const filePath = path.relative('/', path.resolve(Cypress.spec.relative, '../assets/example.txt'));
-    cy.get('.dropzone').selectFile(filePath, { action: 'drag-drop' });
+    cy.get('.dropzone').eq(0).selectFile(filePath, { action: 'drag-drop' });
     cy.wait('@attachmentsAdd');
 
     cy.screenshot(`${ssPrefix}-prevent-grantselector-modified-3`);
 
     // Update page using shortcut keys
-    cy.get('.CodeMirror').click().type('{ctrl+s}');
+    cy.get('.cm-content').click({force: true}).type('{ctrl+s}');
 
     cy.screenshot(`${ssPrefix}-prevent-grantselector-modified-4`);
 
     // expect
     cy.get('.Toastify__toast').should('contain.text', 'Saved successfully');
-    cy.get('.CodeMirror-code').should('contain.text', body);
-    cy.get('.CodeMirror-code').should('contain.text', '[example.txt](/attachment/64b000000000000000000000');
+    cy.get('.cm-content').should('contain.text', body);
+    cy.get('.cm-content').should('contain.text', '[example.txt](/attachment/64b000000000000000000000');
     cy.getByTestid('grw-grant-selector').find('.dropdown-toggle').should('contain.text', 'Only me');
     cy.screenshot(`${ssPrefix}-prevent-grantselector-modified-5`);
   });
@@ -131,11 +121,9 @@ context('Editor while navigation', () => {
 
     // page1
     const bodyHello = 'hello';
-    cy.get('.CodeMirror').type(bodyHello);
-    cy.get('.CodeMirror').should('contain.text', bodyHello);
-    cy.get('.page-editor-preview-body').should('contain.text', bodyHello);
-    cy.getByTestid('page-editor').should('be.visible');
-    cy.get('.CodeMirror').screenshot(`${ssPrefix}-editor-for-page1`);
+    cy.get('.cm-content').should('be.visible').type(bodyHello, { force: true });
+    cy.getByTestid('page-editor-preview-body').should('contain.text', bodyHello);
+    cy.get('.cm-content').screenshot(`${ssPrefix}-editor-for-page1`);
 
     // save page1
     cy.getByTestid('save-page-btn').click();
@@ -159,31 +147,29 @@ context('Editor while navigation', () => {
     })
 
     openEditor();
-
-    cy.get('.CodeMirror').screenshot(`${ssPrefix}-editor-for-page2`);
+    cy.get('.cm-content').screenshot(`${ssPrefix}-editor-for-page2`);
 
     // type (without save)
     const bodyWorld = ' world!!'
-    cy.get('.CodeMirror').type(`${bodyWorld}`);
-    cy.get('.CodeMirror').should('contain.text', `${bodyHello}${bodyWorld}`);
-    cy.get('.page-editor-preview-body').should('contain.text', `${bodyHello}${bodyWorld}`);
-    cy.get('.CodeMirror').screenshot(`${ssPrefix}-editor-for-page2-modified`);
+    cy.get('.cm-content').should('be.visible').type(`{moveToEnd}${bodyWorld}`, { force: true });
+    cy.getByTestid('page-editor-preview-body').should('contain.text', `${bodyHello}${bodyWorld}`);
+    cy.get('.cm-content').screenshot(`${ssPrefix}-editor-for-page2-modified`);
 
     // create a link to page1
-    cy.get('.CodeMirror').type('\n\n[page1](./page1)');
+    cy.get('.cm-content').type('\n\n[page1](./page1)');
 
     // go to page1
-    cy.get('.page-editor-preview-body').within(() => {
+    cy.getByTestid('page-editor-preview-body').within(() => {
       cy.get("a:contains('page1')").click();
     });
 
     openEditor();
 
-    cy.get('.CodeMirror').screenshot(`${ssPrefix}-editor-for-page1-returned`);
+    cy.get('.cm-content').screenshot(`${ssPrefix}-editor-for-page1-returned`);
 
     // expect
-    cy.get('.CodeMirror').should('contain.text', bodyHello);
-    cy.get('.CodeMirror').should('not.contain.text', bodyWorld); // text that added to page2
-    cy.get('.CodeMirror').should('not.contain.text', 'page1'); // text that added to page2
+    cy.get('.cm-content').should('contain.text', bodyHello);
+    cy.get('.cm-content').should('not.contain.text', bodyWorld); // text that added to page2
+    cy.get('.cm-content').should('not.contain.text', 'page1'); // text that added to page2
   });
 });

+ 1 - 1
packages/editor/src/components/CodeMirrorEditor/Toolbar/TemplateButton.tsx

@@ -22,7 +22,7 @@ export const TemplateButton = (props: Props): JSX.Element => {
   }, [codeMirrorEditor?.view, openTemplateModal]);
 
   return (
-    <button type="button" className="btn btn-toolbar-button" onClick={onClickTempleteButton}>
+    <button type="button" className="btn btn-toolbar-button" onClick={onClickTempleteButton} data-testid="open-template-button">
       <span className="material-symbols-outlined fs-5">file_copy</span>
     </button>
   );

+ 3 - 3
yarn.lock

@@ -16992,9 +16992,9 @@ tar-stream@^3.0.0:
     streamx "^2.15.0"
 
 tar@^6.1.11, tar@^6.1.2:
-  version "6.2.0"
-  resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73"
-  integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==
+  version "6.2.1"
+  resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a"
+  integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==
   dependencies:
     chownr "^2.0.0"
     fs-minipass "^2.0.0"