Просмотр исходного кода

Merge branch 'master' into fix/111880-internal-server-err-when-pending-user-login

Kaori Tokashiki 3 лет назад
Родитель
Сommit
16f35d6d66
49 измененных файлов с 743 добавлено и 753 удалено
  1. 0 0
      .github/dependabot.yml.org
  2. 2 2
      .github/workflows/release-rc.yml
  3. 2 2
      .github/workflows/release-slackbot-proxy.yml
  4. 1 1
      lerna.json
  5. 1 1
      package.json
  6. 1 1
      packages/app/cypress.config.ts
  7. 13 12
      packages/app/package.json
  8. 3 2
      packages/app/src/components/Admin/App/SiteUrlSetting.tsx
  9. 1 1
      packages/app/src/components/Admin/Customize/CustomizeCssSetting.tsx
  10. 1 1
      packages/app/src/components/Admin/Customize/CustomizeNoscriptSetting.tsx
  11. 1 1
      packages/app/src/components/Admin/Customize/CustomizeScriptSetting.tsx
  12. 2 1
      packages/app/src/components/Common/Dropdown/PageItemControl.tsx
  13. 1 1
      packages/app/src/components/DescendantsPageListModal.module.scss
  14. 2 2
      packages/app/src/components/DescendantsPageListModal.tsx
  15. 1 1
      packages/app/src/components/Navbar/GrowiNavbar.tsx
  16. 2 2
      packages/app/src/components/PageEditor/Editor.tsx
  17. 20 33
      packages/app/src/components/PageEditor/LinkEditModal.jsx
  18. 3 1
      packages/app/src/components/PageStatusAlert.tsx
  19. 14 11
      packages/app/src/components/Sidebar.tsx
  20. 1 1
      packages/app/src/components/Sidebar/CustomSidebar.tsx
  21. 1 1
      packages/app/src/components/Sidebar/RecentChanges.module.scss
  22. 4 4
      packages/app/src/components/Sidebar/SidebarContents.tsx
  23. 23 24
      packages/app/src/components/Sidebar/Skeleton/SidebarSkeleton.tsx
  24. 4 1
      packages/app/src/components/Sidebar/Skeleton/TagContentSkeleton.tsx
  25. 0 5
      packages/app/src/components/Sidebar/Tag.module.scss
  26. 2 1
      packages/app/src/pages/[[...path]].page.tsx
  27. 0 1
      packages/app/src/pages/_app.page.tsx
  28. 3 0
      packages/app/src/styles/style-app.scss
  29. 1 1
      packages/app/test/cypress/integration/20-basic-features/20-basic-features--access-to-page.spec.ts
  30. 35 72
      packages/app/test/cypress/integration/20-basic-features/20-basic-features--access-to-pagelist.spec.ts
  31. 11 5
      packages/app/test/cypress/integration/20-basic-features/20-basic-features--click-page-icons.spec.ts
  32. 119 257
      packages/app/test/cypress/integration/20-basic-features/20-basic-features--use-tools.spec.ts
  33. 2 2
      packages/app/test/cypress/integration/21-basic-features-for-guest/21-basic-features-for-guest--access-to-page.spec.ts
  34. 204 111
      packages/app/test/cypress/integration/30-search/30-search--search.spec.ts
  35. 124 56
      packages/app/test/cypress/integration/50-sidebar/50-sidebar--access-to-side-bar.spec.ts
  36. 1 1
      packages/app/test/cypress/integration/50-sidebar/50-sidebar--switching-sidebar-mode.spec.ts
  37. 1 1
      packages/app/test/cypress/integration/60-home/60-home--home.spec.ts
  38. 20 19
      packages/app/test/cypress/support/commands.ts
  39. 1 1
      packages/codemirror-textlint/package.json
  40. 1 1
      packages/core/package.json
  41. 1 1
      packages/hackmd/package.json
  42. 4 2
      packages/preset-themes/package.json
  43. 1 1
      packages/remark-drawio/package.json
  44. 1 1
      packages/remark-growi-directive/package.json
  45. 4 4
      packages/remark-lsx/package.json
  46. 1 1
      packages/slack/package.json
  47. 2 2
      packages/slackbot-proxy/package.json
  48. 2 2
      packages/ui/package.json
  49. 98 98
      yarn.lock

+ 0 - 0
.github/dependabot.yml → .github/dependabot.yml.org


+ 2 - 2
.github/workflows/release-rc.yml

@@ -34,14 +34,14 @@ jobs:
         echo ${{ secrets. DOCKER_REGISTRY_PASSWORD }} | docker login --username wsmoogle --password-stdin
 
     - name: Login to GitHub Container Registry
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2
       with:
         registry: ghcr.io
         username: wsmoogle
         password: ${{ secrets.DOCKER_REGISTRY_ON_GITHUB_PASSWORD }}
 
     - name: Set up Docker Buildx
-      uses: docker/setup-buildx-action@v1
+      uses: docker/setup-buildx-action@v2
 
     - name: Build and push
       uses: docker/build-push-action@v2

+ 2 - 2
.github/workflows/release-slackbot-proxy.yml

@@ -36,7 +36,7 @@ jobs:
         echo ${{ secrets. DOCKER_REGISTRY_PASSWORD }} | docker login --username wsmoogle --password-stdin
 
     - name: Login to GitHub Container Registry
-      uses: docker/login-action@v1
+      uses: docker/login-action@v2
       with:
         registry: ghcr.io
         username: wsmoogle
@@ -55,7 +55,7 @@ jobs:
         gcloud auth configure-docker --quiet
 
     - name: Set up Docker Buildx
-      uses: docker/setup-buildx-action@v1
+      uses: docker/setup-buildx-action@v2
 
     - name: Build and push
       uses: docker/build-push-action@v2

+ 1 - 1
lerna.json

@@ -1,7 +1,7 @@
 {
   "npmClient": "yarn",
   "useWorkspaces": true,
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "packages": [
     "packages/*"
   ]

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "growi",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "description": "Team collaboration software using markdown",
   "tags": [
     "wiki",

+ 1 - 1
packages/app/cypress.config.ts

@@ -16,7 +16,7 @@ export default defineConfig({
         return launchOptions;
       });
     },
-    defaultCommandTimeout: 10000,
+    defaultCommandTimeout: 7000,
   },
   fileServerFolder: 'test/cypress',
   fixturesFolder: 'test/cypress/fixtures',

+ 13 - 12
packages/app/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/app",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "license": "MIT",
   "scripts": {
     "//// for production": "",
@@ -53,6 +53,7 @@
   "// comments for dependencies": {
     "openid-client": "Node.js 12 or higher is required for openid-client@3 and above.",
     "escape-string-regexp": "5.0.0 or above exports only ESM",
+    "next": "/Sandbox rendering is crashed with v12.3 or above ",
     "string-width": "5.0.0 or above exports only ESM."
   },
   "dependencies": {
@@ -64,14 +65,14 @@
     "@elastic/elasticsearch7": "npm:@elastic/elasticsearch@^7.17.0",
     "@godaddy/terminus": "^4.9.0",
     "@google-cloud/storage": "^5.8.5",
-    "@growi/codemirror-textlint": "^6.0.0-RC.9",
-    "@growi/core": "^6.0.0-RC.9",
-    "@growi/hackmd": "^6.0.0-RC.9",
-    "@growi/preset-themes": "^6.0.0-RC.9",
-    "@growi/remark-drawio": "^6.0.0-RC.9",
-    "@growi/remark-growi-directive": "^6.0.0-RC.9",
-    "@growi/remark-lsx": "^6.0.0-RC.9",
-    "@growi/slack": "^6.0.0-RC.9",
+    "@growi/codemirror-textlint": "^6.0.0-RC.13",
+    "@growi/core": "^6.0.0-RC.13",
+    "@growi/hackmd": "^6.0.0-RC.13",
+    "@growi/preset-themes": "^6.0.0-RC.13",
+    "@growi/remark-drawio": "^6.0.0-RC.13",
+    "@growi/remark-growi-directive": "^6.0.0-RC.13",
+    "@growi/remark-lsx": "^6.0.0-RC.13",
+    "@growi/slack": "^6.0.0-RC.13",
     "@promster/express": "^7.0.2",
     "@promster/server": "^7.0.4",
     "@slack/web-api": "^6.2.4",
@@ -132,7 +133,7 @@
     "mongoose-unique-validator": "^2.0.3",
     "multer": "~1.4.0",
     "multer-autoreap": "^1.0.3",
-    "next": "^12.2.5",
+    "next": "~12.2",
     "next-i18next": "^12.1.0",
     "next-superjson": "^0.0.4",
     "next-themes": "^0.2.0",
@@ -164,7 +165,7 @@
     "react-syntax-highlighter": "^15.5.0",
     "react-toastify": "^9.1.1",
     "react-use-ripple": "^1.5.2",
-    "reactstrap": "^8.9.0",
+    "reactstrap": "^8.10.1",
     "reconnecting-websocket": "^4.4.0",
     "redis": "^3.0.2",
     "rehype-katex": "^6.0.2",
@@ -201,7 +202,7 @@
     "handsontable": "v7.0.0 or above is no loger MIT lisence."
   },
   "devDependencies": {
-    "@growi/ui": "^6.0.0-RC.9",
+    "@growi/ui": "^6.0.0-RC.13",
     "@handsontable/react": "=2.1.0",
     "@icon/themify-icons": "1.0.1-alpha.3",
     "@next/bundle-analyzer": "^12.2.3",

+ 3 - 2
packages/app/src/components/Admin/App/SiteUrlSetting.tsx

@@ -18,19 +18,20 @@ type Props = {
 
 const SiteUrlSetting = (props: Props) => {
   const { t } = useTranslation('admin', { keyPrefix: 'app_setting' });
+  const { t: tCommon } = useTranslation('commons');
   const { adminAppContainer } = props;
 
 
   const submitHandler = useCallback(async() => {
     try {
       await adminAppContainer.updateSiteUrlSettingHandler();
-      toastSuccess(t('toaster.update_successed', { target: t('site_url.title') }));
+      toastSuccess(tCommon('toaster.update_successed', { target: t('site_url.title') }));
     }
     catch (err) {
       toastError(err);
       logger.error(err);
     }
-  }, [adminAppContainer, t]);
+  }, [adminAppContainer, t, tCommon]);
 
   return (
     <React.Fragment>

+ 1 - 1
packages/app/src/components/Admin/Customize/CustomizeCssSetting.tsx

@@ -46,7 +46,7 @@ const CustomizeCssSetting = (props: Props): JSX.Element => {
               className="form-control"
               name="customizeCss"
               rows={8}
-              value={adminCustomizeContainer.state.currentCustomizeCss || ''}
+              defaultValue={adminCustomizeContainer.state.currentCustomizeCss || ''}
               onChange={(e) => { adminCustomizeContainer.changeCustomizeCss(e.target.value) }}
             />
             {/* disabled in v6.0.0 temporarily -- 2022.12.19 Yuki Takei

+ 1 - 1
packages/app/src/components/Admin/Customize/CustomizeNoscriptSetting.tsx

@@ -50,7 +50,7 @@ const CustomizeNoscriptSetting = (props: Props): JSX.Element => {
               className="form-control"
               name="customizeNoscript"
               rows={8}
-              value={adminCustomizeContainer.state.currentCustomizeNoscript || ''}
+              defaultValue={adminCustomizeContainer.state.currentCustomizeNoscript || ''}
               onChange={(e) => { adminCustomizeContainer.changeCustomizeNoscript(e.target.value) }}
             />
             {/* disabled in v6.0.0 temporarily -- 2022.12.19 Yuki Takei

+ 1 - 1
packages/app/src/components/Admin/Customize/CustomizeScriptSetting.tsx

@@ -47,7 +47,7 @@ const CustomizeScriptSetting = (props: Props): JSX.Element => {
               className="form-control"
               name="customizeScript"
               rows={8}
-              value={adminCustomizeContainer.state.currentCustomizeScript || ''}
+              defaultValue={adminCustomizeContainer.state.currentCustomizeScript || ''}
               onChange={(e) => { adminCustomizeContainer.changeCustomizeScript(e.target.value) }}
             />
             {/* disabled in v6.0.0 temporarily -- 2022.12.19 Yuki Takei

+ 2 - 1
packages/app/src/components/Common/Dropdown/PageItemControl.tsx

@@ -247,9 +247,10 @@ const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.E
   return (
     <DropdownMenu
       data-testid="page-item-control-menu"
-      positionFixed
       modifiers={{ preventOverflow: { boundariesElement: 'viewport' } }}
       right={alignRight}
+      container="body"
+      style={{ zIndex: 1055 }} /* make it larger than $zindex-modal of bootstrap */
     >
       {contents}
     </DropdownMenu>

+ 1 - 1
packages/app/src/components/DescendantsPageListModal.module.scss

@@ -1,4 +1,4 @@
-.grw-page-accessories-modal :global {
+.grw-descendants-page-list-modal :global {
   .modal-header {
     button.close {
       margin: auto 0rem auto auto;

+ 2 - 2
packages/app/src/components/DescendantsPageListModal.tsx

@@ -93,8 +93,8 @@ export const DescendantsPageListModal = (): JSX.Element => {
       size="xl"
       isOpen={isOpened}
       toggle={close}
-      data-testid="page-accessories-modal"
-      className={`grw-page-accessories-modal ${styles['grw-page-accessories-modal']} ${isWindowExpanded ? 'grw-modal-expanded' : ''} `}
+      data-testid="descendants-page-list-modal"
+      className={`grw-descendants-page-list-modal ${styles['grw-descendants-page-list-modal']} ${isWindowExpanded ? 'grw-modal-expanded' : ''} `}
     >
       <ModalHeader className="p-0" toggle={close} close={buttons}>
         <CustomNavTab

+ 1 - 1
packages/app/src/components/Navbar/GrowiNavbar.tsx

@@ -80,7 +80,7 @@ const NavbarRight = memo((): JSX.Element => {
         <li className="grw-apperance-mode-dropdown nav-item dropdown">
           <AppearanceModeDropdown isAuthenticated={isAuthenticated} />
         </li>
-        <li id="login-user" className="nav-item"><a className="nav-link" href="/login">Login</a></li>;
+        <li id="login-user" className="nav-item"><a className="nav-link" href="/login">Login</a></li>
       </>
     );
   }, [isAuthenticated]);

+ 2 - 2
packages/app/src/components/PageEditor/Editor.tsx

@@ -227,7 +227,7 @@ const Editor: ForwardRefRenderFunction<IEditorMethods, EditorPropsType> = (props
     );
   }, [isUploading]);
 
-  const renderNavbar = useCallback(() => {
+  const renderNavbar = () => {
     return (
       <div className="m-0 navbar navbar-default navbar-editor" data-testid="navbar-editor" style={{ minHeight: 'unset' }}>
         <ul className="pl-2 nav nav-navbar">
@@ -238,7 +238,7 @@ const Editor: ForwardRefRenderFunction<IEditorMethods, EditorPropsType> = (props
         </ul>
       </div>
     );
-  }, [editorSubstance]);
+  };
 
   const renderCheatsheetModal = useCallback(() => {
     const hideCheatsheetModal = () => {

+ 20 - 33
packages/app/src/components/PageEditor/LinkEditModal.jsx

@@ -345,7 +345,7 @@ class LinkEditModal extends React.PureComponent {
     return (
       <div className="card well pt-3">
         <form className="form-group mb-0">
-          <div className="form-group row">
+          <div className="form-group mb-0 row">
             <label className="col-sm-3">{t('link_edit.path_format')}</label>
             <div className="col-sm-9">
               <div className="custom-control custom-checkbox custom-checkbox-info custom-control-inline">
@@ -376,36 +376,23 @@ class LinkEditModal extends React.PureComponent {
               </div>
             </div>
           </div>
-          <div className="form-group row mb-0">
-            <label className="col-sm-3">{t('link_edit.notation')}</label>
-            <div className="col-sm-9">
-              <div className="custom-control custom-radio custom-control-inline">
-                <input
-                  type="radio"
-                  className="custom-control-input"
-                  id="markdownType"
-                  value={Linker.types.markdownLink}
-                  checked={this.state.linkerType === Linker.types.markdownLink}
-                  onChange={e => this.handleSelecteLinkerType(e.target.value)}
-                />
-                <label className="custom-control-label" htmlFor="markdownType">
-                  {t('link_edit.markdown')}
-                </label>
-              </div>
-              <div className="custom-control custom-radio custom-control-inline">
-                <input
-                  type="radio"
-                  className="custom-control-input"
-                  id="growiType"
-                  value={Linker.types.growiLink}
-                  checked={this.state.linkerType === Linker.types.growiLink}
-                  onChange={e => this.handleSelecteLinkerType(e.target.value)}
-                />
-                <label className="custom-control-label" htmlFor="growiType">
-                  {t('link_edit.GROWI_original')}
-                </label>
-              </div>
-              {this.isApplyPukiwikiLikeLinkerPlugin && (
+          {this.isApplyPukiwikiLikeLinkerPlugin && (
+            <div className="form-group row mb-0 mt-1">
+              <label className="col-sm-3">{t('link_edit.notation')}</label>
+              <div className="col-sm-9">
+                <div className="custom-control custom-radio custom-control-inline">
+                  <input
+                    type="radio"
+                    className="custom-control-input"
+                    id="markdownType"
+                    value={Linker.types.markdownLink}
+                    checked={this.state.linkerType === Linker.types.markdownLink}
+                    onChange={e => this.handleSelecteLinkerType(e.target.value)}
+                  />
+                  <label className="custom-control-label" htmlFor="markdownType">
+                    {t('link_edit.markdown')}
+                  </label>
+                </div>
                 <div className="custom-control custom-radio custom-control-inline">
                   <input
                     type="radio"
@@ -419,9 +406,9 @@ class LinkEditModal extends React.PureComponent {
                     {t('link_edit.pukiwiki')}
                   </label>
                 </div>
-              )}
+              </div>
             </div>
-          </div>
+          )}
         </form>
       </div>
     );

+ 3 - 1
packages/app/src/components/PageStatusAlert.tsx

@@ -3,6 +3,7 @@ import React, { useCallback, useMemo } from 'react';
 import { useTranslation } from 'next-i18next';
 import * as ReactDOMServer from 'react-dom/server';
 
+import { useIsGuestUser } from '~/stores/context';
 import { useEditingMarkdown, useIsConflict } from '~/stores/editor';
 import {
   useHasDraftOnHackmd, useIsHackmdDraftUpdatingInRealtime, useRevisionIdHackmdSynced,
@@ -31,6 +32,7 @@ export const PageStatusAlert = (): JSX.Element => {
   const { mutate: mutateEditingMarkdown } = useEditingMarkdown();
   const { open: openConflictDiffModal } = useConflictDiffModal();
   const { mutate: mutateEditorMode } = useEditorMode();
+  const { data: isGuest } = useIsGuestUser();
 
   // store remote latest page data
   const { data: revisionIdHackmdSynced } = useRevisionIdHackmdSynced();
@@ -151,7 +153,7 @@ export const PageStatusAlert = (): JSX.Element => {
     getContentsForDraftExistsAlert,
   ]);
 
-  if (alertComponentContents == null) { return <></> }
+  if (isGuest || alertComponentContents == null) { return <></> }
 
   const { additionalClasses, label, btn } = alertComponentContents;
 

+ 14 - 11
packages/app/src/components/Sidebar.tsx

@@ -1,5 +1,5 @@
 import React, {
-  useCallback, useEffect, useRef, useState,
+  memo, useCallback, useEffect, useRef, useState,
 } from 'react';
 
 import dynamic from 'next/dynamic';
@@ -22,12 +22,16 @@ import { StickyStretchableScrollerProps } from './StickyStretchableScroller';
 
 import styles from './Sidebar.module.scss';
 
+const StickyStretchableScroller = dynamic<StickyStretchableScrollerProps>(() => import('./StickyStretchableScroller')
+  .then(mod => mod.StickyStretchableScroller), { ssr: false });
+const SidebarContents = dynamic(() => import('./Sidebar/SidebarContents')
+  .then(mod => mod.SidebarContents), { ssr: false, loading: () => <SidebarSkeleton /> });
 
 const sidebarMinWidth = 240;
 const sidebarMinimizeWidth = 20;
 const sidebarFixedWidthInDrawerMode = 320;
 
-const GlobalNavigation = () => {
+const GlobalNavigation = memo(() => {
   const { data: isDrawerMode } = useDrawerMode();
   const { data: currentContents } = useCurrentSidebarContents();
   const { data: isCollapsed, mutate: mutateSidebarCollapsed } = useSidebarCollapsed();
@@ -54,13 +58,10 @@ const GlobalNavigation = () => {
 
   return <SidebarNav onItemSelected={itemSelectedHandler} />;
 
-};
+});
+GlobalNavigation.displayName = 'GlobalNavigation';
 
-const SidebarContentsWrapper = () => {
-  const StickyStretchableScroller = dynamic<StickyStretchableScrollerProps>(() => import('./StickyStretchableScroller')
-    .then(mod => mod.StickyStretchableScroller), { ssr: false, loading: () => <SidebarSkeleton /> });
-  const SidebarContents = dynamic(() => import('./Sidebar/SidebarContents')
-    .then(mod => mod.SidebarContents), { ssr: false, loading: () => <SidebarSkeleton /> });
+const SidebarContentsWrapper = memo(() => {
   const { mutate: mutateSidebarScroller } = useSidebarScrollerRef();
 
   const calcViewHeight = useCallback(() => {
@@ -85,10 +86,11 @@ const SidebarContentsWrapper = () => {
       <DrawerToggler iconClass="icon-arrow-left" />
     </>
   );
-};
+});
+SidebarContentsWrapper.displayName = 'SidebarContentsWrapper';
 
 
-const Sidebar = (): JSX.Element => {
+const Sidebar = memo((): JSX.Element => {
 
   const { data: isDrawerMode } = useDrawerMode();
   const { data: isDrawerOpened, mutate: mutateDrawerOpened } = useDrawerOpened();
@@ -354,6 +356,7 @@ const Sidebar = (): JSX.Element => {
     </>
   );
 
-};
+});
+Sidebar.displayName = 'Sidebar';
 
 export default Sidebar;

+ 1 - 1
packages/app/src/components/Sidebar/CustomSidebar.tsx

@@ -47,7 +47,7 @@ const CustomSidebar: FC = () => {
       <div className="grw-sidebar-content-header py-3 d-flex">
         <h3 className="mb-0">
           {t('CustomSidebar')}
-          <Link href="/Sidebar"><a className="h6 ml-2"><i className="icon-pencil"></i></a></Link>
+          <Link href="/Sidebar#edit"><a className="h6 ml-2"><i className="icon-pencil"></i></a></Link>
         </h3>
         <SidebarHeaderReloadButton onClick={() => mutate()} />
       </div>

+ 1 - 1
packages/app/src/components/Sidebar/RecentChanges.module.scss

@@ -29,7 +29,7 @@
 
   .grw-recent-changes-skeleton-date {
     @include grw-skeleton-text($font-size:10px, $line-height:12px);
-    width: 90px;
+    width: 80px;
   }
 
   .grw-recent-changes-item-lower {

+ 4 - 4
packages/app/src/components/Sidebar/SidebarContents.tsx

@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { memo } from 'react';
 
 import { SidebarContentsType } from '~/interfaces/ui';
 import { useCurrentSidebarContents } from '~/stores/ui';
@@ -8,7 +8,7 @@ import PageTree from './PageTree';
 import RecentChanges from './RecentChanges';
 import Tag from './Tag';
 
-export const SidebarContents = (): JSX.Element => {
+export const SidebarContents = memo(() => {
   const { data: currentSidebarContents } = useCurrentSidebarContents();
 
   let Contents;
@@ -29,5 +29,5 @@ export const SidebarContents = (): JSX.Element => {
   return (
     <Contents />
   );
-
-};
+});
+SidebarContents.displayName = 'SidebarContents';

+ 23 - 24
packages/app/src/components/Sidebar/Skeleton/SidebarSkeleton.tsx

@@ -1,6 +1,7 @@
-import React from 'react';
+import React, { memo } from 'react';
+
+import { useTranslation } from 'next-i18next';
 
-import { Skeleton } from '~/components/Skeleton';
 import { SidebarContentsType } from '~/interfaces/ui';
 import { useCurrentSidebarContents } from '~/stores/ui';
 
@@ -9,42 +10,40 @@ import PageTreeContentSkeleton from './PageTreeContentSkeleton';
 import RecentChangesContentSkeleton from './RecentChangesContentSkeleton';
 import TagContentSkeleton from './TagContentSkeleton';
 
-import styles from './SidebarSkeleton.module.scss';
-
-export const SidebarHeaderSkeleton = (): JSX.Element => {
-  return (
-    <div className="grw-sidebar-content-header py-3">
-      <Skeleton additionalClass={styles['grw-sidebar-content-header-skeleton']} />
-    </div>
-  );
-};
-
-export const SidebarSkeleton = (): JSX.Element => {
-
+export const SidebarSkeleton = memo(() => {
+  const { t } = useTranslation();
   const { data: currentSidebarContents } = useCurrentSidebarContents();
 
-  let SidebarContentSkeleton: () => JSX.Element;
+  let Contents: () => JSX.Element;
+  let title: string;
   switch (currentSidebarContents) {
 
-    case SidebarContentsType.TAG:
-      SidebarContentSkeleton = TagContentSkeleton;
-      break;
     case SidebarContentsType.RECENT:
-      SidebarContentSkeleton = RecentChangesContentSkeleton;
+      Contents = RecentChangesContentSkeleton;
+      title = t('Recent Changes');
       break;
     case SidebarContentsType.CUSTOM:
-      SidebarContentSkeleton = CustomSidebarContentSkeleton;
+      Contents = CustomSidebarContentSkeleton;
+      title = t('CustomSidebar');
+      break;
+    case SidebarContentsType.TAG:
+      Contents = TagContentSkeleton;
+      title = t('Tags');
       break;
     case SidebarContentsType.TREE:
     default:
-      SidebarContentSkeleton = PageTreeContentSkeleton;
+      Contents = PageTreeContentSkeleton;
+      title = t('Page Tree');
       break;
   }
 
   return (
     <div className={currentSidebarContents === SidebarContentsType.TAG ? 'px-4' : 'px-3'}>
-      <SidebarHeaderSkeleton />
-      <SidebarContentSkeleton />
+      <div className="grw-sidebar-content-header py-3">
+        <h3 className="mb-0">{title}</h3>
+      </div>
+      <Contents />
     </div>
   );
-};
+});
+SidebarSkeleton.displayName = 'SidebarSkeleton';

+ 4 - 1
packages/app/src/components/Sidebar/Skeleton/TagContentSkeleton.tsx

@@ -1,5 +1,7 @@
 import React from 'react';
 
+import { useTranslation } from 'next-i18next';
+
 import { Skeleton } from '~/components/Skeleton';
 
 import styles from '../Tag.module.scss';
@@ -11,10 +13,11 @@ export const TagListSkeleton = (): JSX.Element => {
 };
 
 const TagContentSkeleton = (): JSX.Element => {
+  const { t } = useTranslation('');
 
   return (
     <>
-      <Skeleton additionalClass={`${styles['grw-tag-skeleton-h3']} my-3`} />
+      <h3 className="my-3">{t('tag_list')}</h3>
       <TagListSkeleton />
     </>
   );

+ 0 - 5
packages/app/src/components/Sidebar/Tag.module.scss

@@ -1,10 +1,5 @@
 @use '~/styles/mixins' as *;
 
-.grw-tag-skeleton-h3 {
-  @include grw-skeleton-h3;
-  max-width: 120px;
-}
-
 .grw-tag-list-skeleton {
   height: 90px;
 }

+ 2 - 1
packages/app/src/pages/[[...path]].page.tsx

@@ -292,7 +292,8 @@ const Page: NextPageWithLayout<Props> = (props: Props) => {
   useEffect(() => {
     const decodedURI = decodeURI(window.location.pathname);
     if (isClient() && decodedURI !== props.currentPathname) {
-      router.replace(props.currentPathname, undefined, { shallow: true });
+      const { search, hash } = window.location;
+      router.replace(`${props.currentPathname}${search}${hash}`, undefined, { shallow: true });
     }
   }, [props.currentPathname, router]);
 

+ 0 - 1
packages/app/src/pages/_app.page.tsx

@@ -39,7 +39,6 @@ export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
 }
 
 type GrowiAppProps = AppProps & {
-  pageProps: CommonProps;
   Component: NextPageWithLayout,
 };
 

+ 3 - 0
packages/app/src/styles/style-app.scss

@@ -10,6 +10,9 @@
 @import '~simplebar/dist/simplebar.min.css';
 @import 'override-simplebar';
 
+// Emoji-mart style
+@import '~emoji-mart/css/emoji-mart.css';
+
 // KaTeX
 @import '~katex/dist/katex.min';
 

+ 1 - 1
packages/app/test/cypress/integration/20-basic-features/20-basic-features--access-to-page.spec.ts

@@ -15,7 +15,7 @@ context('Access to page', () => {
     // for check download toc data
     cy.get('.toc-link').eq(0).contains('Table of Contents');
 
-    cy.collapseSidebar(true);
+    cy.collapseSidebar(true, true);
     cy.screenshot(`${ssPrefix}-sandbox`);
   });
 

+ 35 - 72
packages/app/test/cypress/integration/20-basic-features/20-basic-features--access-to-pagelist.spec.ts

@@ -5,79 +5,61 @@ context('Access to pagelist', () => {
     cy.fixture("user-admin.json").then(user => {
       cy.login(user.username, user.password);
     });
-  });
-
-  it('Page list modal is successfully opened ', () => {
     cy.visit('/');
-    cy.waitUntilSkeletonDisappear();
     cy.collapseSidebar(true);
+    cy.waitUntilSkeletonDisappear();
 
-    cy.getByTestid('pageListButton').click({force: true});
-    cy.getByTestid('page-accessories-modal').parent().should('have.class','show');
-    cy.getByTestid('page-list-item-L').should('be.visible');
+    // open PageAccessoriesModal
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('pageListButton').click({force: true});
+      // wait until
+      return cy.getByTestid('descendants-page-list-modal').then($elem => $elem.is(':visible'));
+    });
+
+    cy.waitUntilSpinnerDisappear();
+  });
 
+  it('Page list modal is successfully opened ', () => {
     // Wait until the string "You cannot see this page" is no longer displayed
     cy.getByTestid('page-list-item-L').eq(0).within(() => {
       cy.get('.icon-exclamation').should('not.exist');
     });
 
+    cy.waitUntilSpinnerDisappear();
+    cy.waitUntilSkeletonDisappear();
     cy.screenshot(`${ssPrefix}1-open-pagelist-modal`);
   });
 
-  it('Successfully duplicate a page from page list', () => {
-    cy.visit('/');
-    cy.getByTestid('pageListButton').click({force: true});
-    cy.getByTestid('page-accessories-modal').parent().should('have.class','show').within(() => {
-      cy.getByTestid('open-page-item-control-btn').first().click();
-      cy.getByTestid('page-item-control-menu').should('have.class', 'show').first().within(() => {
-        // eslint-disable-next-line cypress/no-unnecessary-waiting
-        cy.wait(300);
-        cy.screenshot(`${ssPrefix}2-open-page-item-control-menu`);
-        cy.getByTestid('open-page-duplicate-modal-btn').click();
+  it('Successfully open PageItemControl', () => {
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('descendants-page-list-modal').within(() => {
+        cy.getByTestid('page-list-item-L').first().within(() => {
+          cy.getByTestid('open-page-item-control-btn').click();
+        });
       });
+      // wait until
+      return cy.get('.dropdown-menu.show').then($elem => $elem.is(':visible'));
     });
-    cy.getByTestid('page-duplicate-modal').should('be.visible').screenshot(`${ssPrefix}3-duplicate-page-modal-opened`);
-    cy.getByTestid('page-duplicate-modal').should('be.visible').within(() => {
-      cy.get('.rbt-input-main').type('-duplicate', {force: true})
-    }).screenshot(`${ssPrefix}4-input-duplicated-page-name`);
-    cy.getByTestid('page-duplicate-modal').should('be.visible').within(() => {
-      cy.get('.modal-footer > button').click();
-    });
-    cy.get('body').type('{esc}');
-    cy.getByTestid('pageListButton').click({force: true});
-    cy.getByTestid('page-accessories-modal').parent().should('have.class','show').within(() => {
-      cy.get('.list-group-item').eq(0).within(() => {
-        cy.screenshot(`${ssPrefix}5-duplicated-page`);
-      });
+
+    cy.get('.dropdown-menu.show').within(() => {
+      cy.getByTestid('open-page-duplicate-modal-btn').should('be.visible')
     });
-  });
 
-  it('Successfully expand and close modal', () => {
-    cy.visit('/');
     cy.waitUntilSkeletonDisappear();
-    cy.collapseSidebar(true);
-
-    cy.getByTestid('pageListButton').click({force: true});
-    cy.getByTestid('page-accessories-modal').parent().should('have.class','show');
-    cy.getByTestid('page-list-item-L').should('be.visible');
-
-    // Wait until the string "You cannot see this page" is no longer displayed
-    cy.getByTestid('page-list-item-L').eq(0).within(() => {
-      cy.get('.icon-exclamation').should('not.exist');
-    });
+    cy.waitUntilSpinnerDisappear();
+    cy.screenshot(`${ssPrefix}2-open-page-item-control-menu`);
+  });
 
-    cy.screenshot(`${ssPrefix}6-page-list-modal-size-normal`);
-    cy.getByTestid('page-accessories-modal').parent().should('have.class','show').within(() => {
-      cy.get('button.close').eq(0).click();
-    });
+  it('Successfully expand and close modal', () => {
+    cy.get('button.close').eq(0).click();
 
+    cy.waitUntilSkeletonDisappear();
+    cy.waitUntilSpinnerDisappear();
     cy.screenshot(`${ssPrefix}7-page-list-modal-size-fullscreen`);
 
-    cy.getByTestid('page-accessories-modal').parent().should('have.class','show').within(() => {
-      cy.get('button.close').eq(1).click();
-    });
-
-    cy.collapseSidebar(true);
+    cy.get('button.close').eq(1).click();
     cy.screenshot(`${ssPrefix}8-close-page-list-modal`);
   });
 });
@@ -95,30 +77,11 @@ context('Access to timeline', () => {
     cy.collapseSidebar(true);
 
     cy.getByTestid('pageListButton').click({force: true});
-    cy.getByTestid('page-accessories-modal').parent().should('have.class','show').within(() => {
+    cy.getByTestid('descendants-page-list-modal').parent().should('have.class','show').within(() => {
       cy.get('.nav-title > li').eq(1).find('a').click();
     });
     // eslint-disable-next-line cypress/no-unnecessary-waiting
     cy.wait(500); // wait for loading wiki
     cy.screenshot(`${ssPrefix}1-timeline-list`);
   });
-
-  it('Successfully expand and close modal', () => {
-    cy.visit('/');
-    cy.collapseSidebar(true);
-
-    cy.getByTestid('pageListButton').click({force: true});
-    cy.getByTestid('page-accessories-modal').parent().should('have.class','show').within(() => {
-      cy.get('.nav-title > li').eq(1).find('a').click();
-      cy.get('button.close').eq(0).click();
-    });
-    cy.get('.modal').should('be.visible');
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(500); // wait for loading wiki
-    cy.screenshot(`${ssPrefix}2-timeline-list-fullscreen`);
-    cy.getByTestid('page-accessories-modal').parent().should('have.class','show').within(() => {
-      cy.get('button.close').eq(1).click();
-    });
-    cy.screenshot(`${ssPrefix}3-close-modal`);
-  });
 });

+ 11 - 5
packages/app/test/cypress/integration/20-basic-features/20-basic-features--click-page-icons.spec.ts

@@ -6,13 +6,11 @@ context('Click page icons button', () => {
     cy.fixture("user-admin.json").then(user => {
       cy.login(user.username, user.password);
     });
-    // collapse sidebar
-    cy.collapseSidebar(true);
   });
 
   it('Successfully subscribe/unsubscribe a page', () => {
     cy.visit('/Sandbox');
-    cy.waitUntilSkeletonDisappear();
+    cy.collapseSidebar(true, true);
 
     // Subscribe
     cy.get('#subscribe-button').click({force: true});
@@ -26,6 +24,7 @@ context('Click page icons button', () => {
     })
     cy.getByTestid('subscribe-button-tooltip').should('not.exist');
 
+    cy.waitUntilSkeletonDisappear();
     cy.get('#grw-subnav-container').within(() => { cy.screenshot(`${ssPrefix}1-subscribe-page`) })
 
     // Unsubscribe
@@ -40,12 +39,13 @@ context('Click page icons button', () => {
     })
     cy.getByTestid('subscribe-button-tooltip').should('not.exist');
 
+    cy.waitUntilSkeletonDisappear();
     cy.get('#grw-subnav-container').within(() => { cy.screenshot(`${ssPrefix}2-unsubscribe-page`) })
   });
 
   it('Successfully Like / Dislike a page', () => {
     cy.visit('/Sandbox');
-    cy.waitUntilSkeletonDisappear();
+    cy.collapseSidebar(true);
 
     // like
     cy.get('#like-button').click({force: true});
@@ -59,6 +59,7 @@ context('Click page icons button', () => {
     })
     cy.getByTestid('like-button-tooltip').should('not.exist');
 
+    cy.waitUntilSpinnerDisappear();
     cy.get('#grw-subnav-container').within(() => { cy.screenshot(`${ssPrefix}3-like-page`) });
 
     // total liker (user-list-popover is commented out because it is sometimes displayed and sometimes not.)
@@ -78,6 +79,7 @@ context('Click page icons button', () => {
     })
     cy.getByTestid('like-button-tooltip').should('not.exist');
 
+    cy.waitUntilSpinnerDisappear();
     cy.get('#grw-subnav-container').within(() => { cy.screenshot(`${ssPrefix}5-dislike-page`) });
 
     // total liker (user-list-popover is commented out because it is sometimes displayed and sometimes not.)
@@ -88,7 +90,7 @@ context('Click page icons button', () => {
 
   it('Successfully Bookmark / Unbookmark a page', () => {
     cy.visit('/Sandbox');
-    cy.waitUntilSkeletonDisappear();
+    cy.collapseSidebar(true);
 
     // bookmark
     cy.get('#bookmark-button').click({force: true});
@@ -102,11 +104,13 @@ context('Click page icons button', () => {
     })
     cy.getByTestid('bookmark-button-tooltip').should('not.exist');
 
+    cy.waitUntilSpinnerDisappear();
     cy.get('#grw-subnav-container').within(() => { cy.screenshot(`${ssPrefix}7-bookmark-page`) });
 
     // total bookmarker
     cy.get('#po-total-bookmarks').click({force: true});
     cy.get('.user-list-popover').should('be.visible');
+    cy.waitUntilSpinnerDisappear();
     cy.get('#grw-subnav-container').within(() => { cy.screenshot(`${ssPrefix}8-bookmarks-counter`) });
 
     // unbookmark
@@ -121,11 +125,13 @@ context('Click page icons button', () => {
     })
     cy.getByTestid('bookmark-button-tooltip').should('not.exist');
 
+    cy.waitUntilSpinnerDisappear();
     cy.get('#grw-subnav-container').within(() => { cy.screenshot(`${ssPrefix}9-unbookmark-page`) });
 
     // total bookmarker
     cy.get('#po-total-bookmarks').click({force: true});
     cy.get('.user-list-popover').should('be.visible');
+    cy.waitUntilSpinnerDisappear();
     cy.get('#grw-subnav-container').within(() => { cy.screenshot(`${ssPrefix}10-bookmarks-counter`) });
   });
 

+ 119 - 257
packages/app/test/cypress/integration/20-basic-features/20-basic-features--use-tools.spec.ts

@@ -1,25 +1,3 @@
-context('Switch Sidebar content', { scrollBehavior: false }, () => {
-  const ssPrefix = 'switch-sidebar-content';
-
-  beforeEach(() => {
-    // login
-    cy.fixture("user-admin.json").then(user => {
-      cy.login(user.username, user.password);
-    });
-  });
-
-  it('PageTree is successfully shown', () => {
-    cy.visit('/page');
-    cy.collapseSidebar(false);
-    cy.waitUntilSkeletonDisappear();
-
-    cy.getByTestid('grw-sidebar-nav-primary-page-tree').click();
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(1500);
-    cy.screenshot(`${ssPrefix}-pagetree-after-load`);
-  });
-});
-
 context('Modal for page operation', () => {
 
   const ssPrefix = 'modal-for-page-operation-';
@@ -33,12 +11,13 @@ context('Modal for page operation', () => {
 
   it("PageCreateModal is shown and closed successfully", () => {
     cy.visit('/');
-    cy.waitUntilSkeletonDisappear();
 
-    cy.getByTestid('newPageBtn').click();
-
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(1000) // Wait for animation to finish when the Create Page button is pressed
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('newPageBtn').click({force: true});
+      // wait until
+      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
+    });
 
     cy.getByTestid('page-create-modal').should('be.visible').within(() => {
       cy.screenshot(`${ssPrefix}new-page-modal-opened`);
@@ -52,9 +31,13 @@ context('Modal for page operation', () => {
   it("Successfully Create Today's page", () => {
     const pageName = "Today's page";
     cy.visit('/');
-    cy.waitUntilSkeletonDisappear();
 
-    cy.getByTestid('newPageBtn').click();
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('newPageBtn').click({force: true});
+      // wait until
+      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
+    });
 
     cy.getByTestid('page-create-modal').should('be.visible').within(() => {
       cy.get('.page-today-input2').type(pageName);
@@ -67,10 +50,7 @@ context('Modal for page operation', () => {
 
     cy.getByTestid('grw-contextual-sub-nav').should('be.visible');
 
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(300);
-
-    cy.collapseSidebar(true, true);
+    cy.collapseSidebar(true);
     cy.waitUntilSkeletonDisappear();
     cy.screenshot(`${ssPrefix}create-today-page`);
   });
@@ -78,16 +58,17 @@ context('Modal for page operation', () => {
   it('Successfully create page under specific path', () => {
     const pageName = 'child';
 
-    cy.visit('/Sandbox');
-    cy.waitUntilSkeletonDisappear();
-
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(1000);
+    cy.visit('/foo/bar');
 
-    cy.getByTestid('newPageBtn').click();
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('newPageBtn').click({force: true});
+      // wait until
+      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
+    });
 
     cy.getByTestid('page-create-modal').should('be.visible').within(() => {
-      cy.get('.rbt-input-main').should('have.value', '/Sandbox/');
+      cy.get('.rbt-input-main').should('have.value', '/foo/bar/');
       cy.get('.rbt-input-main').type(pageName);
       cy.screenshot(`${ssPrefix}under-path-add-page-name`);
       cy.getByTestid('btn-create-page-under-below').click();
@@ -98,9 +79,6 @@ context('Modal for page operation', () => {
 
     cy.getByTestid('grw-contextual-sub-nav').should('be.visible');
 
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(300);
-
     cy.waitUntilSkeletonDisappear();
     cy.collapseSidebar(true);
     cy.screenshot(`${ssPrefix}create-page-under-specific-page`);
@@ -108,12 +86,15 @@ context('Modal for page operation', () => {
 
   it('Trying to create template page under the root page fail', () => {
     cy.visit('/');
-    cy.waitUntilSkeletonDisappear();
 
-    cy.getByTestid('newPageBtn').click();
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('newPageBtn').click({force: true});
+      // wait until
+      return cy.getByTestid('page-create-modal').then($elem => $elem.is(':visible'));
+    });
 
     cy.getByTestid('page-create-modal').should('be.visible').within(() => {
-
       cy.getByTestid('grw-page-create-modal-path-name').should('have.text', '/');
 
       cy.get('#template-type').click();
@@ -138,7 +119,6 @@ context('Modal for page operation', () => {
 
   it('Page Deletion and PutBack is executed successfully', { scrollBehavior: false }, () => {
     cy.visit('/Sandbox/Bootstrap4');
-    cy.waitUntilSkeletonDisappear();
 
     cy.get('#grw-subnav-container').within(() => {
       cy.getByTestid('open-page-item-control-btn').click({force: true});
@@ -229,58 +209,56 @@ context('Page Accessories Modal', () => {
     cy.fixture("user-admin.json").then(user => {
       cy.login(user.username, user.password);
     });
+
+    cy.visit('/Sandbox/Bootstrap4');
+
+    cy.getByTestid('grw-contextual-sub-nav').as('subnav').should('be.visible').within(() => {
+      cy.getByTestid('open-page-item-control-btn').as('pageItemControlBtn').should('be.visible');
+    });
+    cy.waitUntil(() => {
+      // do
+      cy.get('@pageItemControlBtn').click();
+      // wait until
+      return cy.get('.dropdown-menu.show').then($elem => $elem.is(':visible'));
+    });
+
   });
 
   it('Page History is shown successfully', () => {
-     cy.visit('/Sandbox/Bootstrap4');
-     cy.waitUntilSkeletonDisappear();
-
-     cy.get('#grw-subnav-container').within(() => {
-      cy.getByTestid('open-page-item-control-btn').within(() => {
-        cy.get('button.btn-page-item-control').click({force: true});
-      });
+    cy.get('.dropdown-menu.show').should('be.visible').within(() => {
       cy.getByTestid('open-page-accessories-modal-btn-with-history-tab').click({force: true});
     });
 
-     cy.getByTestid('page-history').should('be.visible');
-     cy.collapseSidebar(true);
-     cy.screenshot(`${ssPrefix}-open-page-history-bootstrap4`);
+    cy.getByTestid('page-history').should('be.visible');
+
+    cy.collapseSidebar(true, true);
+    cy.waitUntilSpinnerDisappear();
+    cy.screenshot(`${ssPrefix}-open-page-history-bootstrap4`);
   });
 
   it('Page Attachment Data is shown successfully', () => {
-     cy.visit('/Sandbox/Bootstrap4');
-     cy.waitUntilSkeletonDisappear();
-
-     cy.get('#grw-subnav-container').within(() => {
-      cy.getByTestid('open-page-item-control-btn').within(() => {
-        cy.get('button.btn-page-item-control').click({force: true});
-      });
+    cy.get('.dropdown-menu.show').should('be.visible').within(() => {
       cy.getByTestid('open-page-accessories-modal-btn-with-attachment-data-tab').click({force: true});
     });
 
-     cy.getByTestid('page-attachment').should('be.visible').contains('No attachments yet.');
+    cy.waitUntilSpinnerDisappear();
+    cy.getByTestid('page-attachment').should('be.visible').contains('No attachments yet.');
 
-     cy.collapseSidebar(true);
-     cy.screenshot(`${ssPrefix}-open-page-attachment-data-bootstrap4`);
+    cy.collapseSidebar(true);
+    cy.screenshot(`${ssPrefix}-open-page-attachment-data-bootstrap4`);
   });
 
   it('Share Link Management is shown successfully', () => {
-    cy.visit('/Sandbox/Bootstrap4');
-    cy.waitUntilSkeletonDisappear();
-
-    cy.get('#grw-subnav-container').within(() => {
-      cy.getByTestid('open-page-item-control-btn').within(() => {
-        cy.get('button.btn-page-item-control').click({force: true});
-      });
-      cy.getByTestid('open-page-accessories-modal-btn-with-share-link-management-data-tab').should('be.visible');
-      cy.getByTestid('open-page-accessories-modal-btn-with-share-link-management-data-tab').click();
-   });
+    cy.get('.dropdown-menu.show').should('be.visible').within(() => {
+      cy.getByTestid('open-page-accessories-modal-btn-with-share-link-management-data-tab').click({force: true});
+    });
 
-   cy.getByTestid('page-accessories-modal').should('be.visible');
-   cy.getByTestid('share-link-management').should('be.visible');
+    cy.waitUntilSpinnerDisappear();
+    cy.getByTestid('page-accessories-modal').should('be.visible');
+    cy.getByTestid('share-link-management').should('be.visible');
 
-   cy.collapseSidebar(true);
-   cy.screenshot(`${ssPrefix}-open-share-link-management-bootstrap4`);
+    cy.collapseSidebar(true);
+    cy.screenshot(`${ssPrefix}-open-share-link-management-bootstrap4`);
   });
 });
 
@@ -297,209 +275,93 @@ context('Tag Oprations', { scrollBehavior: false }, () =>{
     const ssPrefix = 'tag-operations-add-new-tag-'
     const tag = 'we';
 
-    cy.visit('/Sandbox');
-    cy.waitUntilSkeletonDisappear();
+    cy.visit('/Sandbox/Bootstrap4');
 
-    cy.get('#edit-tags-btn-wrapper-for-tooltip > a').should('be.visible');
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(200);
-    cy.get('#edit-tags-btn-wrapper-for-tooltip > a').click();
-    cy.get('#edit-tag-modal').should('be.visible').screenshot(`${ssPrefix}1-edit-tag-input`);
+    // Add tag
+    cy.get('#edit-tags-btn-wrapper-for-tooltip').as('edit-tag-tooltip').should('be.visible');
 
-    cy.get('#edit-tag-modal').within(() => {
-      cy.get('.rbt-input-main').type(tag, {force: true});
-      cy.get('#tag-typeahead-asynctypeahead').should('be.visible');
-      cy.get('#tag-typeahead-asynctypeahead-item-0').should('be.visible');
-      cy.screenshot(`${ssPrefix}2-type-tag-name`);
+    // open Edit Tags Modal
+    cy.waitUntil(() => {
+      // do
+      cy.get('@edit-tag-tooltip').find('a').click({force: true});
+      // wait until
+      return cy.get('#edit-tag-modal').then($elem => $elem.is(':visible'));
     });
 
-    cy.get('#edit-tag-modal').within(() => {
+    cy.collapseSidebar(true);
+    cy.get('#edit-tag-modal').should('be.visible').screenshot(`${ssPrefix}1-edit-tag-input`);
+
+    cy.get('#edit-tag-modal').should('be.visible').within(() => {
+      cy.get('.rbt-input-main').type(tag);
       cy.get('#tag-typeahead-asynctypeahead').should('be.visible');
       cy.get('#tag-typeahead-asynctypeahead-item-0').should('be.visible');
-      cy.get('a#tag-typeahead-asynctypeahead-item-0').click({force: true})
-      cy.screenshot(`${ssPrefix}3-insert-tag-name`);
-    });
-
-    cy.get('#edit-tag-modal').within(() => {
+      // select
+      cy.get('a#tag-typeahead-asynctypeahead-item-0').click();
+      // save
       cy.get('div.modal-footer > button').click();
     });
 
     cy.get('.toast').should('be.visible').trigger('mouseover');
     cy.get('.grw-taglabels-container > .grw-tag-labels > a').contains(tag).should('exist');
-    /* eslint-disable cypress/no-unnecessary-waiting */
-    cy.wait(150); // wait for toastr to change its color occured by mouseover
-    cy.collapseSidebar(true);
-    cy.screenshot(`${ssPrefix}4-click-done`);
-  });
 
-  it('Successfully duplicate page by generated tag', () => {
-    const ssPrefix = 'tag-operations-page-duplicate-';
-    const tag = 'we';
-    const newPageName = 'our';
+    cy.screenshot(`${ssPrefix}2-click-done`);
+  });
 
-    cy.visit('/Sandbox');
-    cy.waitUntilSkeletonDisappear();
+});
 
-    cy.get('.grw-tag-label').should('be.visible').contains(tag).click();
+context('Shortcuts', () => {
+  const ssPrefix = 'shortcuts';
 
-    // Search result page
-    cy.getByTestid('search-result-base').should('be.visible');
-    cy.getByTestid('search-result-list').should('be.visible');
-    cy.getByTestid('search-result-content', { timeout: 60000 }).should('be.visible');
-    cy.get('#revision-loader', { timeout: 60000 }).contains('Table of Contents', { timeout: 60000 });
+  beforeEach(() => {
+    // login
+    cy.fixture("user-admin.json").then(user => {
+      cy.login(user.username, user.password);
+    });
+  });
 
-    // force to add 'active' to pass VRT: https://github.com/weseek/growi/pull/6603
-    cy.getByTestid('page-list-item-L').first().invoke('addClass', 'active');
-    cy.collapseSidebar(true);
-    cy.screenshot(`${ssPrefix}1-click-tag-name`);
-    cy.getByTestid('search-result-list').should('be.visible').then(($el)=>{
-      cy.wrap($el).within(()=>{
-        cy.getByTestid('open-page-item-control-btn').first().click();
-      });
+  it('Successfully updating a page using a shortcut on a previously created page', { scrollBehavior: false }, () => {
+    const body1 = 'hello';
+    const body2 = ' world!';
+    const savePageShortcutKey = '{ctrl+s}';
 
-      // eslint-disable-next-line cypress/no-unnecessary-waiting
-      cy.wait(1500); // for wait rendering pagelist info
-      cy.collapseSidebar(true);
-      cy.screenshot(`${ssPrefix}2-click-three-dots-menu`);
+    cy.visit('/Sandbox/child');
 
-      cy.wrap($el).within(()=>{
-        cy.getByTestid('open-page-item-control-btn').first().within(()=>{
-          cy.getByTestid('open-page-duplicate-modal-btn').click();
-        })
+    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.getByTestid('page-duplicate-modal').should('be.visible').within(() => {
-      cy.get('.rbt-input-main').type(`-${newPageName}`, {force: true});
-    }).screenshot(`${ssPrefix}3-duplicate-page`);
-
-    cy.getByTestid('page-duplicate-modal').within(() => {
-      cy.intercept('POST', '/_api/v3/pages/duplicate').as('duplicate');
-      cy.get('.modal-footer > button.btn').click();
-      // Wait for completion of request to '/_api/v3/pages/duplicate'
-      cy.wait('@duplicate')
-    });
-
-    cy.visit(`Sandbox-${newPageName}`);
-    cy.waitUntilSkeletonDisappear();
-    cy.collapseSidebar(true);
-    cy.screenshot(`${ssPrefix}4-duplicated-page`);
-  });
-
-  it('Successfully rename page from generated tag', () => {
-    const ssPrefix = 'tag-operations-page-rename-';
-    const tag = 'we';
-    const oldPageName = '/Sandbox-our';
-    const newPageName = '/Sandbox-us';
-
-    cy.visit(oldPageName);
-    cy.waitUntilSkeletonDisappear();
-
-    cy.get('.grw-tag-label').should('be.visible').contains(tag).click();
+    cy.get('.grw-editor-navbar-bottom').should('be.visible');
 
-    // Search result page
-    cy.getByTestid('search-result-base').should('be.visible');
-    cy.getByTestid('search-result-list').should('be.visible');
-    cy.getByTestid('search-result-content', { timeout: 60000 }).should('be.visible');
-    cy.get('#revision-loader', { timeout: 60000 }).contains('Table of Contents', { timeout: 60000 });
+    // 1st
+    cy.get('.CodeMirror').type(body1);
+    cy.get('.CodeMirror').contains(body1);
+    cy.get('.page-editor-preview-body').contains(body1);
+    cy.get('.CodeMirror').type(savePageShortcutKey);
 
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(300);
-    cy.collapseSidebar(true);
-    cy.screenshot(`${ssPrefix}1-click-tag-name`);
-
-    cy.getByTestid('search-result-list').within(() => {
-      cy.get('.list-group-item').each(($row) => {
-        if($row.find('a').text() === oldPageName){
-          cy.wrap($row).within(() => {
-            cy.getByTestid('open-page-item-control-btn').first().click();
-            cy.getByTestid('page-item-control-menu').should('have.class', 'show').then(() => {
-              // empty sentence in page list empty: https://github.com/weseek/growi/pull/6880
-              cy.getByTestid('revision-short-body-in-page-list-item-L').invoke('text', '');
-            });
-
-            cy.getByTestid('page-item-control-menu').within(()=>{
-              cy.getByTestid('open-page-delete-modal-btn');
-              cy.screenshot(`${ssPrefix}2-open-page-item-control-menu`);
-            })
-          });
-        }
-      });
+    cy.get('.Toastify__toast').should('be.visible').within(() => {
+      cy.get('.Toastify__close-button').should('be.visible').click();
+      cy.get('.Toastify__progress-bar').invoke('attr', 'style', 'display: none')
     });
+    cy.screenshot(`${ssPrefix}-update-page-1`);
 
-    cy.getByTestid('search-result-list').within(() => {
-      cy.get('.list-group-item').each(($row) => {
-        if($row.find('a').text() === oldPageName){
-          cy.wrap($row).within(() => {
-            cy.getByTestid('open-page-move-rename-modal-btn').click({force: true});
-          });
-        }
-      });
-    });
+    cy.get('.Toastify').should('not.be.visible');
 
-    cy.getByTestid('page-rename-modal').should('be.visible').within(() => {
-      cy.get('.rbt-input-main').clear().type(newPageName,{force: true});
-    }).screenshot(`${ssPrefix}3-insert-new-page-name`);
+    // 2nd
+    cy.get('.CodeMirror').type(body2);
+    cy.get('.CodeMirror').contains(body2);
+    cy.get('.page-editor-preview-body').contains(body2);
+    cy.get('.CodeMirror').type(savePageShortcutKey);
 
-    cy.getByTestid('page-rename-modal').should('be.visible').within(() => {
-      cy.intercept('PUT', '/_api/v3/pages/rename').as('rename');
-      cy.getByTestid('grw-page-rename-button').should('not.be.disabled').click();
-      // Wait for completion of request to '/_api/v3/pages/rename'
-      cy.wait('@rename')
+    cy.get('.Toastify__toast').should('be.visible').within(() => {
+      cy.get('.Toastify__close-button').should('be.visible').click();
+      cy.get('.Toastify__progress-bar').invoke('attr', 'style', 'display: none')
     });
-
-    cy.visit(newPageName);
-    cy.waitUntilSkeletonDisappear();
-
-    cy.getByTestid('grw-tag-labels').should('be.visible')
-    cy.collapseSidebar(true);
-    cy.screenshot(`${ssPrefix}4-new-page-name-applied`);
+    cy.screenshot(`${ssPrefix}-update-page-2`);
   });
 });
-
-// context('Shortcuts', () => {
-//   const ssPrefix = 'shortcuts';
-
-//   beforeEach(() => {
-//     // login
-//     cy.fixture("user-admin.json").then(user => {
-//       cy.login(user.username, user.password);
-//     });
-//   });
-
-//   it('Successfully updating a page using a shortcut on a previously created page', { scrollBehavior: false }, () => {
-//     const body1 = 'hello';
-//     const body2 = 'world';
-//     const savePageShortcutKey = '{ctrl+s}';
-
-//     cy.visit('/Sandbox/child');
-//     cy.waitUntilSkeletonDisappear();
-
-//     cy.get('#grw-subnav-container').within(() => {
-//       cy.getByTestid('editor-button').click();
-//     });
-
-//     cy.get('.layout-root').should('have.class', 'editing');
-//     cy.get('.grw-editor-navbar-bottom').should('be.visible');
-
-//     // 1st
-//     cy.get('.CodeMirror').type(body1);
-//     cy.get('.CodeMirror').contains(body1);
-//     cy.get('.page-editor-preview-body').contains(body1);
-//     cy.get('.CodeMirror').type(savePageShortcutKey);
-
-//     cy.get('.Toastify').should('visible').trigger('mouseover');
-//     cy.screenshot(`${ssPrefix}-update-page-1`);
-//     cy.get('.Toastify__close-button').should('be.visible').click();
-//     cy.get('.Toastify').should('not.be.visible');
-
-//     // 2nd
-//     cy.get('.CodeMirror').type(body2);
-//     cy.get('.CodeMirror').contains(body2);
-//     cy.get('.page-editor-preview-body').contains(body2);
-//     cy.get('.CodeMirror').type(savePageShortcutKey);
-
-//     cy.get('.Toastify').should('visible').trigger('mouseover');
-//     cy.screenshot(`${ssPrefix}-update-page-2`);
-//   });
-// });

+ 2 - 2
packages/app/test/cypress/integration/21-basic-features-for-guest/21-basic-features-for-guest--access-to-page.spec.ts

@@ -4,7 +4,7 @@ context('Access to page by guest', () => {
   it('/Sandbox is successfully loaded', () => {
     cy.visit('/Sandbox');
     cy.getByTestid('grw-pagetree-item-container').should('be.visible');
-    cy.collapseSidebar(true);
+    cy.collapseSidebar(true, true);
     cy.screenshot(`${ssPrefix}-sandbox`);
   });
 
@@ -18,7 +18,7 @@ context('Access to page by guest', () => {
     // hide fab // disable fab for sticky-events warning
     // cy.getByTestid('grw-fab-container').invoke('attr', 'style', 'display: none');
 
-    cy.collapseSidebar(true, true);
+    cy.collapseSidebar(true);
     cy.screenshot(`${ssPrefix}-sandbox-headers`);
   });
 

+ 204 - 111
packages/app/test/cypress/integration/30-search/30-search--search.spec.ts

@@ -1,13 +1,12 @@
 context('Access to search result page', () => {
   const ssPrefix = 'access-to-result-page-directly-';
 
+
   beforeEach(() => {
     // login
     cy.fixture("user-admin.json").then(user => {
       cy.login(user.username, user.password);
     });
-    // collapse sidebar
-    cy.collapseSidebar(true);
   });
 
   it('/_search with "q" param is successfully loaded', () => {
@@ -19,12 +18,17 @@ context('Access to search result page', () => {
     cy.get('.wiki').should('be.visible');
     // for avoid mismatch by auto scrolling
     cy.get('.search-result-content-body-container').scrollTo('top');
+
+    cy.collapseSidebar(true, true);
+    cy.waitUntilSkeletonDisappear();
     cy.screenshot(`${ssPrefix}with-q`);
   });
 
   it('checkboxes behaviors', () => {
     cy.visit('/_search', { qs: { q: 'labels alerts cards blocks' } });
 
+    cy.collapseSidebar(true);
+
     cy.getByTestid('search-result-base').should('be.visible');
     cy.getByTestid('search-result-list').should('be.visible');
     cy.getByTestid('search-result-content').should('be.visible');
@@ -36,7 +40,9 @@ context('Access to search result page', () => {
     cy.getByTestid('page-list-item-L').first().invoke('addClass', 'active');
 
     cy.getByTestid('cb-select').first().click({force: true});
+
     cy.screenshot(`${ssPrefix}the-first-checkbox-on`);
+
     cy.getByTestid('cb-select').first().click({force: true});
     cy.screenshot(`${ssPrefix}the-first-checkbox-off`);
 
@@ -61,8 +67,6 @@ context('Access to legacy private pages', () => {
     cy.fixture("user-admin.json").then(user => {
       cy.login(user.username, user.password);
     });
-    // collapse sidebar
-    cy.collapseSidebar(true);
   });
 
   it('/_private-legacy-pages is successfully loaded', () => {
@@ -71,6 +75,8 @@ context('Access to legacy private pages', () => {
     cy.getByTestid('search-result-base').should('be.visible');
     cy.getByTestid('search-result-private-legacy-pages').should('be.visible');
 
+    cy.collapseSidebar(true);
+    cy.waitUntilSkeletonDisappear();
     cy.screenshot(`${ssPrefix}shown`);
   });
 
@@ -84,14 +90,14 @@ context('Search all pages', () => {
     cy.fixture("user-admin.json").then(user => {
       cy.login(user.username, user.password);
     });
-    // collapse sidebar
-    cy.collapseSidebar(true);
   });
 
   it(`Search all pages by word is successfully loaded`, () => {
     const searchText = 'help';
 
     cy.visit('/');
+
+    cy.collapseSidebar(true, true);
     cy.waitUntilSkeletonDisappear();
 
     cy.get('.rbt-input').click();
@@ -102,108 +108,62 @@ context('Search all pages', () => {
     cy.get('.rbt-input-main').type(`${searchText}`);
     cy.screenshot(`${ssPrefix}2-insert-search-text`, { capture: 'viewport'});
     cy.get('.rbt-input-main').type('{enter}');
-
-
-    cy.getByTestid('search-result-base').should('be.visible');
-    cy.getByTestid('search-result-list').should('be.visible');
-    cy.getByTestid('search-result-content').should('be.visible');
-    cy.get('.wiki').should('be.visible');
-    // force to add 'active' to pass VRT: https://github.com/weseek/growi/pull/6603
-    cy.getByTestid('page-list-item-L').first().invoke('addClass', 'active');
-    // for avoid mismatch by auto scrolling
-    cy.get('.search-result-content-body-container').scrollTo('top');
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(1500);
-    cy.screenshot(`${ssPrefix}3-search-page-results`, { capture: 'viewport'});
-
-    // TODO: chlick three dots bottom, collapse sidebar doesn't working.
-    cy.getByTestid('open-page-item-control-btn').eq(1).click();
-    cy.getByTestid('search-result-content').should('be.visible');
-    cy.get('.wiki').should('be.visible');
-    // for avoid mismatch by auto scrolling
-    cy.get('.search-result-content-body-container').scrollTo('top');
-    cy.screenshot(`${ssPrefix}4-click-three-dots-menu`, {capture: 'viewport'});
-
-    // Add bookmark
-    cy.getByTestid('add-remove-bookmark-btn').click({force: true});
-    cy.get('.btn-bookmark.active').should('be.visible');
-    cy.screenshot(`${ssPrefix}5-add-bookmark`, {capture: 'viewport'});
-
-    // Duplicate page
-    cy.getByTestid('open-page-duplicate-modal-btn').first().click({force: true});
-    cy.getByTestid('page-duplicate-modal').should('be.visible').within(() => {
-      cy.screenshot(`${ssPrefix}6-duplicate-page`);
-    });
-
-    // Close Modal
-    cy.get('body').type('{esc}');
-
-    // Move / Rename Page
-    cy.getByTestid('open-page-move-rename-modal-btn').first().click({force: true});
-    cy.getByTestid('page-rename-modal').should('be.visible').within(() => {
-      cy.screenshot(`${ssPrefix}7-move-rename-page`);
-    });
-
-    // Close Modal
-    cy.get('body').type('{esc}');
-
-    // Delete page
-    cy.getByTestid('open-page-delete-modal-btn').first().click({ force: true});
-    cy.getByTestid('page-delete-modal').should('be.visible').within(() => {
-      cy.screenshot(`${ssPrefix}8-delete-page`);
-    });
   });
 
   it(`Search all pages by tag is successfully loaded `, () => {
     const tag = 'help';
     const searchText = `tag:${tag}`;
+
     cy.visit('/');
-    cy.waitUntilSkeletonDisappear();
 
     // Add tag
     cy.get('#edit-tags-btn-wrapper-for-tooltip').as('edit-tag-tooltip').should('be.visible');
-    cy.get('@edit-tag-tooltip').within(()=>{
-      cy.get('a').should('be.visible').click();
-    })
-    cy.get('#edit-tag-modal').as('tag-modal').should('be.visible');
 
-    cy.get('@tag-modal').within(() => {
+    // open Edit Tags Modal
+    cy.waitUntil(() => {
+      // do
+      cy.get('@edit-tag-tooltip').find('a').click({force: true});
+      // wait until
+      return cy.get('#edit-tag-modal').then($elem => $elem.is(':visible'));
+    });
+
+    cy.get('#edit-tag-modal').should('be.visible').within(() => {
       cy.get('.rbt-input-main').type(tag);
       cy.get('#tag-typeahead-asynctypeahead').should('be.visible');
       cy.get('#tag-typeahead-asynctypeahead-item-0').should('be.visible');
-      cy.get('a#tag-typeahead-asynctypeahead-item-0').click()
-    });
-
-    cy.get('#edit-tag-modal').within(() => {
+      // select
+      cy.get('a#tag-typeahead-asynctypeahead-item-0').click();
+      // save
       cy.get('div.modal-footer > button').click();
     });
 
     cy.visit('/');
-    cy.waitUntilSkeletonDisappear();
 
     cy.get('.rbt-input').should('be.visible');
     cy.get('.rbt-input').click();
     cy.get('.rbt-input-main').type(`${searchText}`);
+
+    cy.collapseSidebar(true);
+    cy.waitUntilSkeletonDisappear();
     cy.screenshot(`${ssPrefix}1-insert-search-text-with-tag`, { capture: 'viewport'});
+
     cy.get('.rbt-input-main').type('{enter}');
 
     cy.getByTestid('search-result-base').should('be.visible');
     cy.getByTestid('search-result-list').should('be.visible');
     cy.getByTestid('search-result-content').should('be.visible');
     cy.get('.wiki').should('be.visible');
-    cy.waitUntilSpinnerDisappear();
 
     // force to add 'active' to pass VRT: https://github.com/weseek/growi/pull/6603
     cy.getByTestid('page-list-item-L').first().invoke('addClass', 'active');
-    cy.screenshot(`${ssPrefix}2-search-with-tag-result`, {capture: 'viewport'});
 
-    cy.getByTestid('search-result-content').should('be.visible');
-    cy.get('.wiki').should('be.visible');
-    cy.screenshot(`${ssPrefix}3-click-three-dots-menu-search-with-tag`, {capture: 'viewport'});
+    cy.collapseSidebar(true);
+    cy.waitUntilSpinnerDisappear();
+    cy.waitUntilSkeletonDisappear();
+    cy.screenshot(`${ssPrefix}2-search-with-tag-result`, {capture: 'viewport'});
 
   });
 
-  // TODO: fix this VRT
   it('Successfully order page search results by tag', () => {
     const tag = 'help';
 
@@ -213,50 +173,185 @@ context('Search all pages', () => {
     cy.getByTestid('search-result-list').should('be.visible');
     cy.getByTestid('search-result-content').should('be.visible');
     cy.get('.wiki').should('be.visible');
-    cy.waitUntilSpinnerDisappear();
 
     // force to add 'active' to pass VRT: https://github.com/weseek/growi/pull/6603
     cy.getByTestid('page-list-item-L').first().invoke('addClass', 'active');
+
+    cy.collapseSidebar(true);
+    cy.waitUntilSkeletonDisappear();
+    cy.waitUntilSpinnerDisappear();
     cy.screenshot(`${ssPrefix}1-tag-order-click-tag-name`, {capture: 'viewport'});
 
-    cy.get('.grw-search-page-nav').within(() => {
-      cy.get('button.dropdown-toggle').first().click({force: true});
-      cy.get('.dropdown-menu-right').should('be.visible');
-      cy.get('.dropdown-menu-right > button:nth-child(1)').click({force: true});
+  });
+
+});
+
+context('Sort with dropdown', () => {
+  const ssPrefix = 'sort-with-dropdown-';
+
+  beforeEach(() => {
+    // login
+    cy.fixture("user-admin.json").then(user => {
+      cy.login(user.username, user.password);
     });
+
+    cy.visit('/_search', { qs: { q: 'sand' } });
+
     cy.getByTestid('search-result-base').should('be.visible');
     cy.getByTestid('search-result-list').should('be.visible');
     cy.getByTestid('search-result-content').should('be.visible');
-    // cy.get('.wiki').should('be.visible');
-    // cy.screenshot(`${ssPrefix}2-tag-order-by-relevance`);
+    cy.get('.wiki').should('be.visible');
 
-    cy.get('.grw-search-page-nav').within(() => {
-      cy.get('button.dropdown-toggle').first().click({force: true});
-      cy.get('.dropdown-menu-right').should('be.visible');
-      cy.get('.dropdown-menu-right > button:nth-child(2)').click({force: true});
+    cy.waitUntilSpinnerDisappear();
+    // for avoid mismatch by auto scrolling
+    cy.get('.search-result-content-body-container').scrollTo('top');
+
+    // open sort dropdown
+    cy.waitUntil(() => {
+      // do
+      cy.get('.grw-search-page-nav').within(() => {
+        cy.get('button.dropdown-toggle').first().click({force: true});
+      });
+      // wait until
+      return cy.get('.grw-search-page-nav').within(() => {
+        return Cypress.$('.dropdown-menu.show').is(':visible');
+      });
+    });
+  });
+
+  it('Open sort dropdown', () => {
+    cy.get('.grw-search-page-nav .dropdown-menu.show').should('be.visible');
+      cy.screenshot(`${ssPrefix}2-open-sort-dropdown`);
+  });
+
+  it('Sort by relevance', () => {
+    cy.get('.grw-search-page-nav .dropdown-menu.show').should('be.visible').within(() => {
+      cy.get('button:nth-child(1)').click({force: true});
     });
     cy.getByTestid('search-result-base').should('be.visible');
     cy.getByTestid('search-result-list').should('be.visible');
     cy.getByTestid('search-result-content').should('be.visible');
-    // cy.get('.wiki').should('be.visible');
-    // cy.screenshot(`${ssPrefix}3-tag-order-by-creation-date`);
+    cy.get('.wiki').should('be.visible');
 
-    cy.get('.grw-search-page-nav').within(() => {
-      cy.get('button.dropdown-toggle').first().click({force: true});
-      cy.get('.dropdown-menu-right').should('be.visible');
-      cy.get('.dropdown-menu-right > button:nth-child(3)').click({force: true});
+    cy.waitUntilSpinnerDisappear();
+    // for avoid mismatch by auto scrolling
+    cy.get('.search-result-content-body-container').scrollTo('top');
+    cy.screenshot(`${ssPrefix}3-tag-order-by-relevance`);
+  });
+
+  it('Sort by creation date', () => {
+    cy.get('.grw-search-page-nav .dropdown-menu.show').should('be.visible').within(() => {
+      cy.get('button:nth-child(2)').click({force: true});
     });
     cy.getByTestid('search-result-base').should('be.visible');
     cy.getByTestid('search-result-list').should('be.visible');
     cy.getByTestid('search-result-content').should('be.visible');
-    // cy.get('.wiki').should('be.visible');
+    cy.get('.wiki').should('be.visible');
+
     cy.waitUntilSpinnerDisappear();
+    // for avoid mismatch by auto scrolling
+    cy.get('.search-result-content-body-container').scrollTo('top');
+    cy.screenshot(`${ssPrefix}3-tag-order-by-creation-date`);
+  });
 
-    // cy.screenshot(`${ssPrefix}4-tag-order-by-last-update-date`);
+  it('Sort by last update date', () => {
+    cy.get('.grw-search-page-nav .dropdown-menu.show').should('be.visible').within(() => {
+      cy.get('button:nth-child(3)').click({force: true});
+    });
+    cy.getByTestid('search-result-base').should('be.visible');
+    cy.getByTestid('search-result-list').should('be.visible');
+    cy.getByTestid('search-result-content').should('be.visible');
+    cy.get('.wiki').should('be.visible');
+
+    cy.waitUntilSpinnerDisappear();
+    // for avoid mismatch by auto scrolling
+    cy.get('.search-result-content-body-container').scrollTo('top');
+    cy.screenshot(`${ssPrefix}4-tag-order-by-last-update-date`);
   });
 
 });
 
+
+context('Search and use', () => {
+  const ssPrefix = 'search-and-use-';
+
+  beforeEach(() => {
+    // login
+    cy.fixture("user-admin.json").then(user => {
+      cy.login(user.username, user.password);
+    });
+
+    cy.visit('/_search', { qs: { q: 'labels alerts cards blocks' } });
+    cy.getByTestid('search-result-base').should('be.visible');
+    cy.getByTestid('search-result-list').should('be.visible');
+    cy.getByTestid('search-result-content').should('be.visible');
+    cy.get('.wiki').should('be.visible');
+
+    cy.getByTestid('page-list-item-L').first().as('firstItem');
+
+    // force to add 'active' to pass VRT: https://github.com/weseek/growi/pull/6603
+    cy.get('@firstItem').invoke('addClass', 'active');
+    // for avoid mismatch by auto scrolling
+    cy.get('.search-result-content-body-container').scrollTo('top');
+
+    cy.waitUntil(() => {
+      // do
+      cy.get('@firstItem').within(() => {
+        cy.getByTestid('open-page-item-control-btn').click();
+      });
+      // wait until
+      return cy.get('.dropdown-menu.show').then($elem => $elem.is(':visible'));
+    });
+  });
+
+  it('Successfully the dropdown is opened', () => {
+    cy.get('.dropdown-menu.show').should('be.visible');
+    cy.screenshot(`${ssPrefix}1-click-three-dots-menu`, {capture: 'viewport'});
+  });
+
+  it('Successfully add bookmark', () => {
+    cy.get('.dropdown-menu.show').should('be.visible').within(() => {
+      // Add bookmark
+      cy.getByTestid('add-remove-bookmark-btn').click({force: true});
+    });
+    cy.getByTestid('search-result-content').within(() => {
+      cy.get('.btn-bookmark.active').should('be.visible');
+    });
+    cy.screenshot(`${ssPrefix}2-add-bookmark`, {capture: 'viewport'});
+  });
+
+  it('Successfully open duplicate modal', () => {
+    cy.get('.dropdown-menu.show').should('be.visible').within(() => {
+      cy.getByTestid('open-page-duplicate-modal-btn').click({force: true});
+    });
+    cy.getByTestid('page-duplicate-modal').should('be.visible').within(() => {
+      cy.screenshot(`${ssPrefix}3-duplicate-page`);
+    });
+    // Close Modal
+    cy.get('body').type('{esc}');
+  });
+
+  it('Successfully open move/rename modal', () => {
+    cy.get('.dropdown-menu.show').should('be.visible').within(() => {
+      cy.getByTestid('open-page-move-rename-modal-btn').click({force: true});
+    });
+    cy.getByTestid('page-rename-modal').should('be.visible').within(() => {
+      cy.screenshot(`${ssPrefix}4-move-rename-page`);
+    });
+    // Close Modal
+    cy.get('body').type('{esc}');
+  });
+
+  it('Successfully open delete modal', () => {
+    cy.get('.dropdown-menu.show').should('be.visible').within(() => {
+      cy.getByTestid('open-page-delete-modal-btn').click({ force: true});
+    });
+    cy.getByTestid('page-delete-modal').should('be.visible').within(() => {
+      cy.screenshot(`${ssPrefix}5-delete-page`);
+    });
+  });
+})
+
 context('Search current tree with "prefix":', () => {
   const ssPrefix = 'search-current-tree-';
 
@@ -265,21 +360,31 @@ context('Search current tree with "prefix":', () => {
     cy.fixture("user-admin.json").then(user => {
       cy.login(user.username, user.password);
     });
-    // collapse sidebar
-    cy.collapseSidebar(true);
   });
 
   it(`Search current tree by word is successfully loaded`, () => {
     const searchText = 'help';
+
     cy.visit('/');
     cy.waitUntilSkeletonDisappear();
+    cy.collapseSidebar(true);
 
-    cy.getByTestid('select-search-scope').click();
-    cy.get('.input-group-prepend.show > div > button:nth-child(2)').click();
-    cy.get('.rbt-input').click();
-    cy.get('.rbt-menu.dropdown-menu.show').should('be.visible').within(() => {
+    cy.waitUntil(() => {
+      // do
+      cy.getByTestid('select-search-scope').click();
+      // wait until
+      return cy.get('.grw-global-search-container').within(() => {
+        return Cypress.$('.dropdown-menu.show').is(':visible');
+      });
+    });
+
+    cy.get('.grw-global-search-container').within(() => {
+      cy.get('.dropdown-menu.show').should('be.visible');
+      cy.get('.input-group-prepend.show > div > button:nth-child(2)').click();
+      cy.get('.rbt-input').should('be.focused');
       cy.screenshot(`${ssPrefix}1-search-input-focused`);
-    })
+    });
+
     cy.get('.rbt-input').type(`${searchText}`);
     cy.screenshot(`${ssPrefix}2-insert-search-text`, { capture: 'viewport'});
     cy.get('.rbt-input').type('{enter}');
@@ -294,19 +399,7 @@ context('Search current tree with "prefix":', () => {
     cy.getByTestid('page-list-item-L').first().invoke('addClass', 'active');
     // for avoid mismatch by auto scrolling
     cy.get('.search-result-content-body-container').scrollTo('top');
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(1500);
     cy.screenshot(`${ssPrefix}3-search-page-results`, { capture: 'viewport'});
-
-    cy.getByTestid('search-result-list').within(() => {
-      cy.getByTestid('open-page-item-control-btn').first().click();
-    })
-
-    // for avoid mismatch by auto scrolling
-    cy.get('.search-result-content-body-container').scrollTo('top');
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(1500);
-    cy.screenshot(`${ssPrefix}4-click-three-dots-menu`, {capture: 'viewport'});
   });
 
 });

+ 124 - 56
packages/app/test/cypress/integration/50-sidebar/50-sidebar--access-to-side-bar.spec.ts

@@ -12,15 +12,21 @@ describe('Access to sidebar', () => {
     context('when access to root page', { scrollBehavior: false }, () => {
       beforeEach(() => {
         cy.visit('/');
-        cy.waitUntilSkeletonDisappear();
+
+        // Workaround for waitinig initial open/close interaction
+        // TODO: remove this cy.wait() after SSR without the initial interaction is implemented
+        // eslint-disable-next-line cypress/no-unnecessary-waiting
+        cy.wait(2000);
+
         // Since this is a sidebar test, call collapseSidebar in beforeEach.
         cy.collapseSidebar(false);
       });
 
       describe('Test show/collapse button', () => {
         it('Successfully show sidebar', () => {
-          cy.getByTestid('grw-pagetree-item-container').should('be.visible');
+          cy.getByTestid('grw-contextual-navigation-sub').should('be.visible');
 
+          cy.waitUntilSkeletonDisappear();
           cy.screenshot(`${ssPrefix}1-sidebar-shown`, {
             capture: 'viewport',
             // Blackout for recalculation of toc content hight
@@ -31,6 +37,9 @@ describe('Access to sidebar', () => {
         it('Successfully collapse sidebar', () => {
           cy.getByTestid('grw-navigation-resize-button').click({force: true});
 
+          cy.getByTestid('grw-contextual-navigation-sub').should('not.be.visible');
+
+          cy.waitUntilSkeletonDisappear();
           cy.screenshot(`${ssPrefix}2-sidebar-collapsed`, {
             capture: 'viewport',
             // Blackout for recalculation of toc content hight
@@ -40,10 +49,21 @@ describe('Access to sidebar', () => {
       });
 
       describe('Test page tree tab', () => {
+        beforeEach(() => {
+          cy.getByTestid('grw-sidebar-nav-primary-page-tree').should('be.visible')
+            .then($elem => {
+              // open if inactive
+              if (!$elem.hasClass('active')) {
+                cy.getByTestid('grw-sidebar-nav-primary-page-tree').click();
+              }
+            });
+        });
+
         it('Successfully access to page tree', () => {
           cy.getByTestid('grw-contextual-navigation-sub').within(() => {
             cy.getByTestid('grw-pagetree-item-container').should('be.visible');
 
+            cy.waitUntilSkeletonDisappear();
             cy.screenshot(`${ssPrefix}page-tree-1-access-to-page-tree`);
           });
         });
@@ -60,13 +80,17 @@ describe('Access to sidebar', () => {
         });
 
         it('Successfully click Add to Bookmarks button', () => {
-          // click three dots
-          cy.get('.grw-pagetree-item-children').first().within(() => {
-            cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click();
+          cy.waitUntil(() => {
+            // do
+            cy.getByTestid('grw-contextual-navigation-sub').within(() => {
+              cy.get('.grw-pagetree-item-children').first().as('pagetreeItem').within(() => {
+                cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click()
+              });
+            });
+            // wait until
+            return cy.get('.dropdown-menu.show').then($elem => $elem.is(':visible'));
           });
 
-          cy.getByTestid('page-item-control-menu').should('have.class', 'show');
-
           cy.screenshot(`${ssPrefix}page-tree-3-before-click-button`, {
             // Blackout for recalculation of toc content hight
             blackout: ['.grw-side-contents-container', '[data-hide-in-vrt=true]'],
@@ -76,14 +100,18 @@ describe('Access to sidebar', () => {
           cy.getByTestid('page-item-control-menu').should('have.class', 'show')
           cy.getByTestid('add-remove-bookmark-btn').click();
 
-
           // show dropdown again
-          cy.get('.grw-pagetree-item-children').first().within(() => {
-            cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click();
+          cy.waitUntil(() => {
+            // do
+            cy.getByTestid('grw-contextual-navigation-sub').within(() => {
+              cy.get('.grw-pagetree-item-children').first().as('pagetreeItem').within(() => {
+                cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click()
+              });
+            });
+            // wait until
+            return cy.get('.dropdown-menu.show').then($elem => $elem.is(':visible'));
           });
 
-          cy.getByTestid('page-item-control-menu').should('have.class', 'show');
-
           cy.screenshot(`${ssPrefix}page-tree-4-after-click-button`, {
             // Blackout for recalculation of toc content hight
             blackout: ['.grw-side-contents-container', '[data-hide-in-vrt=true]'],
@@ -91,14 +119,23 @@ describe('Access to sidebar', () => {
         });
 
         it('Successfully show duplicate page modal', () => {
-          cy.get('.grw-pagetree-item-children').first().within(() => {
-            cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click();
+          cy.waitUntil(() => {
+            // do
+            cy.getByTestid('grw-contextual-navigation-sub').within(() => {
+              cy.get('.grw-pagetree-item-children').first().as('pagetreeItem').within(() => {
+                cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click()
+              });
+            });
+            // wait until
+            return cy.get('.dropdown-menu.show').then($elem => $elem.is(':visible'));
           });
-          cy.get('.dropdown-menu.show').should('be.visible').within(() => {
-            cy.getByTestid('open-page-duplicate-modal-btn').click();
+
+          cy.get('.dropdown-menu.show').within(() => {
+            cy.getByTestid('open-page-duplicate-modal-btn').should('be.visible').click();
           });
+
           cy.getByTestid('page-duplicate-modal').should('be.visible').within(() => {
-            cy.get('.rbt-input-main').type('_test');
+            cy.get('.form-control').type('_test');
 
             cy.screenshot(`${ssPrefix}page-tree-5-duplicate-page-modal`);
 
@@ -107,49 +144,67 @@ describe('Access to sidebar', () => {
         });
 
         it('Successfully rename page', () => {
-          cy.getByTestid('grw-contextual-navigation-sub').within(() => {
-            cy.get('.grw-pagetree-item-children').first().within(() => {
-              cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click()
-            });
-            cy.get('.dropdown-menu.show').should('be.visible').within(() => {
-              cy.getByTestid('open-page-move-rename-modal-btn').click();
-            });
-            cy.get('.grw-pagetree-item-children').first().within(() => {
-              cy.getByTestid('closable-text-input').type('_newname');
+          cy.waitUntil(() => {
+            // do
+            cy.getByTestid('grw-contextual-navigation-sub').within(() => {
+              cy.get('.grw-pagetree-item-children').first().as('pagetreeItem').within(() => {
+                cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click()
+              });
             });
+            // wait until
+            return cy.get('.dropdown-menu.show').then($elem => $elem.is(':visible'));
+          });
 
-            cy.screenshot(`${ssPrefix}page-tree-6-rename-page`);
+          cy.get('.dropdown-menu.show').within(() => {
+            cy.getByTestid('open-page-move-rename-modal-btn').should('be.visible').click();
           });
+
+          cy.get('@pagetreeItem').within(() => {
+            cy.getByTestid('closable-text-input').type('_newname');
+          })
+
+          cy.screenshot(`${ssPrefix}page-tree-6-rename-page`);
         });
 
         it('Successfully show delete page modal', () => {
-          cy.getByTestid('grw-contextual-navigation-sub').within(() => {
-            cy.get('.grw-pagetree-item-children').first().within(() => {
-              cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click()
-            });
-            cy.get('.dropdown-menu.show').should('be.visible').within(() => {
-              cy.getByTestid('open-page-delete-modal-btn').click();
+          cy.waitUntil(() => {
+            // do
+            cy.getByTestid('grw-contextual-navigation-sub').within(() => {
+              cy.get('.grw-pagetree-item-children').first().as('pagetreeItem').within(() => {
+                cy.getByTestid('open-page-item-control-btn').find('button').first().invoke('css','display','block').click()
+              });
             });
+            // wait until
+            return cy.get('.dropdown-menu.show').then($elem => $elem.is(':visible'));
           });
-          cy.getByTestid('page-delete-modal').should('be.visible').within(() => {
 
-            cy.screenshot(`${ssPrefix}page-tree-7-delete-page-modal`);
+          cy.get('.dropdown-menu.show').within(() => {
+            cy.getByTestid('open-page-delete-modal-btn').should('be.visible').click();
+          });
 
+          cy.getByTestid('page-delete-modal').should('be.visible').within(() => {
+            cy.screenshot(`${ssPrefix}page-tree-7-delete-page-modal`);
             cy.get('.modal-header > button').click();
           });
         });
       });
 
       describe('Test custom sidebar tab', () => {
-        it('Successfully access to custom sidebar', () => {
-          cy.getByTestid('grw-sidebar-nav-primary-custom-sidebar').click();
-
-          // eslint-disable-next-line cypress/no-unnecessary-waiting
-          cy.wait(1500); // Wait debounce for UserUISettings update
+        beforeEach(() => {
+          cy.getByTestid('grw-sidebar-nav-primary-custom-sidebar').should('be.visible')
+            .then($elem => {
+              // open if inactive
+              if (!$elem.hasClass('active')) {
+                cy.getByTestid('grw-sidebar-nav-primary-custom-sidebar').click();
+              }
+            });
+        });
 
+        it('Successfully access to custom sidebar', () => {
           cy.getByTestid('grw-contextual-navigation-sub').within(() => {
-            cy.get('.grw-sidebar-content-header.h5').find('a');
+            cy.get('.grw-sidebar-content-header > h3').find('a');
 
+            cy.waitUntilSkeletonDisappear();
             cy.screenshot(`${ssPrefix}custom-sidebar-1-access-to-custom-sidebar`);
           });
         });
@@ -157,7 +212,9 @@ describe('Access to sidebar', () => {
         it('Successfully redirect to editor', () => {
           const content = '# HELLO \n ## Hello\n ### Hello';
 
-          cy.get('.grw-sidebar-content-header.h5').find('a').click();
+          cy.get('.grw-sidebar-content-header > h3').find('a').click();
+
+          cy.get('.layout-root').should('have.class', 'editing');
           cy.get('.CodeMirror textarea').type(content, {force: true});
 
           cy.screenshot(`${ssPrefix}custom-sidebar-2-redirect-to-editor`);
@@ -167,21 +224,27 @@ describe('Access to sidebar', () => {
         });
 
         it('Successfully create custom sidebar content', () => {
-          cy.getByTestid('grw-contextual-navigation-sub').within(() => {
-            cy.get('.grw-custom-sidebar-content').should('be.visible');
+          cy.getByTestid('grw-sidebar-nav-primary-custom-sidebar')
+            .should('be.visible')
+            .should('have.class', 'active');
 
-            cy.screenshot(`${ssPrefix}custom-sidebar-3-content-created`);
-          });
+          cy.waitUntilSkeletonDisappear();
+          cy.screenshot(`${ssPrefix}custom-sidebar-3-content-created`);
         });
       });
 
       describe('Test recent changes tab', () => {
-        it('Successfully access to recent changes', () => {
-          cy.getByTestid('grw-sidebar-nav-primary-recent-changes').click();
-
-          // eslint-disable-next-line cypress/no-unnecessary-waiting
-          cy.wait(1500); // Wait debounce for UserUISettings update
+        beforeEach(() => {
+          cy.getByTestid('grw-sidebar-nav-primary-recent-changes').should('be.visible')
+            .then($elem => {
+              // open if inactive
+              if (!$elem.hasClass('active')) {
+                cy.getByTestid('grw-sidebar-nav-primary-recent-changes').click();
+              }
+            });
+        });
 
+        it('Successfully access to recent changes', () => {
           cy.getByTestid('grw-recent-changes').should('be.visible');
           cy.get('.list-group-item').should('be.visible');
 
@@ -207,12 +270,17 @@ describe('Access to sidebar', () => {
       });
 
       describe('Test tags tab', () => {
-        it('Successfully access to tags', () => {
-          cy.getByTestid('grw-sidebar-nav-primary-tags').click();
-
-          // eslint-disable-next-line cypress/no-unnecessary-waiting
-          cy.wait(1500); // Wait debounce for UserUISettings update
+        beforeEach(() => {
+          cy.getByTestid('grw-sidebar-nav-primary-tags').should('be.visible')
+            .then($elem => {
+              // open if inactive
+              if (!$elem.hasClass('active')) {
+                cy.getByTestid('grw-sidebar-nav-primary-tags').click();
+              }
+            });
+        });
 
+        it('Successfully access to tags', () => {
           cy.getByTestid('grw-contextual-navigation-sub').within(() => {
             cy.getByTestid('grw-tags-list').should('be.visible');
 

+ 1 - 1
packages/app/test/cypress/integration/50-sidebar/50-sidebar--switching-sidebar-mode.spec.ts

@@ -22,7 +22,7 @@ context('Switch sidebar mode', () => {
   it('Switching sidebar mode', () => {
     cy.visit('/');
     // This test uses collapseSidebar here, because this test for the sidebar.
-    cy.collapseSidebar(true, true)
+    cy.collapseSidebar(true)
     cy.get('.grw-apperance-mode-dropdown').first().click();
 
     cy.get('[for="swSidebarMode"]').click({force: true});

+ 1 - 1
packages/app/test/cypress/integration/60-home/60-home--home.spec.ts

@@ -45,7 +45,7 @@ context('Access User settings', () => {
       cy.login(user.username, user.password);
     });
     cy.visit('/me');
-    cy.collapseSidebar(true);
+    cy.collapseSidebar(true, true);
     // hide fab // disable fab for sticky-events warning
     // cy.getByTestid('grw-fab-container').invoke('attr', 'style', 'display: none');
   });

+ 20 - 19
packages/app/test/cypress/support/commands.ts

@@ -69,26 +69,27 @@ Cypress.Commands.add('waitUntilSpinnerDisappear', () => {
   cy.get('.fa-spinner').should('not.exist');
 });
 
-Cypress.Commands.add('collapseSidebar', (isCollapsed: boolean) => {
-  const isSidebarExists = isVisibleByTestId('grw-sidebar-wrapper');
+Cypress.Commands.add('collapseSidebar', (isCollapsed: boolean, waitUntilSaving = false) => {
+  cy.getByTestid('grw-sidebar-wrapper', { timeout: 5000 }).within(() => {
+    // process only when Dock Mode
+    cy.get('.grw-sidebar-dock').within(() => {
+      const isSidebarContextualNavigationHidden = isHiddenByTestId('grw-contextual-navigation-sub');
+      if (isSidebarContextualNavigationHidden === isCollapsed) {
+        return;
+      }
 
-  if (!isSidebarExists) {
-    return;
-  }
-
-  const isSidebarContextualNavigationHidden = isHiddenByTestId('grw-contextual-navigation-sub');
-  if (isSidebarContextualNavigationHidden === isCollapsed) {
-    return;
-  }
-
-  cy.waitUntil(() => {
-    // do
-    cy.getByTestid("grw-navigation-resize-button").click({force: true});
-    // wait until saving UserUISettings
-    // eslint-disable-next-line cypress/no-unnecessary-waiting
-    cy.wait(1500);
+      cy.waitUntil(() => {
+        // do
+        cy.getByTestid("grw-navigation-resize-button").click({force: true});
+        // wait until saving UserUISettings
+        if (waitUntilSaving) {
+          // eslint-disable-next-line cypress/no-unnecessary-waiting
+          cy.wait(1500);
+        }
 
-    // wait until
-    return cy.getByTestid('grw-contextual-navigation-sub').then($contents => isHidden($contents) === isCollapsed);
+        // wait until
+        return cy.getByTestid('grw-contextual-navigation-sub').then($contents => isHidden($contents) === isCollapsed);
+      });
+    });
   });
 });

+ 1 - 1
packages/codemirror-textlint/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/codemirror-textlint",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "license": "MIT",
   "main": "dist/index.js",
   "scripts": {

+ 1 - 1
packages/core/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/core",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "description": "GROWI Core Libraries",
   "license": "MIT",
   "keywords": [

+ 1 - 1
packages/hackmd/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/hackmd",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "description": "GROWI js and css files to use hackmd",
   "license": "MIT",
   "main": "dist/index.js",

+ 4 - 2
packages/preset-themes/package.json

@@ -1,10 +1,12 @@
 {
   "name": "@growi/preset-themes",
   "description": "GROWI preset themes",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "license": "MIT",
   "main": "dist/libs/index.js",
-  "files": ["dist"],
+  "files": [
+    "dist"
+  ],
   "scripts": {
     "build": "yarn build:libs & yarn build:themes",
     "build:w": "yarn build:libs -w & yarn build:themes -w",

+ 1 - 1
packages/remark-drawio/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/remark-drawio",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "description": "remark plugin to draw diagrams with draw.io (diagrams.net)",
   "license": "MIT",
   "keywords": [

+ 1 - 1
packages/remark-growi-directive/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/remark-growi-directive",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "description": "remark plugin to support GROWI plugin (forked from remark-directive@2.0.1)",
   "license": "MIT",
   "keywords": [

+ 4 - 4
packages/remark-lsx/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/remark-lsx",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "description": "GROWI plugin to list pages",
   "license": "MIT",
   "keywords": ["growi", "growi-plugin"],
@@ -23,9 +23,9 @@
     "test": ""
   },
   "dependencies": {
-    "@growi/core": "^6.0.0-RC.9",
-    "@growi/remark-growi-directive": "^6.0.0-RC.9",
-    "@growi/ui": "^6.0.0-RC.9",
+    "@growi/core": "^6.0.0-RC.13",
+    "@growi/remark-growi-directive": "^6.0.0-RC.13",
+    "@growi/ui": "^6.0.0-RC.13",
     "swr": "^1.3.0"
   },
   "devDependencies": {

+ 1 - 1
packages/slack/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/slack",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "license": "MIT",
   "main": "dist/index.js",
   "typings": "dist/index.d.ts",

+ 2 - 2
packages/slackbot-proxy/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/slackbot-proxy",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-slackbot-proxy.0",
   "license": "MIT",
   "scripts": {
     "build": "yarn tsc && tsc-alias -p tsconfig.build.json",
@@ -26,7 +26,7 @@
   },
   "dependencies": {
     "@godaddy/terminus": "^4.9.0",
-    "@growi/slack": "^6.0.0-RC.9",
+    "@growi/slack": "^6.0.0-RC.13",
     "@slack/oauth": "^2.0.1",
     "@slack/web-api": "^6.2.4",
     "@tsed/common": "^6.43.0",

+ 2 - 2
packages/ui/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/ui",
-  "version": "6.0.0-RC.9",
+  "version": "6.0.0-RC.13",
   "description": "GROWI UI Libraries",
   "license": "MIT",
   "keywords": ["growi"],
@@ -17,7 +17,7 @@
     "test": "jest --verbose"
   },
   "dependencies": {
-    "@growi/core": "^6.0.0-RC.9"
+    "@growi/core": "^6.0.0-RC.13"
   },
   "devDependencies": {
     "eslint-plugin-regex": "^1.8.0",

+ 98 - 98
yarn.lock

@@ -2929,10 +2929,10 @@
   dependencies:
     webpack-bundle-analyzer "4.3.0"
 
-"@next/env@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/env/-/env-12.2.5.tgz#d908c57b35262b94db3e431e869b72ac3e1ad3e3"
-  integrity sha512-vLPLV3cpPGjUPT3PjgRj7e3nio9t6USkuew3JE/jMeon/9Mvp1WyR18v3iwnCuX7eUAm1HmAbJHHLAbcu/EJcw==
+"@next/env@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/env/-/env-12.2.6.tgz#5903853efa7e44e6280f4e805d07499b99f4b240"
+  integrity sha512-THKlM+l5a2JUKEC3/X+qZ74gACapD/OQ1dz9p2hi504FB3vdgUgh2lswkWvjLZssxBdHW0FJiWoUYf8z19vxuw==
 
 "@next/eslint-plugin-next@12.1.6":
   version "12.1.6"
@@ -2941,70 +2941,70 @@
   dependencies:
     glob "7.1.7"
 
-"@next/swc-android-arm-eabi@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.5.tgz#903a5479ab4c2705d9c08d080907475f7bacf94d"
-  integrity sha512-cPWClKxGhgn2dLWnspW+7psl3MoLQUcNqJqOHk2BhNcou9ARDtC0IjQkKe5qcn9qg7I7U83Gp1yh2aesZfZJMA==
-
-"@next/swc-android-arm64@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.2.5.tgz#2f9a98ec4166c7860510963b31bda1f57a77c792"
-  integrity sha512-vMj0efliXmC5b7p+wfcQCX0AfU8IypjkzT64GiKJD9PgiA3IILNiGJr1fw2lyUDHkjeWx/5HMlMEpLnTsQslwg==
-
-"@next/swc-darwin-arm64@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.2.5.tgz#31b1c3c659d54be546120c488a1e1bad21c24a1d"
-  integrity sha512-VOPWbO5EFr6snla/WcxUKtvzGVShfs302TEMOtzYyWni6f9zuOetijJvVh9CCTzInnXAZMtHyNhefijA4HMYLg==
-
-"@next/swc-darwin-x64@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.2.5.tgz#2e44dd82b2b7fef88238d1bc4d3bead5884cedfd"
-  integrity sha512-5o8bTCgAmtYOgauO/Xd27vW52G2/m3i5PX7MUYePquxXAnX73AAtqA3WgPXBRitEB60plSKZgOTkcpqrsh546A==
-
-"@next/swc-freebsd-x64@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.5.tgz#e24e75d8c2581bfebc75e4f08f6ddbd116ce9dbd"
-  integrity sha512-yYUbyup1JnznMtEBRkK4LT56N0lfK5qNTzr6/DEyDw5TbFVwnuy2hhLBzwCBkScFVjpFdfiC6SQAX3FrAZzuuw==
-
-"@next/swc-linux-arm-gnueabihf@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.2.5.tgz#46d8c514d834d2b5f67086013f0bd5e3081e10b9"
-  integrity sha512-2ZE2/G921Acks7UopJZVMgKLdm4vN4U0yuzvAMJ6KBavPzqESA2yHJlm85TV/K9gIjKhSk5BVtauIUntFRP8cg==
-
-"@next/swc-linux-arm64-gnu@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.2.5.tgz#91f725ac217d3a1f4f9f53b553615ba582fd3d9f"
-  integrity sha512-/I6+PWVlz2wkTdWqhlSYYJ1pWWgUVva6SgX353oqTh8njNQp1SdFQuWDqk8LnM6ulheVfSsgkDzxrDaAQZnzjQ==
-
-"@next/swc-linux-arm64-musl@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.2.5.tgz#e627e8c867920995810250303cd9b8e963598383"
-  integrity sha512-LPQRelfX6asXyVr59p5sTpx5l+0yh2Vjp/R8Wi4X9pnqcayqT4CUJLiHqCvZuLin3IsFdisJL0rKHMoaZLRfmg==
-
-"@next/swc-linux-x64-gnu@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.2.5.tgz#83a5e224fbc4d119ef2e0f29d0d79c40cc43887e"
-  integrity sha512-0szyAo8jMCClkjNK0hknjhmAngUppoRekW6OAezbEYwHXN/VNtsXbfzgYOqjKWxEx3OoAzrT3jLwAF0HdX2MEw==
-
-"@next/swc-linux-x64-musl@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.2.5.tgz#be700d48471baac1ec2e9539396625584a317e95"
-  integrity sha512-zg/Y6oBar1yVnW6Il1I/08/2ukWtOG6s3acdJdEyIdsCzyQi4RLxbbhkD/EGQyhqBvd3QrC6ZXQEXighQUAZ0g==
-
-"@next/swc-win32-arm64-msvc@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.2.5.tgz#a93e958133ad3310373fda33a79aa10af2a0aa97"
-  integrity sha512-3/90DRNSqeeSRMMEhj4gHHQlLhhKg5SCCoYfE3kBjGpE63EfnblYUqsszGGZ9ekpKL/R4/SGB40iCQr8tR5Jiw==
-
-"@next/swc-win32-ia32-msvc@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.2.5.tgz#4f5f7ba0a98ff89a883625d4af0125baed8b2e19"
-  integrity sha512-hGLc0ZRAwnaPL4ulwpp4D2RxmkHQLuI8CFOEEHdzZpS63/hMVzv81g8jzYA0UXbb9pus/iTc3VRbVbAM03SRrw==
-
-"@next/swc-win32-x64-msvc@12.2.5":
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.5.tgz#20fed129b04a0d3f632c6d0de135345bb623b1e4"
-  integrity sha512-7h5/ahY7NeaO2xygqVrSG/Y8Vs4cdjxIjowTZ5W6CKoTKn7tmnuxlUc2h74x06FKmbhAd9agOjr/AOKyxYYm9Q==
+"@next/swc-android-arm-eabi@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.6.tgz#6ca64fc3e3b37b55e61bc294adf17fc523167200"
+  integrity sha512-dDo8Dxz/+v7gM7y0GwKunl4iMyoXDJV4xhH3zsO2yYReK+WL/KTJxRMzxtRJIiH9XFHHzdxnL935067r4hs1+A==
+
+"@next/swc-android-arm64@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.2.6.tgz#5a36130c2aee1f10f97a1b6f113f3132b1da80e6"
+  integrity sha512-l547hA/ddEnqCEhJgZ7exnTAvLdw6kcDmO/C+S0C6Pg63doNO/OwOD9tNqX7yU8EhJLOYFG07Ei3hPMeOGiEDw==
+
+"@next/swc-darwin-arm64@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.2.6.tgz#01aa6eeb457fbec3fd8775db6c37c87ef3233b8b"
+  integrity sha512-3HnlL7l/0S5YR4Wvi8BDWvqwbr0V/D034/pcaRlRK/bNWUA7PzjI6RuJ2HFdNVl9W/bUD6i5EoE7xQpRa8AFRA==
+
+"@next/swc-darwin-x64@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.2.6.tgz#ecef189e380b1212b6fdd409813b6e9bbfa2e593"
+  integrity sha512-praySt/hINjb8vI2J67sNvHGTvTmAVZqw8XewTWL7krj4MoiX2lTY+SsIKdfWkkYaae0OqufoPeOqXk3R7xE3g==
+
+"@next/swc-freebsd-x64@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.6.tgz#611db3160d4c8ef0cf66ecd340ce1f05d2e1bb39"
+  integrity sha512-p8TU7HCNjFEf7pLrKG0fAtuHKbIk8XWLCFvn0n54RvGAnQmwo0kzghU0I8RFzcl/XFbVhxg5oX9Npx/GBlPgcw==
+
+"@next/swc-linux-arm-gnueabihf@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.2.6.tgz#27e977c115d495721434976435e7673718596ef1"
+  integrity sha512-l7yqnAVjYKECDytU6LBLqVYex473fp/e5xb/4wHIxSoAWH7OCfCH1UT+TdKXZBfeupBKlUhin7Rw//lWuq2qew==
+
+"@next/swc-linux-arm64-gnu@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.2.6.tgz#db353803c25bee7eb27af0640069901b634f22cf"
+  integrity sha512-UDy+1ynNSW27KJBj7mZSOopc9uavPQP31ywwVhcOVtTKMdEzZ5z3ZKsPUTsuJuihN/J5BGQke5PIh9KwMSEvkA==
+
+"@next/swc-linux-arm64-musl@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.2.6.tgz#8e45531b5fa08917f1ad63f628c3d67fbae6d1f8"
+  integrity sha512-6AVgmBi5gMZIdXh8GIrbW8Bf21wO993TZ5eeuIFXgKW7j30Xt+NnYxfq6ElilQnyrxdmhan8Efovx2pb5fWjMQ==
+
+"@next/swc-linux-x64-gnu@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.2.6.tgz#262680e69274cdffd8a57a178e35f7af846a46cf"
+  integrity sha512-JjixyBnwsdbdQedku8cWAeJ+E562TE3WsjYcFCaCrASa4hW8SrJsqm2fTe6Q0Tu5bCy4TwCNjo9Tjwgp88pCeg==
+
+"@next/swc-linux-x64-musl@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.2.6.tgz#1b754b404ed9ca80407a63ce04c096776d5b77f3"
+  integrity sha512-EQGRzdJKIrWVsn2/B7k0BdJ7N4yOYhR+6pr7DuIGnzJRo4CIZRMKs7dOvvnxtgHky3Swu5vIFOPp+qSdYmck8A==
+
+"@next/swc-win32-arm64-msvc@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.2.6.tgz#457c955b3787a7d00abc241415889e1cadc491cc"
+  integrity sha512-87jDRqWPH5J7HrLKSmVjnC+FGAPWvUhQUe1p5dROawsDrCJtNFPuxmOifDid9saW99CDpcOxu3xZ7HWbp9XO7A==
+
+"@next/swc-win32-ia32-msvc@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.2.6.tgz#6f6acae984e7ae08b9c4959e0b91752babb29f6e"
+  integrity sha512-IjAuEVybts1pguSHbPvk+KQEMnyyQnrhn7yaxphYfIh8wPhsxwKXJY+AN4WrxqA4gbO+sgpMxZW3bhqJmYKWGw==
+
+"@next/swc-win32-x64-msvc@12.2.6":
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.6.tgz#7ca74a12b2f46d8cbaca18de11547797db7a86b1"
+  integrity sha512-AQ1QbiJ13I+47wXRjJuOUmBp9tmEqEhhqFoaKrFvbj6v4ekZS5/2tlybaZxrVB5mF5Tqu/OcLp5fCqXrDxHbXw==
 
 "@nodelib/fs.scandir@2.1.3":
   version "2.1.3"
@@ -6369,9 +6369,9 @@ caniuse-lite@^1.0.30001219:
   integrity sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==
 
 caniuse-lite@^1.0.30001332:
-  version "1.0.30001354"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001354.tgz#95c5efdb64148bb4870771749b9a619304755ce5"
-  integrity sha512-mImKeCkyGDAHNywYFA4bqnLAzTUvVkqPvhY4DV47X+Gl2c5Z8c3KNETnXp14GQt11LvxE8AwjzGxJ+rsikiOzg==
+  version "1.0.30001441"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz#987437b266260b640a23cd18fbddb509d7f69f3e"
+  integrity sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==
 
 caniuse-lite@^1.0.30001366:
   version "1.0.30001367"
@@ -15913,31 +15913,31 @@ next-transpile-modules@^9.0.0:
     enhanced-resolve "^5.7.0"
     escalade "^3.1.1"
 
-next@^12.2.5:
-  version "12.2.5"
-  resolved "https://registry.yarnpkg.com/next/-/next-12.2.5.tgz#14fb5975e8841fad09553b8ef41fe1393602b717"
-  integrity sha512-tBdjqX5XC/oFs/6gxrZhjmiq90YWizUYU6qOWAfat7zJwrwapJ+BYgX2PmiacunXMaRpeVT4vz5MSPSLgNkrpA==
+next@~12.2:
+  version "12.2.6"
+  resolved "https://registry.yarnpkg.com/next/-/next-12.2.6.tgz#105383333c8de542a8c28db9246bd9f2d62f73d3"
+  integrity sha512-Wlln0vp91NVj4f2Tr5c1e7ZXPiwZ+XEefPiuoTnt/VopOh5xK7//KCl1pCicYZP3P2mRbpuKs5PvcVQG/+EC7w==
   dependencies:
-    "@next/env" "12.2.5"
+    "@next/env" "12.2.6"
     "@swc/helpers" "0.4.3"
     caniuse-lite "^1.0.30001332"
     postcss "8.4.14"
     styled-jsx "5.0.4"
     use-sync-external-store "1.2.0"
   optionalDependencies:
-    "@next/swc-android-arm-eabi" "12.2.5"
-    "@next/swc-android-arm64" "12.2.5"
-    "@next/swc-darwin-arm64" "12.2.5"
-    "@next/swc-darwin-x64" "12.2.5"
-    "@next/swc-freebsd-x64" "12.2.5"
-    "@next/swc-linux-arm-gnueabihf" "12.2.5"
-    "@next/swc-linux-arm64-gnu" "12.2.5"
-    "@next/swc-linux-arm64-musl" "12.2.5"
-    "@next/swc-linux-x64-gnu" "12.2.5"
-    "@next/swc-linux-x64-musl" "12.2.5"
-    "@next/swc-win32-arm64-msvc" "12.2.5"
-    "@next/swc-win32-ia32-msvc" "12.2.5"
-    "@next/swc-win32-x64-msvc" "12.2.5"
+    "@next/swc-android-arm-eabi" "12.2.6"
+    "@next/swc-android-arm64" "12.2.6"
+    "@next/swc-darwin-arm64" "12.2.6"
+    "@next/swc-darwin-x64" "12.2.6"
+    "@next/swc-freebsd-x64" "12.2.6"
+    "@next/swc-linux-arm-gnueabihf" "12.2.6"
+    "@next/swc-linux-arm64-gnu" "12.2.6"
+    "@next/swc-linux-arm64-musl" "12.2.6"
+    "@next/swc-linux-x64-gnu" "12.2.6"
+    "@next/swc-linux-x64-musl" "12.2.6"
+    "@next/swc-win32-arm64-msvc" "12.2.6"
+    "@next/swc-win32-ia32-msvc" "12.2.6"
+    "@next/swc-win32-x64-msvc" "12.2.6"
 
 nice-try@^1.0.4:
   version "1.0.4"
@@ -18284,10 +18284,10 @@ react-toastify@^9.1.1:
   dependencies:
     clsx "^1.1.1"
 
-react-transition-group@^2.3.1:
-  version "2.9.0"
-  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
-  integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==
+react-transition-group@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-3.0.0.tgz#36efa4db970d5eec5e3028e0c458931163fa3b9b"
+  integrity sha512-A9ojB/LWECbFj58SNfjK1X9aaAU+1olLS0DFSikvrr2KfMaiBELemHDa5dKNvcTk2t3gUtDL/PJpFrBKDfMpLg==
   dependencies:
     dom-helpers "^3.4.0"
     loose-envify "^1.4.0"
@@ -18316,16 +18316,16 @@ react@^18.2.0:
   dependencies:
     loose-envify "^1.1.0"
 
-reactstrap@^8.9.0:
-  version "8.9.0"
-  resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.9.0.tgz#bca4afa3f5cd18899ef9b33d877a141886d5abae"
-  integrity sha512-pmf33YjpNZk1IfrjqpWCUMq9hk6GzSnMWBAofTBNIRJQB1zQ0Au2kzv3lPUAFsBYgWEuI9iYa/xKXHaboSiMkQ==
+reactstrap@^8.10.1:
+  version "8.10.1"
+  resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.10.1.tgz#43ea596c7f82f88997a9c8aae203417910262d3f"
+  integrity sha512-StjLADa/12yMNjafrSs+UD7sZAGtKpLO9fZp++2Dj0IzJinqY7eQhXlM3nFf0q40YsIcLvQdFc9pKF8PF4f0Qg==
   dependencies:
     "@babel/runtime" "^7.12.5"
     classnames "^2.2.3"
     prop-types "^15.5.8"
     react-popper "^1.3.6"
-    react-transition-group "^2.3.1"
+    react-transition-group "^3.0.0"
 
 read-cmd-shim@^2.0.0:
   version "2.0.0"