Procházet zdrojové kódy

refactor IPageInfo

Yuki Takei před 4 roky
rodič
revize
34ce5bd8d8

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

@@ -9,17 +9,17 @@ import { useTranslation } from 'react-i18next';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
 import {
 import {
-  IPageInfo, IPageInfoCommon, isExistPageInfo,
+  IPageInfoAll, isIPageInfoForOperation,
 } from '~/interfaces/page';
 } from '~/interfaces/page';
 import { useSWRxPageInfo } from '~/stores/page';
 import { useSWRxPageInfo } from '~/stores/page';
 
 
 const logger = loggerFactory('growi:cli:PageItemControl');
 const logger = loggerFactory('growi:cli:PageItemControl');
 
 
 
 
-export type AdditionalMenuItemsRendererProps = { pageInfo: IPageInfoCommon | IPageInfo };
+export type AdditionalMenuItemsRendererProps = { pageInfo: IPageInfoAll };
 
 
 type CommonProps = {
 type CommonProps = {
-  pageInfo?: IPageInfoCommon | IPageInfo,
+  pageInfo?: IPageInfoAll,
   isEnableActions?: boolean,
   isEnableActions?: boolean,
   hideBookmarkMenuItem?: boolean,
   hideBookmarkMenuItem?: boolean,
   onClickBookmarkMenuItem?: (pageId: string, newValue?: boolean) => Promise<void>,
   onClickBookmarkMenuItem?: (pageId: string, newValue?: boolean) => Promise<void>,
@@ -46,7 +46,7 @@ const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.E
 
 
   // eslint-disable-next-line react-hooks/rules-of-hooks
   // eslint-disable-next-line react-hooks/rules-of-hooks
   const bookmarkItemClickedHandler = useCallback(async() => {
   const bookmarkItemClickedHandler = useCallback(async() => {
-    if (!isExistPageInfo(pageInfo) || onClickBookmarkMenuItem == null) {
+    if (!isIPageInfoForOperation(pageInfo) || onClickBookmarkMenuItem == null) {
       return;
       return;
     }
     }
     await onClickBookmarkMenuItem(pageId, !pageInfo.isBookmarked);
     await onClickBookmarkMenuItem(pageId, !pageInfo.isBookmarked);
@@ -62,7 +62,7 @@ const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.E
 
 
   // eslint-disable-next-line react-hooks/rules-of-hooks
   // eslint-disable-next-line react-hooks/rules-of-hooks
   const deleteItemClickedHandler = useCallback(async() => {
   const deleteItemClickedHandler = useCallback(async() => {
-    if (!isExistPageInfo(pageInfo) || onClickDeleteMenuItem == null) {
+    if (pageInfo == null || onClickDeleteMenuItem == null) {
       return;
       return;
     }
     }
     if (!pageInfo.isDeletable) {
     if (!pageInfo.isDeletable) {
@@ -88,7 +88,7 @@ const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.E
       ) }
       ) }
 
 
       {/* Bookmark */}
       {/* Bookmark */}
-      { !hideBookmarkMenuItem && isExistPageInfo(pageInfo) && isEnableActions && (
+      { !hideBookmarkMenuItem && isEnableActions && !pageInfo.isEmpty && isIPageInfoForOperation(pageInfo) && (
         <DropdownItem onClick={bookmarkItemClickedHandler}>
         <DropdownItem onClick={bookmarkItemClickedHandler}>
           <i className="fa fa-fw fa-bookmark-o"></i>
           <i className="fa fa-fw fa-bookmark-o"></i>
           { pageInfo.isBookmarked ? t('remove_bookmark') : t('add_bookmark') }
           { pageInfo.isBookmarked ? t('remove_bookmark') : t('add_bookmark') }
@@ -96,7 +96,7 @@ const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.E
       ) }
       ) }
 
 
       {/* Duplicate */}
       {/* Duplicate */}
-      { isExistPageInfo(pageInfo) && isEnableActions && (
+      { isEnableActions && !pageInfo.isEmpty && (
         <DropdownItem onClick={() => toastr.warning(t('search_result.currently_not_implemented'))}>
         <DropdownItem onClick={() => toastr.warning(t('search_result.currently_not_implemented'))}>
           <i className="icon-fw icon-docs"></i>
           <i className="icon-fw icon-docs"></i>
           {t('Duplicate')}
           {t('Duplicate')}
@@ -115,7 +115,7 @@ const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.E
 
 
       {/* divider */}
       {/* divider */}
       {/* Delete */}
       {/* Delete */}
-      { isExistPageInfo(pageInfo) && isEnableActions && pageInfo.isMovable && (
+      { isEnableActions && pageInfo.isMovable && !pageInfo.isEmpty && (
         <>
         <>
           <DropdownItem divider />
           <DropdownItem divider />
           <DropdownItem
           <DropdownItem

+ 1 - 1
packages/app/src/components/IdenticalPathPage.tsx

@@ -9,7 +9,7 @@ import { useCurrentPagePath } from '~/stores/context';
 
 
 import { PageListItemL } from './PageList/PageListItemL';
 import { PageListItemL } from './PageList/PageListItemL';
 import { useSWRxPageInfoForList } from '~/stores/page';
 import { useSWRxPageInfoForList } from '~/stores/page';
-import { IPageInfoForList, IPageWithMeta } from '~/interfaces/page';
+import { IPageWithMeta } from '~/interfaces/page';
 
 
 
 
 type IdenticalPathAlertProps = {
 type IdenticalPathAlertProps = {

+ 21 - 9
packages/app/src/components/Navbar/SubNavButtons.tsx

@@ -1,6 +1,6 @@
 import React, { useCallback } from 'react';
 import React, { useCallback } from 'react';
 
 
-import { IPageInfo, isExistPageInfo } from '~/interfaces/page';
+import { IPageInfoAll, isIPageInfoForEntity, isIPageInfoForOperation } from '~/interfaces/page';
 
 
 import { useSWRxPageInfo } from '../../stores/page';
 import { useSWRxPageInfo } from '../../stores/page';
 import { useSWRBookmarkInfo } from '../../stores/bookmark';
 import { useSWRBookmarkInfo } from '../../stores/bookmark';
@@ -25,7 +25,7 @@ type CommonProps = {
 type SubNavButtonsSubstanceProps= CommonProps & {
 type SubNavButtonsSubstanceProps= CommonProps & {
   pageId: string,
   pageId: string,
   revisionId: string,
   revisionId: string,
-  pageInfo: IPageInfo,
+  pageInfo: IPageInfoAll,
 }
 }
 
 
 const SubNavButtonsSubstance = (props: SubNavButtonsSubstanceProps): JSX.Element => {
 const SubNavButtonsSubstance = (props: SubNavButtonsSubstanceProps): JSX.Element => {
@@ -39,8 +39,8 @@ const SubNavButtonsSubstance = (props: SubNavButtonsSubstanceProps): JSX.Element
 
 
   const { data: bookmarkInfo, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(pageId);
   const { data: bookmarkInfo, mutate: mutateBookmarkInfo } = useSWRBookmarkInfo(pageId);
 
 
-  const likerIds = pageInfo.likerIds != null ? pageInfo.likerIds.slice(0, 15) : [];
-  const seenUserIds = pageInfo.seenUserIds != null ? pageInfo.seenUserIds.slice(0, 15) : [];
+  const likerIds = isIPageInfoForEntity(pageInfo) ? pageInfo.likerIds.slice(0, 15) : [];
+  const seenUserIds = isIPageInfoForEntity(pageInfo) ? pageInfo.seenUserIds.slice(0, 15) : [];
 
 
   // Put in a mixture of seenUserIds and likerIds data to make the cache work
   // Put in a mixture of seenUserIds and likerIds data to make the cache work
   const { data: usersList } = useSWRxUsersList([...likerIds, ...seenUserIds]);
   const { data: usersList } = useSWRxUsersList([...likerIds, ...seenUserIds]);
@@ -51,30 +51,42 @@ const SubNavButtonsSubstance = (props: SubNavButtonsSubstanceProps): JSX.Element
     if (isGuestUser == null || isGuestUser) {
     if (isGuestUser == null || isGuestUser) {
       return;
       return;
     }
     }
+    if (!isIPageInfoForOperation(pageInfo)) {
+      return;
+    }
 
 
     await toggleSubscribe(pageId, pageInfo.subscriptionStatus);
     await toggleSubscribe(pageId, pageInfo.subscriptionStatus);
     mutatePageInfo();
     mutatePageInfo();
-  }, [isGuestUser, mutatePageInfo, pageId, pageInfo.subscriptionStatus]);
+  }, [isGuestUser, mutatePageInfo, pageId, pageInfo]);
 
 
   const likeClickhandler = useCallback(async() => {
   const likeClickhandler = useCallback(async() => {
     if (isGuestUser == null || isGuestUser) {
     if (isGuestUser == null || isGuestUser) {
       return;
       return;
     }
     }
+    if (!isIPageInfoForOperation(pageInfo)) {
+      return;
+    }
 
 
     await toggleLike(pageId, pageInfo.isLiked);
     await toggleLike(pageId, pageInfo.isLiked);
     mutatePageInfo();
     mutatePageInfo();
-  }, [isGuestUser, mutatePageInfo, pageId, pageInfo.isLiked]);
+  }, [isGuestUser, mutatePageInfo, pageId, pageInfo]);
 
 
   const bookmarkClickHandler = useCallback(async() => {
   const bookmarkClickHandler = useCallback(async() => {
     if (isGuestUser == null || isGuestUser) {
     if (isGuestUser == null || isGuestUser) {
       return;
       return;
     }
     }
+    if (!isIPageInfoForOperation(pageInfo)) {
+      return;
+    }
 
 
     await toggleBookmark(pageId, pageInfo.isBookmarked);
     await toggleBookmark(pageId, pageInfo.isBookmarked);
     mutatePageInfo();
     mutatePageInfo();
     mutateBookmarkInfo();
     mutateBookmarkInfo();
-  }, [isGuestUser, mutateBookmarkInfo, mutatePageInfo, pageId, pageInfo.isBookmarked]);
+  }, [isGuestUser, mutateBookmarkInfo, mutatePageInfo, pageId, pageInfo]);
 
 
+  if (!isIPageInfoForOperation(pageInfo)) {
+    return <></>;
+  }
 
 
   const {
   const {
     sumOfLikers, isLiked, bookmarkCount, isBookmarked,
     sumOfLikers, isLiked, bookmarkCount, isBookmarked,
@@ -135,11 +147,11 @@ export const SubNavButtons = (props: SubNavButtonsProps): JSX.Element => {
 
 
   const { data: pageInfo, error } = useSWRxPageInfo(pageId ?? null);
   const { data: pageInfo, error } = useSWRxPageInfo(pageId ?? null);
 
 
-  if (revisionId == null || pageInfo == null || error != null) {
+  if (revisionId == null || error != null) {
     return <></>;
     return <></>;
   }
   }
 
 
-  if (!isExistPageInfo(pageInfo)) {
+  if (!isIPageInfoForOperation(pageInfo)) {
     return <></>;
     return <></>;
   }
   }
 
 

+ 11 - 7
packages/app/src/components/PageList/PageListItemL.tsx

@@ -5,13 +5,15 @@ import Clamp from 'react-multiline-clamp';
 import { UserPicture, PageListMeta, PagePathLabel } from '@growi/ui';
 import { UserPicture, PageListMeta, PagePathLabel } from '@growi/ui';
 import { DevidedPagePath } from '@growi/core';
 import { DevidedPagePath } from '@growi/core';
 import { useIsDeviceSmallerThanLg } from '~/stores/ui';
 import { useIsDeviceSmallerThanLg } from '~/stores/ui';
-import { IPageInfoForList, IPageWithMeta, isIPageInfoForList } from '~/interfaces/page';
+import {
+  IPageInfoAll, IPageWithMeta, isIPageInfoForEntity, isIPageInfoForListing,
+} from '~/interfaces/page';
 import { IPageSearchMeta, isIPageSearchMeta } from '~/interfaces/search';
 import { IPageSearchMeta, isIPageSearchMeta } from '~/interfaces/search';
 
 
 import { AsyncPageItemControl } from '../Common/Dropdown/PageItemControl';
 import { AsyncPageItemControl } from '../Common/Dropdown/PageItemControl';
 
 
 type Props = {
 type Props = {
-  page: IPageWithMeta | IPageWithMeta<IPageSearchMeta> | IPageWithMeta<IPageInfoForList>,
+  page: IPageWithMeta | IPageWithMeta<IPageInfoAll & IPageSearchMeta>,
   isSelected?: boolean, // is item selected(focused)
   isSelected?: boolean, // is item selected(focused)
   isChecked?: boolean, // is checkbox of item checked
   isChecked?: boolean, // is checkbox of item checked
   isEnableActions?: boolean,
   isEnableActions?: boolean,
@@ -21,7 +23,7 @@ type Props = {
   onClickDeleteButton?: (pageId: string) => void,
   onClickDeleteButton?: (pageId: string) => void,
 }
 }
 
 
-export const PageListItemL: FC<Props> = memo((props:Props) => {
+export const PageListItemL = memo((props: Props): JSX.Element => {
   const {
   const {
     // todo: refactoring variable name to clear what changed
     // todo: refactoring variable name to clear what changed
     page: { pageData, pageMeta }, isSelected, onClickItem, onClickCheckbox, isChecked, isEnableActions,
     page: { pageData, pageMeta }, isSelected, onClickItem, onClickCheckbox, isChecked, isEnableActions,
@@ -33,7 +35,7 @@ export const PageListItemL: FC<Props> = memo((props:Props) => {
   const pagePath: DevidedPagePath = new DevidedPagePath(pageData.path, true);
   const pagePath: DevidedPagePath = new DevidedPagePath(pageData.path, true);
 
 
   const elasticSearchResult = isIPageSearchMeta(pageMeta) ? pageMeta.elasticSearchResult : null;
   const elasticSearchResult = isIPageSearchMeta(pageMeta) ? pageMeta.elasticSearchResult : null;
-  const revisionShortBody = isIPageInfoForList(pageMeta) ? pageMeta.revisionShortBody : null;
+  const revisionShortBody = isIPageInfoForListing(pageMeta) ? pageMeta.revisionShortBody : null;
 
 
   const pageTitle = (
   const pageTitle = (
     <PagePathLabel
     <PagePathLabel
@@ -113,9 +115,11 @@ export const PageListItemL: FC<Props> = memo((props:Props) => {
               </Clamp>
               </Clamp>
 
 
               {/* page meta */}
               {/* page meta */}
-              <div className="d-none d-md-flex py-0 px-1">
-                <PageListMeta page={pageData} bookmarkCount={pageMeta?.bookmarkCount} shouldSpaceOutIcon />
-              </div>
+              { isIPageInfoForEntity(pageMeta) && (
+                <div className="d-none d-md-flex py-0 px-1">
+                  <PageListMeta page={pageData} bookmarkCount={pageMeta.bookmarkCount} shouldSpaceOutIcon />
+                </div>
+              ) }
               {/* doropdown icon includes page control buttons */}
               {/* doropdown icon includes page control buttons */}
               <div className="item-control ml-auto">
               <div className="item-control ml-auto">
                 {/* TODO: use PageItemControl with prefetched IPageInfo object */}
                 {/* TODO: use PageItemControl with prefetched IPageInfo object */}

+ 2 - 2
packages/app/src/components/SearchPage/SearchResultList.tsx

@@ -1,5 +1,5 @@
 import React, { FC } from 'react';
 import React, { FC } from 'react';
-import { IPageWithMeta } from '~/interfaces/page';
+import { IPageInfoForEntity, IPageWithMeta } from '~/interfaces/page';
 import { IPageSearchMeta } from '~/interfaces/search';
 import { IPageSearchMeta } from '~/interfaces/search';
 
 
 import { PageListItemL } from '../PageList/PageListItemL';
 import { PageListItemL } from '../PageList/PageListItemL';
@@ -7,7 +7,7 @@ import PaginationWrapper from '../PaginationWrapper';
 
 
 
 
 type Props = {
 type Props = {
-  pages: IPageWithMeta<IPageSearchMeta>[],
+  pages: IPageWithMeta<IPageInfoForEntity & IPageSearchMeta>[],
   selectedPagesIdList: Set<string>
   selectedPagesIdList: Set<string>
   isEnableActions: boolean,
   isEnableActions: boolean,
   searchResultCount?: number,
   searchResultCount?: number,

+ 37 - 10
packages/app/src/interfaces/page.ts

@@ -36,37 +36,64 @@ export type IPageHasId = IPage & HasObjectId;
 
 
 export type IPageForItem = Partial<IPageHasId & {isTarget?: boolean}>;
 export type IPageForItem = Partial<IPageHasId & {isTarget?: boolean}>;
 
 
-export type IPageInfoCommon = {
+export type IPageInfo = {
   isEmpty: boolean,
   isEmpty: boolean,
   isMovable: boolean,
   isMovable: boolean,
   isDeletable: boolean,
   isDeletable: boolean,
   isAbleToDeleteCompletely: boolean,
   isAbleToDeleteCompletely: boolean,
 }
 }
 
 
-export type IPageInfo = IPageInfoCommon & {
+export type IPageInfoForEntity = IPageInfo & {
   bookmarkCount: number,
   bookmarkCount: number,
   sumOfLikers: number,
   sumOfLikers: number,
   likerIds: string[],
   likerIds: string[],
   sumOfSeenUsers: number,
   sumOfSeenUsers: number,
   seenUserIds: string[],
   seenUserIds: string[],
+}
 
 
+export type IPageInfoForOperation = IPageInfoForEntity & {
   isBookmarked?: boolean,
   isBookmarked?: boolean,
   isLiked?: boolean,
   isLiked?: boolean,
   subscriptionStatus?: SubscriptionStatusType,
   subscriptionStatus?: SubscriptionStatusType,
 }
 }
 
 
-export type IPageInfoForList = IPageInfo & HasRevisionShortbody;
+export type IPageInfoForListing = IPageInfoForEntity & HasRevisionShortbody;
+
+export type IPageInfoAll = IPageInfo | IPageInfoForEntity | IPageInfoForOperation | IPageInfoForListing;
+
+export const isIPageInfoForEntity = (pageInfo: IPageInfoAll | undefined): pageInfo is IPageInfoForEntity => {
+  return pageInfo != null && !pageInfo.isEmpty && 'bookmarkCount' in pageInfo;
+};
 
 
-export const isExistPageInfo = (pageInfo: IPageInfoCommon | undefined): pageInfo is IPageInfo => {
-  return pageInfo != null && !pageInfo.isEmpty;
+export const isIPageInfoForOperation = (pageInfo: IPageInfoAll | undefined): pageInfo is IPageInfoForOperation => {
+  return pageInfo != null
+    && isIPageInfoForEntity(pageInfo)
+    && ('isBookmarked' in pageInfo || 'isLiked' in pageInfo || 'subscriptionStatus' in pageInfo);
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
-export const isIPageInfoForList = (pageInfo: any): pageInfo is IPageInfoForList => {
-  return pageInfo != null && pageInfo.revisionShortBody != null;
+export const isIPageInfoForListing = (pageInfo: IPageInfoAll | undefined): pageInfo is IPageInfoForListing => {
+  return pageInfo != null
+    && isIPageInfoForEntity(pageInfo)
+    && 'revisionShortBody' in pageInfo;
 };
 };
 
 
-export type IPageWithMeta<M = Record<string, unknown>> = {
+// export type IPageInfoTypeResolver<T extends IPageInfo> =
+//   T extends HasRevisionShortbody ? IPageInfoForListing :
+//   T extends { isBookmarked?: boolean } | { isLiked?: boolean } | { subscriptionStatus?: SubscriptionStatusType } ? IPageInfoForOperation :
+//   T extends { bookmarkCount: number } ? IPageInfoForEntity :
+//   T extends { isEmpty: number } ? IPageInfo :
+//   T;
+
+/**
+ * Union Distribution
+ * @param pageInfo
+ * @returns
+ */
+// export const resolvePageInfo = <T extends IPageInfo>(pageInfo: T | undefined): IPageInfoTypeResolver<T> => {
+//   return <IPageInfoTypeResolver<T>>pageInfo;
+// };
+
+export type IPageWithMeta<M = IPageInfoAll> = {
   pageData: IPageHasId,
   pageData: IPageHasId,
-  pageMeta?: Partial<IPageInfo> & M,
+  pageMeta?: M,
 };
 };

+ 3 - 4
packages/app/src/interfaces/search.ts

@@ -1,4 +1,4 @@
-import { IPageWithMeta } from './page';
+import { IPageInfoAll, IPageWithMeta } from './page';
 
 
 export enum CheckboxType {
 export enum CheckboxType {
   NONE_CHECKED = 'noneChecked',
   NONE_CHECKED = 'noneChecked',
@@ -14,9 +14,8 @@ export type IPageSearchMeta = {
   };
   };
 }
 }
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
-export const isIPageSearchMeta = (meta: any): meta is IPageSearchMeta => {
-  return !!(meta as IPageSearchMeta)?.elasticSearchResult;
+export const isIPageSearchMeta = (meta: IPageInfoAll | (IPageInfoAll & IPageSearchMeta) | undefined): meta is IPageInfoAll & IPageSearchMeta => {
+  return meta != null && 'elasticSearchResult' in meta;
 };
 };
 
 
 export type IFormattedSearchResult = {
 export type IFormattedSearchResult = {

+ 5 - 5
packages/app/src/server/routes/apiv3/page-listing.ts

@@ -8,7 +8,7 @@ import ErrorV3 from '../../models/vo/error-apiv3';
 import loggerFactory from '../../../utils/logger';
 import loggerFactory from '../../../utils/logger';
 import Crowi from '../../crowi';
 import Crowi from '../../crowi';
 import { ApiV3Response } from './interfaces/apiv3-response';
 import { ApiV3Response } from './interfaces/apiv3-response';
-import { IPageInfoForList, IPageInfoCommon, isExistPageInfo } from '~/interfaces/page';
+import { IPageInfoAll, isIPageInfoForEntity, IPageInfoForListing } from '~/interfaces/page';
 import PageService from '../../service/page';
 import PageService from '../../service/page';
 
 
 const logger = loggerFactory('growi:routes:apiv3:page-tree');
 const logger = loggerFactory('growi:routes:apiv3:page-tree');
@@ -114,20 +114,20 @@ export default (crowi: Crowi): Router => {
       const shortBodiesMap = await pageService.shortBodiesMapByPageIds(foundIds, req.user);
       const shortBodiesMap = await pageService.shortBodiesMapByPageIds(foundIds, req.user);
       const bookmarkCountMap = await Bookmark.getPageIdToCountMap(foundIds) as Record<string, number>;
       const bookmarkCountMap = await Bookmark.getPageIdToCountMap(foundIds) as Record<string, number>;
 
 
-      const idToPageInfoMap: Record<string, IPageInfoCommon|IPageInfoForList> = {};
+      const idToPageInfoMap: Record<string, IPageInfoAll> = {};
 
 
       for (const page of pages) {
       for (const page of pages) {
-        // construct IPageInfoForList
+        // construct isIPageInfoForListing
         const basicPageInfo = pageService.constructBasicPageInfo(page);
         const basicPageInfo = pageService.constructBasicPageInfo(page);
 
 
-        const pageInfo: IPageInfoCommon | IPageInfoForList = (!isExistPageInfo(basicPageInfo))
+        const pageInfo = (!isIPageInfoForEntity(basicPageInfo))
           ? basicPageInfo
           ? basicPageInfo
           // create IPageInfoForList
           // create IPageInfoForList
           : {
           : {
             ...basicPageInfo,
             ...basicPageInfo,
             bookmarkCount: bookmarkCountMap[page._id],
             bookmarkCount: bookmarkCountMap[page._id],
             revisionShortBody: shortBodiesMap[page._id],
             revisionShortBody: shortBodiesMap[page._id],
-          } as IPageInfoForList;
+          } as IPageInfoForListing;
 
 
         idToPageInfoMap[page._id] = pageInfo;
         idToPageInfoMap[page._id] = pageInfo;
       }
       }

+ 2 - 2
packages/app/src/server/service/page.ts

@@ -14,7 +14,7 @@ import {
 import { stringifySnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
 import { stringifySnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
 import ActivityDefine from '../util/activityDefine';
 import ActivityDefine from '../util/activityDefine';
 import {
 import {
-  IPage, IPageInfo, IPageInfoCommon,
+  IPage, IPageInfo, IPageInfoForEntity,
 } from '~/interfaces/page';
 } from '~/interfaces/page';
 import { PageRedirectModel } from '../models/page-redirect';
 import { PageRedirectModel } from '../models/page-redirect';
 import { ObjectIdLike } from '../interfaces/mongoose-utils';
 import { ObjectIdLike } from '../interfaces/mongoose-utils';
@@ -1613,7 +1613,7 @@ class PageService {
     });
     });
   }
   }
 
 
-  constructBasicPageInfo(page: IPage, isGuestUser?: boolean): IPageInfoCommon | IPageInfo {
+  constructBasicPageInfo(page: IPage, isGuestUser?: boolean): IPageInfo | IPageInfoForEntity {
     if (page.isEmpty) {
     if (page.isEmpty) {
       return {
       return {
         isEmpty: true,
         isEmpty: true,

+ 3 - 3
packages/app/src/stores/page.tsx

@@ -4,7 +4,7 @@ import useSWRImmutable from 'swr/immutable';
 import { apiv3Get } from '~/client/util/apiv3-client';
 import { apiv3Get } from '~/client/util/apiv3-client';
 
 
 import {
 import {
-  IPageInfo, IPageInfoCommon, IPageInfoForList, IPageHasId,
+  IPageInfo, IPageHasId, IPageInfoForOperation, IPageInfoForListing,
 } from '~/interfaces/page';
 } from '~/interfaces/page';
 import { IPagingResult } from '~/interfaces/paging-result';
 import { IPagingResult } from '~/interfaces/paging-result';
 import { apiGet } from '../client/util/apiv1-client';
 import { apiGet } from '../client/util/apiv1-client';
@@ -59,14 +59,14 @@ export const useSWRTagsInfo = (pageId: string | null | undefined): SWRResponse<I
   }));
   }));
 };
 };
 
 
-export const useSWRxPageInfo = (pageId: string | null | undefined): SWRResponse<IPageInfoCommon | IPageInfo, Error> => {
+export const useSWRxPageInfo = (pageId: string | null | undefined): SWRResponse<IPageInfo | IPageInfoForOperation, Error> => {
   return useSWRImmutable(
   return useSWRImmutable(
     pageId != null ? ['/page/info', pageId] : null,
     pageId != null ? ['/page/info', pageId] : null,
     (endpoint, pageId) => apiv3Get(endpoint, { pageId }).then(response => response.data),
     (endpoint, pageId) => apiv3Get(endpoint, { pageId }).then(response => response.data),
   );
   );
 };
 };
 
 
-export const useSWRxPageInfoForList = (pageIds: string[] | null | undefined): SWRResponse<Record<string, IPageInfoCommon|IPageInfoForList>, Error> => {
+export const useSWRxPageInfoForList = (pageIds: string[] | null | undefined): SWRResponse<Record<string, IPageInfo | IPageInfoForListing>, Error> => {
 
 
   const shouldFetch = pageIds != null && pageIds.length > 0;
   const shouldFetch = pageIds != null && pageIds.length > 0;