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

Merge pull request #6073 from weseek/fix/98146-revision-err-related-tag-edt

fix: Revision err when updating tags
Yuki Takei 3 лет назад
Родитель
Сommit
b07761cc1c

+ 12 - 7
packages/app/src/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -5,12 +5,13 @@ import { useTranslation } from 'react-i18next';
 import { DropdownItem } from 'reactstrap';
 import { DropdownItem } from 'reactstrap';
 
 
 import EditorContainer from '~/client/services/EditorContainer';
 import EditorContainer from '~/client/services/EditorContainer';
+import PageContainer from '~/client/services/PageContainer';
 import { exportAsMarkdown } from '~/client/services/page-operation';
 import { exportAsMarkdown } from '~/client/services/page-operation';
 import { toastSuccess, toastError } from '~/client/util/apiNotification';
 import { toastSuccess, toastError } from '~/client/util/apiNotification';
 import { apiPost } from '~/client/util/apiv1-client';
 import { apiPost } from '~/client/util/apiv1-client';
-import {
-  IPageHasId, IPageToRenameWithMeta, IPageWithMeta,
-} from '~/interfaces/page';
+import { getIdForRef } from '~/interfaces/common';
+import { IPageHasId, IPageToRenameWithMeta, IPageWithMeta } from '~/interfaces/page';
+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,
@@ -184,14 +185,17 @@ const GrowiContextualSubNavigation = (props) => {
   const [isPageTemplateModalShown, setIsPageTempleteModalShown] = useState(false);
   const [isPageTemplateModalShown, setIsPageTempleteModalShown] = useState(false);
 
 
   const {
   const {
-    isCompactMode, isLinkSharingDisabled,
+    isCompactMode, isLinkSharingDisabled, pageContainer,
   } = props;
   } = props;
 
 
   const isViewMode = editorMode === EditorMode.View;
   const isViewMode = editorMode === EditorMode.View;
 
 
+
   const tagsUpdatedHandlerForViewMode = useCallback(async(newTags: string[]) => {
   const tagsUpdatedHandlerForViewMode = useCallback(async(newTags: string[]) => {
     try {
     try {
-      await apiPost('/tags.update', { pageId, revisionId, tags: newTags }) as { tags };
+      const res: IResTagsUpdateApiv1 = await apiPost('/tags.update', { pageId, revisionId, tags: newTags });
+      const updatedRevisionId = getIdForRef(res.savedPage.revision);
+      await pageContainer.setState({ revisionId: updatedRevisionId });
 
 
       // revalidate SWRTagsInfo
       // revalidate SWRTagsInfo
       mutateSWRTagsInfo();
       mutateSWRTagsInfo();
@@ -203,7 +207,7 @@ const GrowiContextualSubNavigation = (props) => {
       toastError(err, 'fail to update tags');
       toastError(err, 'fail to update tags');
     }
     }
 
 
-  }, [pageId, revisionId, mutateSWRTagsInfo, mutatePageTagsForEditors]);
+  }, [pageId, revisionId, mutateSWRTagsInfo, mutatePageTagsForEditors, pageContainer]);
 
 
   const tagsUpdatedHandlerForEditMode = useCallback((newTags: string[]): void => {
   const tagsUpdatedHandlerForEditMode = useCallback((newTags: string[]): void => {
     // It will not be reflected in the DB until the page is refreshed
     // It will not be reflected in the DB until the page is refreshed
@@ -343,11 +347,12 @@ const GrowiContextualSubNavigation = (props) => {
 /**
 /**
  * Wrapper component for using unstated
  * Wrapper component for using unstated
  */
  */
-const GrowiContextualSubNavigationWrapper = withUnstatedContainers(GrowiContextualSubNavigation, [EditorContainer]);
+const GrowiContextualSubNavigationWrapper = withUnstatedContainers(GrowiContextualSubNavigation, [EditorContainer, PageContainer]);
 
 
 
 
 GrowiContextualSubNavigation.propTypes = {
 GrowiContextualSubNavigation.propTypes = {
   editorContainer: PropTypes.instanceOf(EditorContainer).isRequired,
   editorContainer: PropTypes.instanceOf(EditorContainer).isRequired,
+  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
 
 
   isCompactMode: PropTypes.bool,
   isCompactMode: PropTypes.bool,
   isLinkSharingDisabled: PropTypes.bool,
   isLinkSharingDisabled: PropTypes.bool,

+ 2 - 2
packages/app/src/components/SavePageControls/GrantSelector.tsx

@@ -9,7 +9,7 @@ import {
 } from 'reactstrap';
 } from 'reactstrap';
 
 
 
 
-import { isNotRef } from '~/interfaces/common';
+import { isPopulated } from '~/interfaces/common';
 import { IUserGroupHasId } from '~/interfaces/user';
 import { IUserGroupHasId } from '~/interfaces/user';
 import { useCurrentUser } from '~/stores/context';
 import { useCurrentUser } from '~/stores/context';
 import { useSWRxMyUserGroupRelations } from '~/stores/user-group';
 import { useSWRxMyUserGroupRelations } from '~/stores/user-group';
@@ -170,7 +170,7 @@ const GrantSelector = (props: Props): JSX.Element => {
     const userRelatedGroups: IUserGroupHasId[] = myUserGroupRelations
     const userRelatedGroups: IUserGroupHasId[] = myUserGroupRelations
       .map((relation) => {
       .map((relation) => {
         // relation.relatedGroup should be populated by server
         // relation.relatedGroup should be populated by server
-        return isNotRef(relation.relatedGroup) ? relation.relatedGroup : undefined;
+        return isPopulated(relation.relatedGroup) ? relation.relatedGroup : undefined;
       })
       })
       // exclude undefined elements
       // exclude undefined elements
       .filter((elem): elem is IUserGroupHasId => elem != null);
       .filter((elem): elem is IUserGroupHasId => elem != null);

+ 7 - 1
packages/app/src/interfaces/common.ts

@@ -10,6 +10,12 @@ export type Ref<T> = string | T & HasObjectId;
 
 
 export type Nullable<T> = T | null | undefined;
 export type Nullable<T> = T | null | undefined;
 
 
-export const isNotRef = <T>(ref: string | T & HasObjectId): ref is T & HasObjectId => {
+export const isPopulated = <T>(ref: Ref<T>): ref is T & HasObjectId => {
   return !(typeof ref === 'string');
   return !(typeof ref === 'string');
 };
 };
+
+export const getIdForRef = <T>(ref: Ref<T>): string => {
+  return isPopulated(ref)
+    ? ref._id
+    : ref;
+};

+ 10 - 2
packages/app/src/interfaces/tag.ts

@@ -1,3 +1,5 @@
+import { IPageHasId } from './page';
+
 export type ITag<ID = string> = {
 export type ITag<ID = string> = {
   _id: ID
   _id: ID
   name: string,
   name: string,
@@ -13,15 +15,21 @@ export type IPageTagsInfo = {
 export type IListTagNamesByPage = string[];
 export type IListTagNamesByPage = string[];
 
 
 
 
+export type IResTagsUpdateApiv1 = {
+  ok: boolean,
+  savedPage: IPageHasId,
+  tags: string[],
+}
+
 export type IResTagsSearchApiv1 = {
 export type IResTagsSearchApiv1 = {
   ok: boolean,
   ok: boolean,
-  tags: string[]
+  tags: string[],
 }
 }
 
 
 export type IResGetPageTags = {
 export type IResGetPageTags = {
   ok: boolean,
   ok: boolean,
   tags: string[],
   tags: string[],
-};
+}
 
 
 export type IResTagsListApiv1 = {
 export type IResTagsListApiv1 = {
   ok: boolean,
   ok: boolean,