Jelajahi Sumber

80623 TagLabel refactor

Mao 4 tahun lalu
induk
melakukan
a1d87c9819

+ 30 - 4
packages/app/src/components/Navbar/GrowiSubNavigation.jsx

@@ -5,6 +5,7 @@ import { withUnstatedContainers } from '../UnstatedUtils';
 import AppContainer from '~/client/services/AppContainer';
 import NavigationContainer from '~/client/services/NavigationContainer';
 import PageContainer from '~/client/services/PageContainer';
+import EditorContainer from '~/client/services/EditorContainer';
 
 import TagLabels from '../Page/TagLabels';
 import SubnavButtons from './SubNavButtons';
@@ -15,13 +16,16 @@ import DrawerToggler from './DrawerToggler';
 
 import PagePathNav from '../PagePathNav';
 
+import { toastSuccess, toastError } from '~/client/util/apiNotification';
+import { apiPost } from '~/client/util/apiv1-client';
+
 const GrowiSubNavigation = (props) => {
   const {
-    appContainer, navigationContainer, pageContainer, isCompactMode,
+    appContainer, navigationContainer, pageContainer, editorContainer, isCompactMode,
   } = props;
   const { isDrawerMode, editorMode, isDeviceSmallerThanMd } = navigationContainer.state;
   const {
-    pageId, path, createdAt, creator, updatedAt, revisionAuthor, isPageExist,
+    pageId, path, createdAt, creator, updatedAt, revisionAuthor, isPageExist, tags,
   } = pageContainer.state;
 
   const { isGuestUser } = appContainer;
@@ -33,6 +37,27 @@ const GrowiSubNavigation = (props) => {
     navigationContainer.setEditorMode(viewType);
   }
 
+  const tagsUpdatedHandler = async(newTags) => {
+    // It will not be reflected in the DB until the page is refreshed
+    if (editorMode === 'edit') {
+      return editorContainer.setState({ tags: newTags });
+    }
+
+    try {
+      const { tags } = await apiPost('/tags.update', { pageId, tags: newTags });
+
+      // update pageContainer.state
+      pageContainer.setState({ tags });
+      // update editorContainer.state
+      editorContainer.setState({ tags });
+
+      toastSuccess('updated tags successfully');
+    }
+    catch (err) {
+      toastError(err, 'fail to update tags');
+    }
+  };
+
   return (
     <div className={`grw-subnav container-fluid d-flex align-items-center justify-content-between ${isCompactMode ? 'grw-subnav-compact d-print-none' : ''}`}>
 
@@ -47,7 +72,7 @@ const GrowiSubNavigation = (props) => {
         <div className="grw-path-nav-container">
           { pageContainer.isAbleToShowTagLabel && !isCompactMode && !isTagLabelHidden && (
             <div className="grw-taglabels-container">
-              <TagLabels editorMode={editorMode} />
+              <TagLabels tags={tags} tagsUpdateInvoked={tagsUpdatedHandler} />
             </div>
           ) }
           <PagePathNav pageId={pageId} pagePath={path} isSingleLineMode={isEditorMode} isCompactMode={isCompactMode} />
@@ -92,13 +117,14 @@ const GrowiSubNavigation = (props) => {
 /**
  * Wrapper component for using unstated
  */
-const GrowiSubNavigationWrapper = withUnstatedContainers(GrowiSubNavigation, [AppContainer, NavigationContainer, PageContainer]);
+const GrowiSubNavigationWrapper = withUnstatedContainers(GrowiSubNavigation, [AppContainer, NavigationContainer, PageContainer, EditorContainer]);
 
 
 GrowiSubNavigation.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   navigationContainer: PropTypes.instanceOf(NavigationContainer).isRequired,
   pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+  editorContainer: PropTypes.instanceOf(EditorContainer).isRequired,
 
   isCompactMode: PropTypes.bool,
 };

+ 5 - 48
packages/app/src/components/Page/TagLabels.jsx

@@ -2,12 +2,9 @@ import React, { Suspense } from 'react';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 
-import { toastSuccess, toastError } from '~/client/util/apiNotification';
 
 import { withUnstatedContainers } from '../UnstatedUtils';
 import AppContainer from '~/client/services/AppContainer';
-import PageContainer from '~/client/services/PageContainer';
-import EditorContainer from '~/client/services/EditorContainer';
 
 import RenderTagLabels from './RenderTagLabels';
 import TagEditModal from './TagEditModal';
@@ -23,18 +20,8 @@ class TagLabels extends React.Component {
 
     this.openEditorModal = this.openEditorModal.bind(this);
     this.closeEditorModal = this.closeEditorModal.bind(this);
-    this.tagsUpdatedHandler = this.tagsUpdatedHandler.bind(this);
   }
 
-  /**
-   * @return tags data
-   *   1. pageContainer.state.tags if editorMode is view
-   *   2. editorContainer.state.tags if editorMode is edit
-   */
-  getTagData() {
-    const { editorContainer, pageContainer, editorMode } = this.props;
-    return (editorMode === 'edit') ? editorContainer.state.tags : pageContainer.state.tags;
-  }
 
   openEditorModal() {
     this.setState({ isTagEditModalShown: true });
@@ -44,37 +31,9 @@ class TagLabels extends React.Component {
     this.setState({ isTagEditModalShown: false });
   }
 
-  async tagsUpdatedHandler(newTags) {
-    const {
-      appContainer, editorContainer, pageContainer, editorMode,
-    } = this.props;
-
-    const { pageId } = pageContainer.state;
-
-    // It will not be reflected in the DB until the page is refreshed
-    if (editorMode === 'edit') {
-      return editorContainer.setState({ tags: newTags });
-    }
-
-    try {
-      const { tags } = await appContainer.apiPost('/tags.update', { pageId, tags: newTags });
-
-      // update pageContainer.state
-      pageContainer.setState({ tags });
-      // update editorContainer.state
-      editorContainer.setState({ tags });
-
-      toastSuccess('updated tags successfully');
-    }
-    catch (err) {
-      toastError(err, 'fail to update tags');
-    }
-  }
-
 
   render() {
-    const tags = this.getTagData();
-    const { appContainer } = this.props;
+    const { appContainer, tagsUpdateInvoked, tags } = this.props;
 
     return (
       <>
@@ -95,7 +54,7 @@ class TagLabels extends React.Component {
           isOpen={this.state.isTagEditModalShown}
           onClose={this.closeEditorModal}
           appContainer={this.props.appContainer}
-          onTagsUpdated={this.tagsUpdatedHandler}
+          onTagsUpdated={tagsUpdateInvoked}
         />
 
       </>
@@ -107,16 +66,14 @@ class TagLabels extends React.Component {
 /**
  * Wrapper component for using unstated
  */
-const TagLabelsWrapper = withUnstatedContainers(TagLabels, [AppContainer, PageContainer, EditorContainer]);
+const TagLabelsWrapper = withUnstatedContainers(TagLabels, [AppContainer]);
 
 TagLabels.propTypes = {
   t: PropTypes.func.isRequired, // i18next
 
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
-  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
-  editorContainer: PropTypes.instanceOf(EditorContainer).isRequired,
-
-  editorMode: PropTypes.string.isRequired,
+  tags: PropTypes.arrayOf(PropTypes.object).isRequired,
+  tagsUpdateInvoked: PropTypes.func,
 };
 
 export default withTranslation()(TagLabelsWrapper);

+ 31 - 9
packages/app/src/components/SearchPage/SearchResultContentSubNavigation.tsx

@@ -1,7 +1,10 @@
-import React, { FC } from 'react';
+import React, { FC, useEffect, useState } from 'react';
 import PagePathNav from '../PagePathNav';
 import { withUnstatedContainers } from '../UnstatedUtils';
 import AppContainer from '../../client/services/AppContainer';
+import TagLabels from '../Page/TagLabels';
+import { toastSuccess, toastError } from '../../client/util/apiNotification';
+import { apiPost } from '../../client/util/apiv1-client';
 
 type Props = {
   appContainer:AppContainer
@@ -11,26 +14,45 @@ type Props = {
   isCompactMode?: boolean,
 }
 
+const TagLableWrapper = (props) => {
+  return <TagLabels {...props}></TagLabels>;
+};
+
 const SearchResultContentSubNavigation: FC<Props> = (props : Props) => {
   const {
     appContainer, pageId, path, isCompactMode, isSignleLineMode,
   } = props;
+  const [tags, setTags] = useState([]);
+
+  useEffect(() => {
+    const f = async() => {
+      const res : any = await appContainer.apiGet('/pages.getPageTag', { pageId });
+      setTags(res.tags);
+    };
+    f();
+  }, []);
+
+  const tagsUpdatedHandler = async(newTags) => {
+    try {
+      const res : any = await apiPost('/tags.update', { pageId, tags: newTags });
+      setTags(res.tags);
+      toastSuccess('updated tags successfully');
+    }
+    catch (err) {
+      toastError(err, 'fail to update tags');
+    }
+  };
 
   const { isSharedUser } = appContainer;
   return (
     <div className={`grw-subnav container-fluid d-flex align-items-center justify-content-between ${isCompactMode ? 'grw-subnav-compact d-print-none' : ''}`}>
       {/* Left side */}
       <div className="grw-path-nav-container">
-        {/* TODO : refactor TagLabels in a way that it can be used independently from pageContainenr
-              TASK: #80623 https://estoc.weseek.co.jp/redmine/issues/80623
-              CONDITION reference : https://dev.growi.org/5fabddf8bbeb1a0048bcb9e9
-              userPage is not included in search so chekcing only isSharedUser or not.
-          */}
-        {/* { !isSharedUser &&  !isCompactMode &&  (
+        {!isSharedUser && !isCompactMode && (
           <div className="grw-taglabels-container">
-            <TagLabels editorMode={editorMode} />
+            <TagLableWrapper tags={tags} tagsUpdateInvoked={tagsUpdatedHandler} />
           </div>
-        )} */}
+        )}
         <PagePathNav pageId={pageId} pagePath={path} isCompactMode={isCompactMode} isSingleLineMode={isSignleLineMode} />
       </div>
       {/* Right side */}