ソースを参照

Merge pull request #6124 from weseek/imprv/83341-template-tag-data

imprv: Reflect tmp tag data
cao 3 年 前
コミット
6c32a00d31

+ 15 - 2
packages/app/src/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -17,7 +17,7 @@ import { IResTagsUpdateApiv1 } from '~/interfaces/tag';
 import { OnDuplicatedFunction, OnRenamedFunction, OnDeletedFunction } from '~/interfaces/ui';
 import { OnDuplicatedFunction, OnRenamedFunction, OnDeletedFunction } from '~/interfaces/ui';
 import {
 import {
   useCurrentCreatedAt, useCurrentUpdatedAt, useCurrentPageId, useRevisionId, useCurrentPagePath,
   useCurrentCreatedAt, useCurrentUpdatedAt, useCurrentPageId, useRevisionId, useCurrentPagePath,
-  useCreator, useRevisionAuthor, useCurrentUser, useIsGuestUser, useIsSharedUser, useShareLinkId, useEmptyPageId,
+  useCreator, useRevisionAuthor, useCurrentUser, useIsGuestUser, useIsSharedUser, useShareLinkId, useEmptyPageId, useTemplateTagData,
 } from '~/stores/context';
 } from '~/stores/context';
 import { usePageTagsForEditors } from '~/stores/editor';
 import { usePageTagsForEditors } from '~/stores/editor';
 import {
 import {
@@ -178,13 +178,26 @@ const GrowiContextualSubNavigation = (props) => {
   const { open: openDuplicateModal } = usePageDuplicateModal();
   const { open: openDuplicateModal } = usePageDuplicateModal();
   const { open: openRenameModal } = usePageRenameModal();
   const { open: openRenameModal } = usePageRenameModal();
   const { open: openDeleteModal } = usePageDeleteModal();
   const { open: openDeleteModal } = usePageDeleteModal();
+  const { data: templateTagData } = useTemplateTagData();
+
 
 
   useEffect(() => {
   useEffect(() => {
     // Run only when tagsInfoData has been updated
     // Run only when tagsInfoData has been updated
-    syncPageTagsForEditors();
+    if (templateTagData == null) {
+      syncPageTagsForEditors();
+    }
     // eslint-disable-next-line react-hooks/exhaustive-deps
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [tagsInfoData?.tags]);
   }, [tagsInfoData?.tags]);
 
 
+  useEffect(() => {
+    if (pageId === null && templateTagData != null) {
+      const tags = templateTagData.split(',').filter((str: string) => {
+        return str !== ''; // filter empty values
+      });
+      mutatePageTagsForEditors(tags);
+    }
+  }, [pageId, mutatePageTagsForEditors, templateTagData, mutateSWRTagsInfo]);
+
   const [isPageTemplateModalShown, setIsPageTempleteModalShown] = useState(false);
   const [isPageTemplateModalShown, setIsPageTempleteModalShown] = useState(false);
 
 
   const {
   const {

+ 1 - 2
packages/app/src/components/Navbar/GrowiSubNavigation.tsx

@@ -71,8 +71,7 @@ export const GrowiSubNavigation = (props: Props): JSX.Element => {
         ) }
         ) }
 
 
         <div className="grw-path-nav-container">
         <div className="grw-path-nav-container">
-          {/* "/trash" page does not exist on page collection and unable to add tags  */}
-          { showTagLabel && !isCompactMode && path !== '/trash' && (
+          { showTagLabel && !isCompactMode && (
             <div className="grw-taglabels-container">
             <div className="grw-taglabels-container">
               <TagLabels tags={tags} isGuestUser={isGuestUser ?? false} tagsUpdateInvoked={tagsUpdatedHandler} />
               <TagLabels tags={tags} isGuestUser={isGuestUser ?? false} tagsUpdateInvoked={tagsUpdatedHandler} />
             </div>
             </div>

+ 1 - 0
packages/app/src/server/routes/page.js

@@ -324,6 +324,7 @@ module.exports = function(crowi, app) {
       // retrieve templates
       // retrieve templates
       if (req.user != null) {
       if (req.user != null) {
         const template = await Page.findTemplate(path);
         const template = await Page.findTemplate(path);
+
         if (template.templateBody) {
         if (template.templateBody) {
           const body = replacePlaceholdersOfTemplate(template.templateBody, req);
           const body = replacePlaceholdersOfTemplate(template.templateBody, req);
           const tags = template.templateTags;
           const tags = template.templateTags;

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

@@ -86,8 +86,8 @@ export const useHasChildren = (initialData?: Nullable<any>): SWRResponse<Nullabl
   return useStaticSWR<Nullable<any>, Error>('hasChildren', initialData);
   return useStaticSWR<Nullable<any>, Error>('hasChildren', initialData);
 };
 };
 
 
-export const useTemplateTagData = (initialData?: Nullable<any>): SWRResponse<Nullable<any>, Error> => {
-  return useStaticSWR<Nullable<any>, Error>('templateTagData', initialData);
+export const useTemplateTagData = (initialData?: Nullable<string>): SWRResponse<Nullable<string>, Error> => {
+  return useStaticSWR<Nullable<string>, Error>('templateTagData', initialData);
 };
 };
 
 
 export const useShareLinksNumber = (initialData?: Nullable<any>): SWRResponse<Nullable<any>, Error> => {
 export const useShareLinksNumber = (initialData?: Nullable<any>): SWRResponse<Nullable<any>, Error> => {

+ 20 - 8
packages/app/src/stores/page.tsx

@@ -15,7 +15,9 @@ import { apiGet } from '../client/util/apiv1-client';
 import { Nullable } from '../interfaces/common';
 import { Nullable } from '../interfaces/common';
 import { IPageTagsInfo } from '../interfaces/tag';
 import { IPageTagsInfo } from '../interfaces/tag';
 
 
-import { useCurrentPageId, useCurrentPagePath } from './context';
+import {
+  useCurrentPageId, useCurrentPagePath,
+} from './context';
 import { ITermNumberManagerUtil, useTermNumberManager } from './use-static-swr';
 import { ITermNumberManagerUtil, useTermNumberManager } from './use-static-swr';
 
 
 
 
@@ -93,14 +95,24 @@ export const useSWRxDescendantsPageListForCurrrentPath = (pageNumber?: number):
   return useSWRxPageList(path, pageNumber, termNumber);
   return useSWRxPageList(path, pageNumber, termNumber);
 };
 };
 
 
-export const useSWRxTagsInfo = (pageId: Nullable<string>): SWRResponse<IPageTagsInfo, Error> => {
-  const key = pageId == null ? null : `/pages.getPageTag?pageId=${pageId}`;
 
 
-  return useSWRImmutable(key, endpoint => apiGet(endpoint).then((response: IPageTagsInfo) => {
-    return {
-      tags: response.tags,
-    };
-  }));
+export const useSWRxTagsInfo = (pageId: Nullable<string>): SWRResponse<IPageTagsInfo | undefined, Error> => {
+
+  const endpoint = `/pages.getPageTag?pageId=${pageId}`;
+  const key = [endpoint, pageId];
+
+  const fetcher = async(endpoint: string, pageId: Nullable<string>) => {
+    let tags: string[] = [];
+    // when the page exists
+    if (pageId != null) {
+      const res = await apiGet<IPageTagsInfo>(endpoint, { pageId });
+      tags = res?.tags;
+    }
+
+    return { tags };
+  };
+
+  return useSWRImmutable(key, fetcher);
 };
 };
 
 
 export const useSWRxPageInfo = (
 export const useSWRxPageInfo = (

+ 7 - 7
packages/app/src/stores/ui.tsx

@@ -1,8 +1,6 @@
 import { RefObject } from 'react';
 import { RefObject } from 'react';
 
 
-import { constants } from 'zlib';
-
-import { isClient, pagePathUtils } from '@growi/core';
+import { isClient } from '@growi/core';
 import { Breakpoint, addBreakpointListener } from '@growi/ui';
 import { Breakpoint, addBreakpointListener } from '@growi/ui';
 import SimpleBar from 'simplebar-react';
 import SimpleBar from 'simplebar-react';
 import {
 import {
@@ -19,15 +17,15 @@ import { SidebarContentsType } from '~/interfaces/ui';
 import { UpdateDescCountData } from '~/interfaces/websocket';
 import { UpdateDescCountData } from '~/interfaces/websocket';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
+import { isTrashTopPage } from '../../../core/src/utils/page-path-utils';
+
 import {
 import {
   useCurrentPageId, useCurrentPagePath, useIsEditable, useIsTrashPage, useIsUserPage, useIsGuestUser, useEmptyPageId,
   useCurrentPageId, useCurrentPagePath, useIsEditable, useIsTrashPage, useIsUserPage, useIsGuestUser, useEmptyPageId,
-  useIsNotCreatable, useIsSharedUser, useNotFoundTargetPathOrId, useIsForbidden, useIsIdenticalPath, useCurrentUser,
+  useIsNotCreatable, useIsSharedUser, useNotFoundTargetPathOrId, useIsForbidden, useIsIdenticalPath, useCurrentUser, useShareLinkId,
 } from './context';
 } from './context';
 import { localStorageMiddleware } from './middlewares/sync-to-storage';
 import { localStorageMiddleware } from './middlewares/sync-to-storage';
 import { useStaticSWR } from './use-static-swr';
 import { useStaticSWR } from './use-static-swr';
 
 
-const { isSharedPage } = pagePathUtils;
-
 const logger = loggerFactory('growi:stores:ui');
 const logger = loggerFactory('growi:stores:ui');
 
 
 
 
@@ -426,6 +424,7 @@ export const useIsAbleToShowTagLabel = (): SWRResponse<boolean, Error> => {
   const { data: isIdenticalPath } = useIsIdenticalPath();
   const { data: isIdenticalPath } = useIsIdenticalPath();
   const { data: notFoundTargetPathOrId } = useNotFoundTargetPathOrId();
   const { data: notFoundTargetPathOrId } = useNotFoundTargetPathOrId();
   const { data: editorMode } = useEditorMode();
   const { data: editorMode } = useEditorMode();
+  const { data: shareLinkId } = useShareLinkId();
 
 
   const includesUndefined = [isUserPage, currentPagePath, isIdenticalPath, notFoundTargetPathOrId, editorMode].some(v => v === undefined);
   const includesUndefined = [isUserPage, currentPagePath, isIdenticalPath, notFoundTargetPathOrId, editorMode].some(v => v === undefined);
 
 
@@ -434,8 +433,9 @@ export const useIsAbleToShowTagLabel = (): SWRResponse<boolean, Error> => {
 
 
   return useSWRImmutable(
   return useSWRImmutable(
     includesUndefined ? null : [key, editorMode],
     includesUndefined ? null : [key, editorMode],
+    // "/trash" page does not exist on page collection and unable to add tags
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    () => !isUserPage && !isSharedPage(currentPagePath!) && !isIdenticalPath && !(isViewMode && isNotFoundPage),
+    () => !isUserPage && !isTrashTopPage(currentPagePath!) && shareLinkId == null && !isIdenticalPath && !(isViewMode && isNotFoundPage),
   );
   );
 };
 };
 
 

+ 8 - 0
packages/core/src/utils/page-path-utils.ts

@@ -61,6 +61,14 @@ export const isUserPage = (path: string): boolean => {
   return false;
   return false;
 };
 };
 
 
+/**
+ * Whether path is the top page of users
+ * @param path
+ */
+export const isTrashTopPage = (path: string): boolean => {
+  return path === '/trash';
+};
+
 /**
 /**
  * Whether path belongs to the trash page
  * Whether path belongs to the trash page
  * @param path
  * @param path