nHigashiWeseek 1 год назад
Родитель
Сommit
3ed9f72c2b

+ 6 - 4
apps/app/src/client/components/DescendantsPageList.tsx

@@ -14,7 +14,7 @@ import type { OnDeletedFunction, OnPutBackedFunction } from '~/interfaces/ui';
 import { useIsGuestUser, useIsReadOnlyUser, useIsSharedUser } from '~/stores-universal/context';
 import {
   mutatePageTree,
-  useSWRxPageInfoForList, useSWRxPageList,
+  useSWRxPageInfoForList, useSWRxPageList, useSWRINFxRecentlyUpdated,
 } from '~/stores/page-listing';
 
 import type { ForceHideMenuItems } from './Common/Dropdown/PageItemControl';
@@ -47,6 +47,7 @@ const DescendantsPageListSubstance = (props: SubstanceProps): JSX.Element => {
 
   const pageIds = pagingResult?.items?.map(page => page._id);
   const { injectTo } = useSWRxPageInfoForList(pageIds, null, true, true);
+  const { mutate: mutateRecentlyUpdated } = useSWRINFxRecentlyUpdated(20, true);
 
   let pageWithMetas: IDataWithMeta<IPageHasId, IPageInfoForOperation>[] = [];
 
@@ -67,21 +68,22 @@ const DescendantsPageListSubstance = (props: SubstanceProps): JSX.Element => {
     else {
       toastSuccess(t('deleted_pages_completely', { path }));
     }
-
+    mutateRecentlyUpdated();
     mutatePageTree();
     if (onPagesDeleted != null) {
       onPagesDeleted(...args);
     }
-  }, [onPagesDeleted, t]);
+  }, [onPagesDeleted, mutateRecentlyUpdated, t]);
 
   const pagePutBackedHandler: OnPutBackedFunction = useCallback((path) => {
     toastSuccess(t('page_has_been_reverted', { path }));
 
+    mutateRecentlyUpdated();
     mutatePageTree();
     if (onPagePutBacked != null) {
       onPagePutBacked(path);
     }
-  }, [onPagePutBacked, t]);
+  }, [onPagePutBacked, mutateRecentlyUpdated, t]);
 
   if (pagingResult == null) {
     return (

+ 6 - 3
apps/app/src/client/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -34,7 +34,7 @@ import {
 import {
   useSWRMUTxCurrentPage, useCurrentPageId, useSWRxPageInfo,
 } from '~/stores/page';
-import { mutatePageTree } from '~/stores/page-listing';
+import { mutatePageTree, useSWRINFxRecentlyUpdated } from '~/stores/page-listing';
 import {
   useIsAbleToShowPageManagement,
   useIsAbleToChangeEditorMode,
@@ -247,6 +247,7 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
   const { open: openRenameModal } = usePageRenameModal();
   const { open: openDeleteModal } = usePageDeleteModal();
   const { mutate: mutatePageInfo } = useSWRxPageInfo(pageId);
+  const { mutate: mutateRecentlyUpdated } = useSWRINFxRecentlyUpdated(20, true);
 
   const [isStickyActive, setStickyActive] = useState(false);
 
@@ -271,9 +272,10 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
       mutateCurrentPage();
       mutatePageInfo();
       mutatePageTree();
+      mutateRecentlyUpdated();
     };
     openRenameModal(page, { onRenamed: renamedHandler });
-  }, [mutateCurrentPage, mutatePageInfo, openRenameModal]);
+  }, [mutateCurrentPage, mutatePageInfo, openRenameModal, mutateRecentlyUpdated]);
 
   const deleteItemClickedHandler = useCallback((pageWithMeta: IPageWithMeta) => {
     const deletedHandler: OnDeletedFunction = (pathOrPathsToDelete, isRecursively, isCompletely) => {
@@ -294,9 +296,10 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
       mutateCurrentPage();
       mutatePageInfo();
       mutatePageTree();
+      mutateRecentlyUpdated();
     };
     openDeleteModal([pageWithMeta], { onDeleted: deletedHandler });
-  }, [currentPathname, mutateCurrentPage, openDeleteModal, router, mutatePageInfo]);
+  }, [currentPathname, mutateCurrentPage, openDeleteModal, router, mutatePageInfo, mutateRecentlyUpdated]);
 
   const switchContentWidthHandler = useCallback(async(pageId: string, value: boolean) => {
     if (!isSharedPage) {

+ 6 - 2
apps/app/src/client/components/PageEditor/PageEditor.tsx

@@ -41,7 +41,7 @@ import {
 import {
   useCurrentPagePath, useSWRxCurrentPage, useCurrentPageId, useIsNotFound, useTemplateBodyData, useSWRxCurrentGrantData,
 } from '~/stores/page';
-import { mutatePageTree } from '~/stores/page-listing';
+import { mutatePageTree, useSWRINFxRecentlyUpdated } from '~/stores/page-listing';
 import { usePreviewOptions } from '~/stores/renderer';
 import { useIsUntitledPage, useSelectedGrant } from '~/stores/ui';
 import { useEditingUsers } from '~/stores/use-editing-users';
@@ -165,6 +165,8 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
 
   const scrollEditorHandlerThrottle = useMemo(() => throttle(25, scrollEditorHandler), [scrollEditorHandler]);
   const scrollPreviewHandlerThrottle = useMemo(() => throttle(25, scrollPreviewHandler), [scrollPreviewHandler]);
+  const { mutate: mutateRecentlyUpdated } = useSWRINFxRecentlyUpdated(20, true);
+
 
   const save: Save = useCallback(async(revisionId, markdown, opts, onConflict) => {
     if (pageId == null || selectedGrant == null) {
@@ -190,6 +192,8 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
 
       // to sync revision id with page tree: https://github.com/weseek/growi/pull/7227
       mutatePageTree();
+
+      mutateRecentlyUpdated();
       // sync current grant data after update
       mutateIsGrantNormalized();
 
@@ -211,7 +215,7 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
     finally {
       mutateWaitingSaveProcessing(false);
     }
-  }, [pageId, selectedGrant, mutateWaitingSaveProcessing, updatePage, mutateIsGrantNormalized, t]);
+  }, [pageId, selectedGrant, mutateWaitingSaveProcessing, updatePage, mutateIsGrantNormalized, mutateRecentlyUpdated, t]);
 
   const saveAndReturnToViewHandler = useCallback(async(opts: SaveOptions) => {
     const markdown = codeMirrorEditor?.getDoc();

+ 8 - 5
apps/app/src/client/components/SearchPage/SearchResultContent.tsx

@@ -21,7 +21,7 @@ import { useCurrentUser } from '~/stores-universal/context';
 import {
   usePageDuplicateModal, usePageRenameModal, usePageDeleteModal,
 } from '~/stores/modal';
-import { mutatePageList, mutatePageTree } from '~/stores/page-listing';
+import { mutatePageList, mutatePageTree, useSWRINFxRecentlyUpdated } from '~/stores/page-listing';
 import { useSearchResultOptions } from '~/stores/renderer';
 import { mutateSearching } from '~/stores/search';
 
@@ -126,7 +126,7 @@ export const SearchResultContent: FC<Props> = (props: Props) => {
   const { open: openDeleteModal } = usePageDeleteModal();
   const { data: rendererOptions } = useSearchResultOptions(pageWithMeta.data.path, highlightKeywords);
   const { data: currentUser } = useCurrentUser();
-
+  const { mutate: mutateRecentlyUpdated } = useSWRINFxRecentlyUpdated(20, true);
   const shouldExpandContent = useShouldExpandContent(page);
 
   const duplicateItemClickedHandler = useCallback(async(pageToDuplicate) => {
@@ -135,22 +135,24 @@ export const SearchResultContent: FC<Props> = (props: Props) => {
       toastSuccess(t('duplicated_pages', { fromPath }));
 
       mutatePageTree();
+      mutateRecentlyUpdated();
       mutateSearching();
       mutatePageList();
     };
     openDuplicateModal(pageToDuplicate, { onDuplicated: duplicatedHandler });
-  }, [openDuplicateModal, t]);
+  }, [openDuplicateModal, mutateRecentlyUpdated, t]);
 
   const renameItemClickedHandler = useCallback((pageToRename: IPageToRenameWithMeta) => {
     const renamedHandler: OnRenamedFunction = (path) => {
       toastSuccess(t('renamed_pages', { path }));
 
       mutatePageTree();
+      mutateRecentlyUpdated();
       mutateSearching();
       mutatePageList();
     };
     openRenameModal(pageToRename, { onRenamed: renamedHandler });
-  }, [openRenameModal, t]);
+  }, [openRenameModal, mutateRecentlyUpdated, t]);
 
   const onDeletedHandler: OnDeletedFunction = useCallback((pathOrPathsToDelete, isRecursively, isCompletely) => {
     if (typeof pathOrPathsToDelete !== 'string') {
@@ -165,9 +167,10 @@ export const SearchResultContent: FC<Props> = (props: Props) => {
       toastSuccess(t('deleted_pages', { path }));
     }
     mutatePageTree();
+    mutateRecentlyUpdated();
     mutateSearching();
     mutatePageList();
-  }, [t]);
+  }, [mutateRecentlyUpdated, t]);
 
   const deleteItemClickedHandler = useCallback((pageToDelete: IPageToDeleteWithMeta) => {
     openDeleteModal([pageToDelete], { onDeleted: onDeletedHandler });

+ 9 - 4
apps/app/src/client/components/SearchPage/SearchResultList.tsx

@@ -12,7 +12,7 @@ import type { ISelectable, ISelectableAll } from '~/client/interfaces/selectable
 import { toastSuccess } from '~/client/util/toastr';
 import type { IPageSearchMeta, IPageWithSearchMeta } from '~/interfaces/search';
 import { useIsGuestUser, useIsReadOnlyUser } from '~/stores-universal/context';
-import { mutatePageTree, useSWRxPageInfoForList } from '~/stores/page-listing';
+import { mutatePageTree, useSWRxPageInfoForList, useSWRINFxRecentlyUpdated } from '~/stores/page-listing';
 import { mutateSearching } from '~/stores/search';
 
 import type { ForceHideMenuItems } from '../Common/Dropdown/PageItemControl';
@@ -89,20 +89,24 @@ const SearchResultListSubstance: ForwardRefRenderFunction<ISelectableAll, Props>
     });
   }
 
+  const { mutate: mutateRecentlyUpdated } = useSWRINFxRecentlyUpdated(20, true);
+
   // eslint-disable-next-line @typescript-eslint/no-unused-vars
   const duplicatedHandler = useCallback((fromPath, toPath) => {
     toastSuccess(t('duplicated_pages', { fromPath }));
 
     mutatePageTree();
+    mutateRecentlyUpdated();
     mutateSearching();
-  }, [t]);
+  }, [t, mutateRecentlyUpdated]);
 
   const renamedHandler = useCallback((path) => {
     toastSuccess(t('renamed_pages', { path }));
 
     mutatePageTree();
+    mutateRecentlyUpdated();
     mutateSearching();
-  }, [t]);
+  }, [t, mutateRecentlyUpdated]);
 
   const deletedHandler = useCallback((pathOrPathsToDelete, isRecursively, isCompletely) => {
     if (typeof pathOrPathsToDelete !== 'string') {
@@ -118,8 +122,9 @@ const SearchResultListSubstance: ForwardRefRenderFunction<ISelectableAll, Props>
       toastSuccess(t('deleted_pages', { path }));
     }
     mutatePageTree();
+    mutateRecentlyUpdated();
     mutateSearching();
-  }, [t]);
+  }, [t, mutateRecentlyUpdated]);
 
   return (
     <ul data-testid="search-result-list" className="page-list-ul list-group list-group-flush">

+ 6 - 3
apps/app/src/client/components/TreeItem/NewPageInput/use-new-page-input.tsx

@@ -11,12 +11,12 @@ import { useRect } from '@growi/ui/dist/utils';
 import { useTranslation } from 'next-i18next';
 import { debounce } from 'throttle-debounce';
 
+import { AutosizeSubmittableInput, getAdjustedMaxWidthForAutosizeInput } from '~/client/components/Common/SubmittableInput';
 import { useCreatePage } from '~/client/services/create-page';
 import { toastWarning, toastError, toastSuccess } from '~/client/util/toastr';
 import type { InputValidationResult } from '~/client/util/use-input-validator';
 import { ValidationTarget, useInputValidator } from '~/client/util/use-input-validator';
-import { AutosizeSubmittableInput, getAdjustedMaxWidthForAutosizeInput } from '~/client/components/Common/SubmittableInput';
-import { mutatePageTree } from '~/stores/page-listing';
+import { mutatePageTree, useSWRINFxRecentlyUpdated } from '~/stores/page-listing';
 import { usePageTreeDescCountMap } from '~/stores/ui';
 
 import { shouldCreateWipPage } from '../../../../utils/should-create-wip-page';
@@ -89,6 +89,8 @@ export const useNewPageInput = (): UseNewPageInput => {
       setShowInput(false);
     }, []);
 
+    const { mutate: mutateRecentlyUpdated } = useSWRINFxRecentlyUpdated(20, true);
+
     const create = useCallback(async(inputText) => {
       if (inputText.trim() === '') {
         return cancel();
@@ -123,6 +125,7 @@ export const useNewPageInput = (): UseNewPageInput => {
             skipTransition: true,
             onCreated: () => {
               mutatePageTree();
+              mutateRecentlyUpdated();
 
               if (!hasDescendants) {
                 stateHandlers?.setIsOpen(true);
@@ -139,7 +142,7 @@ export const useNewPageInput = (): UseNewPageInput => {
       finally {
         setProcessingSubmission(false);
       }
-    }, [cancel, hasDescendants, page.path, stateHandlers, t, createPage]);
+    }, [cancel, hasDescendants, page.path, stateHandlers, t, createPage, mutateRecentlyUpdated]);
 
     const inputContainerClass = newPageInputStyles['new-page-input-container'] ?? '';
     const isInvalid = validationResult != null;

+ 6 - 2
apps/app/src/components/PageView/PageAlerts/WipPageAlert.tsx

@@ -3,12 +3,14 @@ import React, { useCallback } from 'react';
 import { useTranslation } from 'react-i18next';
 
 import { useSWRMUTxCurrentPage, useSWRxCurrentPage } from '~/stores/page';
-
+import { useSWRINFxRecentlyUpdated } from '~/stores/page-listing';
 
 export const WipPageAlert = (): JSX.Element => {
   const { t } = useTranslation();
   const { data: currentPage } = useSWRxCurrentPage();
   const { trigger: mutateCurrentPage } = useSWRMUTxCurrentPage();
+  const { mutate: mutateRecentlyUpdated } = useSWRINFxRecentlyUpdated(20, true);
+
 
   const clickPagePublishButton = useCallback(async() => {
     const pageId = currentPage?._id;
@@ -26,6 +28,8 @@ export const WipPageAlert = (): JSX.Element => {
       const mutatePageTree = (await import('~/stores/page-listing')).mutatePageTree;
       await mutatePageTree();
 
+      await mutateRecentlyUpdated();
+
       const toastSuccess = (await import('~/client/util/toastr')).toastSuccess;
       toastSuccess(t('wip_page.success_publish_page'));
     }
@@ -33,7 +37,7 @@ export const WipPageAlert = (): JSX.Element => {
       const toastError = (await import('~/client/util/toastr')).toastError;
       toastError(t('wip_page.fail_publish_page'));
     }
-  }, [currentPage?._id, mutateCurrentPage, t]);
+  }, [currentPage?._id, mutateCurrentPage, t, mutateRecentlyUpdated]);
 
 
   if (!currentPage?.wip) {