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

Merge branch 'dev/7.0.x' into feat/132680-create-button-handler

ryoji-s 2 лет назад
Родитель
Сommit
0e30a8a07c

+ 4 - 4
apps/app/src/client/services/side-effects/hash-changed.ts

@@ -2,7 +2,7 @@ import { useCallback, useEffect } from 'react';
 
 
 import { useRouter } from 'next/router';
 import { useRouter } from 'next/router';
 
 
-import { useIsEditablePage } from '~/stores/page';
+import { useIsEditable } from '~/stores/context';
 import { useEditorMode, determineEditorModeByHash } from '~/stores/ui';
 import { useEditorMode, determineEditorModeByHash } from '~/stores/ui';
 
 
 /**
 /**
@@ -11,7 +11,7 @@ import { useEditorMode, determineEditorModeByHash } from '~/stores/ui';
 export const useHashChangedEffect = (): void => {
 export const useHashChangedEffect = (): void => {
   const router = useRouter();
   const router = useRouter();
 
 
-  const { data: isEditablePage } = useIsEditablePage();
+  const { data: isEditable } = useIsEditable();
   const { data: editorMode, mutate: mutateEditorMode } = useEditorMode();
   const { data: editorMode, mutate: mutateEditorMode } = useEditorMode();
 
 
   const hashchangeHandler = useCallback(() => {
   const hashchangeHandler = useCallback(() => {
@@ -24,7 +24,7 @@ export const useHashChangedEffect = (): void => {
 
 
   // setup effect
   // setup effect
   useEffect(() => {
   useEffect(() => {
-    if (!isEditablePage) {
+    if (!isEditable) {
       return;
       return;
     }
     }
 
 
@@ -35,7 +35,7 @@ export const useHashChangedEffect = (): void => {
       window.removeEventListener('hashchange', hashchangeHandler);
       window.removeEventListener('hashchange', hashchangeHandler);
     };
     };
 
 
-  }, [hashchangeHandler, isEditablePage]);
+  }, [hashchangeHandler, isEditable]);
 
 
   /*
   /*
   * Route changes by Next Router
   * Route changes by Next Router

+ 4 - 4
apps/app/src/components/Hotkeys/Subscribers/EditPage.jsx

@@ -2,16 +2,16 @@ import { useEffect } from 'react';
 
 
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
-import { useIsEditablePage } from '~/stores/page';
+import { useIsEditable } from '~/stores/context';
 import { EditorMode, useEditorMode } from '~/stores/ui';
 import { EditorMode, useEditorMode } from '~/stores/ui';
 
 
 const EditPage = (props) => {
 const EditPage = (props) => {
-  const { data: isEditablePage } = useIsEditablePage();
+  const { data: isEditable } = useIsEditable();
   const { mutate: mutateEditorMode } = useEditorMode();
   const { mutate: mutateEditorMode } = useEditorMode();
 
 
   // setup effect
   // setup effect
   useEffect(() => {
   useEffect(() => {
-    if (!isEditablePage) {
+    if (!isEditable) {
       return;
       return;
     }
     }
 
 
@@ -24,7 +24,7 @@ const EditPage = (props) => {
 
 
     // remove this
     // remove this
     props.onDeleteRender(this);
     props.onDeleteRender(this);
-  }, [isEditablePage, mutateEditorMode, props]);
+  }, [isEditable, mutateEditorMode, props]);
 
 
   return null;
   return null;
 };
 };

+ 4 - 4
apps/app/src/components/Hotkeys/Subscribers/FocusToGlobalSearch.jsx

@@ -1,15 +1,15 @@
 import { useEffect } from 'react';
 import { useEffect } from 'react';
 
 
-import { useIsEditablePage } from '~/stores/page';
+import { useIsEditable } from '~/stores/context';
 import { useGlobalSearchFormRef } from '~/stores/ui';
 import { useGlobalSearchFormRef } from '~/stores/ui';
 
 
 const FocusToGlobalSearch = (props) => {
 const FocusToGlobalSearch = (props) => {
-  const { data: isEditablePage } = useIsEditablePage();
+  const { data: isEditable } = useIsEditable();
   const { data: globalSearchFormRef } = useGlobalSearchFormRef();
   const { data: globalSearchFormRef } = useGlobalSearchFormRef();
 
 
   // setup effect
   // setup effect
   useEffect(() => {
   useEffect(() => {
-    if (!isEditablePage) {
+    if (!isEditable) {
       return;
       return;
     }
     }
 
 
@@ -22,7 +22,7 @@ const FocusToGlobalSearch = (props) => {
 
 
     // remove this
     // remove this
     props.onDeleteRender();
     props.onDeleteRender();
-  }, [globalSearchFormRef, isEditablePage, props]);
+  }, [globalSearchFormRef, isEditable, props]);
 
 
   return null;
   return null;
 };
 };

+ 1 - 12
apps/app/src/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -27,7 +27,7 @@ import {
 import { mutatePageTree } from '~/stores/page-listing';
 import { mutatePageTree } from '~/stores/page-listing';
 import {
 import {
   useEditorMode, useIsAbleToShowPageManagement,
   useEditorMode, useIsAbleToShowPageManagement,
-  useIsAbleToChangeEditorMode, useIsAbleToShowCreateButton,
+  useIsAbleToChangeEditorMode,
 } from '~/stores/ui';
 } from '~/stores/ui';
 
 
 import CreateTemplateModal from '../CreateTemplateModal';
 import CreateTemplateModal from '../CreateTemplateModal';
@@ -200,7 +200,6 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
 
 
   const { data: isAbleToShowPageManagement } = useIsAbleToShowPageManagement();
   const { data: isAbleToShowPageManagement } = useIsAbleToShowPageManagement();
   const { data: isAbleToChangeEditorMode } = useIsAbleToChangeEditorMode();
   const { data: isAbleToChangeEditorMode } = useIsAbleToChangeEditorMode();
-  const { data: isAbleToShowCreateButton } = useIsAbleToShowCreateButton();
 
 
   // TODO: implement tags for editor
   // TODO: implement tags for editor
   // refs: https://redmine.weseek.co.jp/issues/132125
   // refs: https://redmine.weseek.co.jp/issues/132125
@@ -359,16 +358,6 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
             onPageEditorModeButtonClicked={viewType => mutateEditorMode(viewType)}
             onPageEditorModeButtonClicked={viewType => mutateEditorMode(viewType)}
           />
           />
         )}
         )}
-        {isAbleToShowCreateButton && (
-          <button
-            type="button"
-            className="btn btn-outline-primary"
-            onClick={() => {}}
-          >
-            <span className="me-1"><i className="icon-control-play" /></span>
-            <span>Create</span>
-          </button>
-        )}
       </div>
       </div>
 
 
       {path != null && currentUser != null && !isReadOnlyUser && (
       {path != null && currentUser != null && !isReadOnlyUser && (

+ 4 - 4
apps/app/src/components/Page/DisplaySwitcher.tsx

@@ -5,7 +5,7 @@ import dynamic from 'next/dynamic';
 
 
 import { useHashChangedEffect } from '~/client/services/side-effects/hash-changed';
 import { useHashChangedEffect } from '~/client/services/side-effects/hash-changed';
 import { usePageUpdatedEffect } from '~/client/services/side-effects/page-updated';
 import { usePageUpdatedEffect } from '~/client/services/side-effects/page-updated';
-import { useIsEditablePage } from '~/stores/page';
+import { useIsEditable } from '~/stores/context';
 import { EditorMode, useEditorMode } from '~/stores/ui';
 import { EditorMode, useEditorMode } from '~/stores/ui';
 
 
 import { LazyRenderer } from '../Common/LazyRenderer';
 import { LazyRenderer } from '../Common/LazyRenderer';
@@ -23,7 +23,7 @@ export const DisplaySwitcher = (props: Props): JSX.Element => {
   const { pageView } = props;
   const { pageView } = props;
 
 
   const { data: editorMode = EditorMode.View } = useEditorMode();
   const { data: editorMode = EditorMode.View } = useEditorMode();
-  const { data: isEditablePage } = useIsEditablePage();
+  const { data: isEditable } = useIsEditable();
 
 
   usePageUpdatedEffect();
   usePageUpdatedEffect();
   useHashChangedEffect();
   useHashChangedEffect();
@@ -34,11 +34,11 @@ export const DisplaySwitcher = (props: Props): JSX.Element => {
     <>
     <>
       { isViewMode && pageView }
       { isViewMode && pageView }
 
 
-      <LazyRenderer shouldRender={isEditablePage === true && editorMode === EditorMode.Editor}>
+      <LazyRenderer shouldRender={isEditable === true && editorMode === EditorMode.Editor}>
         <PageEditor />
         <PageEditor />
       </LazyRenderer>
       </LazyRenderer>
 
 
-      { isEditablePage && !isViewMode && <EditorNavbarBottom /> }
+      { isEditable && !isViewMode && <EditorNavbarBottom /> }
     </>
     </>
   );
   );
 };
 };

+ 3 - 4
apps/app/src/components/PageEditor/PageEditor.tsx

@@ -23,7 +23,7 @@ import { SocketEventName } from '~/interfaces/websocket';
 import {
 import {
   useDefaultIndentSize,
   useDefaultIndentSize,
   useCurrentPathname, useIsEnabledAttachTitleHeader,
   useCurrentPathname, useIsEnabledAttachTitleHeader,
-  useIsUploadableFile, useIsUploadableImage, useIsIndentSizeForced,
+  useIsEditable, useIsUploadableFile, useIsUploadableImage, useIsIndentSizeForced,
 } from '~/stores/context';
 } from '~/stores/context';
 import {
 import {
   useCurrentIndentSize, useIsSlackEnabled, usePageTagsForEditors,
   useCurrentIndentSize, useIsSlackEnabled, usePageTagsForEditors,
@@ -35,7 +35,6 @@ import {
 import { useConflictDiffModal } from '~/stores/modal';
 import { useConflictDiffModal } from '~/stores/modal';
 import {
 import {
   useCurrentPagePath, useSWRMUTxCurrentPage, useSWRxCurrentPage, useSWRxTagsInfo, useCurrentPageId, useIsNotFound, useIsLatestRevision, useTemplateBodyData,
   useCurrentPagePath, useSWRMUTxCurrentPage, useSWRxCurrentPage, useSWRxTagsInfo, useCurrentPageId, useIsNotFound, useIsLatestRevision, useTemplateBodyData,
-  useIsEditablePage,
 } from '~/stores/page';
 } from '~/stores/page';
 import { mutatePageTree } from '~/stores/page-listing';
 import { mutatePageTree } from '~/stores/page-listing';
 import {
 import {
@@ -101,7 +100,7 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
   const { data: editingMarkdown, mutate: mutateEditingMarkdown } = useEditingMarkdown();
   const { data: editingMarkdown, mutate: mutateEditingMarkdown } = useEditingMarkdown();
   const { data: isEnabledAttachTitleHeader } = useIsEnabledAttachTitleHeader();
   const { data: isEnabledAttachTitleHeader } = useIsEnabledAttachTitleHeader();
   const { data: templateBodyData } = useTemplateBodyData();
   const { data: templateBodyData } = useTemplateBodyData();
-  const { data: isEditablePage } = useIsEditablePage();
+  const { data: isEditable } = useIsEditable();
   const { mutate: mutateWaitingSaveProcessing } = useWaitingSaveProcessing();
   const { mutate: mutateWaitingSaveProcessing } = useWaitingSaveProcessing();
   const { data: editorMode, mutate: mutateEditorMode } = useEditorMode();
   const { data: editorMode, mutate: mutateEditorMode } = useEditorMode();
   const { data: isSlackEnabled } = useIsSlackEnabled();
   const { data: isSlackEnabled } = useIsSlackEnabled();
@@ -558,7 +557,7 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
     };
     };
   }, [onRouterChangeComplete, router.events]);
   }, [onRouterChangeComplete, router.events]);
 
 
-  if (!isEditablePage) {
+  if (!isEditable) {
     return <></>;
     return <></>;
   }
   }
 
 

+ 7 - 5
apps/app/src/components/SavePageControls.tsx

@@ -10,9 +10,11 @@ import {
 } from 'reactstrap';
 } from 'reactstrap';
 
 
 import type { IPageGrantData } from '~/interfaces/page';
 import type { IPageGrantData } from '~/interfaces/page';
-import { useIsAclEnabled } from '~/stores/context';
+import {
+  useIsEditable, useIsAclEnabled,
+} from '~/stores/context';
 import { useWaitingSaveProcessing } from '~/stores/editor';
 import { useWaitingSaveProcessing } from '~/stores/editor';
-import { useSWRxCurrentPage, useIsEditablePage } from '~/stores/page';
+import { useSWRxCurrentPage } from '~/stores/page';
 import { useSelectedGrant } from '~/stores/ui';
 import { useSelectedGrant } from '~/stores/ui';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
@@ -35,7 +37,7 @@ export const SavePageControls = (props: SavePageControlsProps): JSX.Element | nu
   const { slackChannels } = props;
   const { slackChannels } = props;
   const { t } = useTranslation();
   const { t } = useTranslation();
   const { data: currentPage } = useSWRxCurrentPage();
   const { data: currentPage } = useSWRxCurrentPage();
-  const { data: isEditablePage } = useIsEditablePage();
+  const { data: isEditable } = useIsEditable();
   const { data: isAclEnabled } = useIsAclEnabled();
   const { data: isAclEnabled } = useIsAclEnabled();
   const { data: grantData, mutate: mutateGrant } = useSelectedGrant();
   const { data: grantData, mutate: mutateGrant } = useSelectedGrant();
   const { data: _isWaitingSaveProcessing } = useWaitingSaveProcessing();
   const { data: _isWaitingSaveProcessing } = useWaitingSaveProcessing();
@@ -57,11 +59,11 @@ export const SavePageControls = (props: SavePageControlsProps): JSX.Element | nu
   }, [slackChannels]);
   }, [slackChannels]);
 
 
 
 
-  if (isEditablePage == null || isAclEnabled == null || grantData == null) {
+  if (isEditable == null || isAclEnabled == null || grantData == null) {
     return null;
     return null;
   }
   }
 
 
-  if (!isEditablePage) {
+  if (!isEditable) {
     return null;
     return null;
   }
   }
 
 

+ 2 - 2
apps/app/src/stores/context.tsx

@@ -246,7 +246,7 @@ export const useIsAdmin = (): SWRResponse<boolean, Error> => {
   );
   );
 };
 };
 
 
-export const useIsExecutePageCreation = (): SWRResponse<boolean, Error> => {
+export const useIsEditable = (): SWRResponse<boolean, Error> => {
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isReadOnlyUser } = useIsReadOnlyUser();
   const { data: isReadOnlyUser } = useIsReadOnlyUser();
   const { data: isForbidden } = useIsForbidden();
   const { data: isForbidden } = useIsForbidden();
@@ -254,7 +254,7 @@ export const useIsExecutePageCreation = (): SWRResponse<boolean, Error> => {
   const { data: isIdenticalPath } = useIsIdenticalPath();
   const { data: isIdenticalPath } = useIsIdenticalPath();
 
 
   return useSWRImmutable(
   return useSWRImmutable(
-    ['isExecutePageCreation', isGuestUser, isReadOnlyUser, isForbidden, isNotCreatable, isIdenticalPath],
+    ['isEditable', isGuestUser, isReadOnlyUser, isForbidden, isNotCreatable, isIdenticalPath],
     ([, isGuestUser, isReadOnlyUser, isForbidden, isNotCreatable, isIdenticalPath]) => {
     ([, isGuestUser, isReadOnlyUser, isForbidden, isNotCreatable, isIdenticalPath]) => {
       return (!isForbidden && !isIdenticalPath && !isNotCreatable && !isGuestUser && !isReadOnlyUser);
       return (!isForbidden && !isIdenticalPath && !isNotCreatable && !isGuestUser && !isReadOnlyUser);
     },
     },

+ 1 - 13
apps/app/src/stores/page.tsx

@@ -24,7 +24,7 @@ import type { AxiosResponse } from '~/utils/axios';
 import type { IPageTagsInfo } from '../interfaces/tag';
 import type { IPageTagsInfo } from '../interfaces/tag';
 
 
 import {
 import {
-  useCurrentPathname, useShareLinkId, useIsGuestUser, useIsReadOnlyUser, useIsExecutePageCreation,
+  useCurrentPathname, useShareLinkId, useIsGuestUser, useIsReadOnlyUser,
 } from './context';
 } from './context';
 
 
 
 
@@ -292,15 +292,3 @@ export const useIsTrashPage = (): SWRResponse<boolean, Error> => {
     // { fallbackData:  }
     // { fallbackData:  }
   );
   );
 };
 };
-
-export const useIsEditablePage = (): SWRResponse<boolean, Error> => {
-  const { data: isExecutePageCreation } = useIsExecutePageCreation();
-  const { data: isNotFound } = useIsNotFound();
-
-  return useSWRImmutable(
-    ['isEditablePage', isExecutePageCreation, isNotFound],
-    ([, isExecutePageCreation, isNotFound]) => {
-      return (!!isExecutePageCreation && !isNotFound);
-    },
-  );
-};

+ 15 - 27
apps/app/src/stores/ui.tsx

@@ -20,12 +20,12 @@ import type { ISidebarConfig } from '~/interfaces/sidebar-config';
 import { SidebarContentsType } from '~/interfaces/ui';
 import { SidebarContentsType } from '~/interfaces/ui';
 import type { UpdateDescCountData } from '~/interfaces/websocket';
 import type { UpdateDescCountData } from '~/interfaces/websocket';
 import {
 import {
-  useIsNotFound, useCurrentPagePath, useIsTrashPage, useCurrentPageId, useIsEditablePage,
+  useIsNotFound, useCurrentPagePath, useIsTrashPage, useCurrentPageId,
 } from '~/stores/page';
 } from '~/stores/page';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
 import {
 import {
-  useIsReadOnlyUser, useIsExecutePageCreation,
+  useIsEditable, useIsReadOnlyUser,
   useIsSharedUser, useIsIdenticalPath, useCurrentUser, useShareLinkId,
   useIsSharedUser, useIsIdenticalPath, useCurrentUser, useShareLinkId,
 } from './context';
 } from './context';
 import { useStaticSWR } from './use-static-swr';
 import { useStaticSWR } from './use-static-swr';
@@ -131,16 +131,18 @@ type EditorModeUtils = {
 }
 }
 
 
 export const useEditorMode = (): SWRResponseWithUtils<EditorModeUtils, EditorMode> => {
 export const useEditorMode = (): SWRResponseWithUtils<EditorModeUtils, EditorMode> => {
-  const { data: _isEditablePage } = useIsEditablePage();
+  const { data: _isEditable } = useIsEditable();
+  const { data: isNotFound } = useIsNotFound();
 
 
   const editorModeByHash = determineEditorModeByHash();
   const editorModeByHash = determineEditorModeByHash();
 
 
-  const isLoading = _isEditablePage === undefined;
-  const isEditablePage = !isLoading && _isEditablePage;
-  const initialData = isEditablePage ? editorModeByHash : EditorMode.View;
+  const isLoading = _isEditable === undefined;
+  const isEditable = !isLoading && _isEditable;
+  const preventModeEditor = !isEditable || isNotFound === undefined || isNotFound === true;
+  const initialData = preventModeEditor ? EditorMode.View : editorModeByHash;
 
 
   const swrResponse = useSWRImmutable(
   const swrResponse = useSWRImmutable(
-    isLoading ? null : ['editorMode', isEditablePage],
+    isLoading ? null : ['editorMode', isEditable, preventModeEditor],
     null,
     null,
     { fallbackData: initialData },
     { fallbackData: initialData },
   );
   );
@@ -148,12 +150,12 @@ export const useEditorMode = (): SWRResponseWithUtils<EditorModeUtils, EditorMod
   // construct overriding mutate method
   // construct overriding mutate method
   const mutateOriginal = swrResponse.mutate;
   const mutateOriginal = swrResponse.mutate;
   const mutate = useCallback((editorMode: EditorMode, shouldRevalidate?: boolean) => {
   const mutate = useCallback((editorMode: EditorMode, shouldRevalidate?: boolean) => {
-    if (!isEditablePage) {
+    if (preventModeEditor) {
       return Promise.resolve(EditorMode.View); // fixed if not editable
       return Promise.resolve(EditorMode.View); // fixed if not editable
     }
     }
     updateHashByEditorMode(editorMode);
     updateHashByEditorMode(editorMode);
     return mutateOriginal(editorMode, shouldRevalidate);
     return mutateOriginal(editorMode, shouldRevalidate);
-  }, [isEditablePage, mutateOriginal]);
+  }, [preventModeEditor, mutateOriginal]);
 
 
   const getClassNames = useCallback(() => {
   const getClassNames = useCallback(() => {
     return getClassNamesByEditorMode(swrResponse.data);
     return getClassNamesByEditorMode(swrResponse.data);
@@ -451,14 +453,14 @@ export const useIsAbleToShowTagLabel = (): SWRResponse<boolean, Error> => {
 
 
 export const useIsAbleToChangeEditorMode = (): SWRResponse<boolean, Error> => {
 export const useIsAbleToChangeEditorMode = (): SWRResponse<boolean, Error> => {
   const key = 'isAbleToChangeEditorMode';
   const key = 'isAbleToChangeEditorMode';
-  const { data: isEditablePage } = useIsEditablePage();
+  const { data: isEditable } = useIsEditable();
   const { data: isSharedUser } = useIsSharedUser();
   const { data: isSharedUser } = useIsSharedUser();
 
 
-  const includesUndefined = [isEditablePage, isSharedUser].some(v => v === undefined);
+  const includesUndefined = [isEditable, isSharedUser].some(v => v === undefined);
 
 
   return useSWRImmutable(
   return useSWRImmutable(
-    includesUndefined ? null : [key, isEditablePage, isSharedUser],
-    () => !!isEditablePage && !isSharedUser,
+    includesUndefined ? null : [key, isEditable, isSharedUser],
+    () => !!isEditable && !isSharedUser,
   );
   );
 };
 };
 
 
@@ -477,17 +479,3 @@ export const useIsAbleToShowPageAuthors = (): SWRResponse<boolean, Error> => {
     () => isPageExist && !isUsersTopPagePath,
     () => isPageExist && !isUsersTopPagePath,
   );
   );
 };
 };
-
-export const useIsAbleToShowCreateButton = (): SWRResponse<boolean, Error> => {
-  const key = 'isAbleToShowCreateButton';
-  const { data: isEditablePage } = useIsEditablePage();
-  const { data: isExecutePageCreation } = useIsExecutePageCreation();
-  const { data: isSharedUser } = useIsSharedUser();
-
-  const includesUndefined = [isEditablePage, isExecutePageCreation, isSharedUser].some(v => v === undefined);
-
-  return useSWRImmutable(
-    includesUndefined ? null : [key, isEditablePage, isExecutePageCreation, isSharedUser],
-    () => !isEditablePage && !!isExecutePageCreation && !isSharedUser,
-  );
-};