yuken před 4 roky
rodič
revize
16b3cb19a4

+ 3 - 48
packages/app/src/components/CustomNavigation/CustomNav.jsx

@@ -3,17 +3,11 @@ import React, {
 } from 'react';
 
 import PropTypes from 'prop-types';
-import { useTranslation } from 'react-i18next';
 import {
   Nav, NavItem, NavLink,
 } from 'reactstrap';
 
 
-import { useCurrentPagePath } from '~/stores/context';
-import { usePageDeleteModal } from '~/stores/modal';
-import { useSWRxDescendantsPageListForCurrrentPath, useSWRxPageInfoForList } from '~/stores/page';
-
-
 function getBreakpointOneLevelLarger(breakpoint) {
   switch (breakpoint) {
     case 'sm':
@@ -89,16 +83,12 @@ CustomNavDropdown.propTypes = {
 
 
 export const CustomNavTab = (props) => {
-  const { t } = useTranslation();
   const navContainer = useRef();
   const [sliderWidth, setSliderWidth] = useState(0);
   const [sliderMarginLeft, setSliderMarginLeft] = useState(0);
-  const { open: openDeleteModal } = usePageDeleteModal();
-  const { data: currentPath } = useCurrentPagePath();
-  const { data: pagingResult, mutate } = useSWRxDescendantsPageListForCurrrentPath();
 
   const {
-    activeTab, navTabMapping, onNavSelected, hideBorderBottom, breakpointToHideInactiveTabsDown,
+    activeTab, navTabMapping, onNavSelected, hideBorderBottom, breakpointToHideInactiveTabsDown, emptyTrashButton,
   } = props;
 
   const navTabRefs = useMemo(() => {
@@ -115,28 +105,6 @@ export const CustomNavTab = (props) => {
     }
   }, [onNavSelected]);
 
-  const pageIds = pagingResult?.items?.map(page => page._id);
-  const { injectTo } = useSWRxPageInfoForList(pageIds, true, true);
-
-  let pageWithMetas = [];
-
-  const convertToIDataWithMeta = (page) => {
-    return { data: page };
-  };
-
-  if (pagingResult != null) {
-    const dataWithMetas = pagingResult.items.map(page => convertToIDataWithMeta(page));
-    pageWithMetas = injectTo(dataWithMetas);
-  }
-
-  const onDeletedHandler = (...args) => {
-    // process after multipe pages delete api
-  };
-
-  const emptyTrashClickHandler = () => {
-    openDeleteModal(pageWithMetas, { onDeleted: onDeletedHandler, emptyTrash: true });
-  };
-
   function registerNavLink(key, elm) {
     if (elm != null) {
       navTabRefs[key] = elm;
@@ -180,9 +148,6 @@ export const CustomNavTab = (props) => {
     inactiveClassnames.push(`d-${breakpointOneLevelLarger}-block`);
   }
 
-  // trash page flag
-  const isTrash = currentPath === '/trash';
-
   return (
     <div className="grw-custom-nav-tab">
       <div ref={navContainer} className="d-flex justify-content-between">
@@ -205,18 +170,7 @@ export const CustomNavTab = (props) => {
             );
           })}
         </Nav>
-        { isTrash && (
-          <div className="d-flex align-items-center">
-            <button
-              type="button"
-              className="btn btn-outline-secondary rounded-pill text-danger d-flex align-items-center"
-              onClick={() => emptyTrashClickHandler()}
-            >
-              <i className="icon-fw icon-trash"></i>
-              <div>{t('modal_delete.empty_trash')}</div>
-            </button>
-          </div>
-        )}
+        {emptyTrashButton && emptyTrashButton}
       </div>
       <hr className="my-0 grw-nav-slide-hr border-none" style={{ width: `${sliderWidth}%`, marginLeft: `${sliderMarginLeft}%` }} />
       { !hideBorderBottom && <hr className="my-0 border-top-0 border-bottom" /> }
@@ -231,6 +185,7 @@ CustomNavTab.propTypes = {
   onNavSelected: PropTypes.func,
   hideBorderBottom: PropTypes.bool,
   breakpointToHideInactiveTabsDown: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
+  emptyTrashButton: PropTypes.element,
 };
 
 CustomNavTab.defaultProps = {

+ 4 - 1
packages/app/src/components/CustomNavigation/CustomNavAndContents.jsx

@@ -1,4 +1,5 @@
 import React, { useState } from 'react';
+
 import PropTypes from 'prop-types';
 
 import CustomNav, { CustomNavTab, CustomNavDropdown } from './CustomNav';
@@ -7,7 +8,7 @@ import CustomTabContent from './CustomTabContent';
 
 const CustomNavAndContents = (props) => {
   const {
-    navTabMapping, defaultTabIndex, navigationMode, tabContentClasses, breakpointToHideInactiveTabsDown,
+    navTabMapping, defaultTabIndex, navigationMode, tabContentClasses, breakpointToHideInactiveTabsDown, emptyTrashButton,
   } = props;
   const [activeTab, setActiveTab] = useState(Object.keys(props.navTabMapping)[defaultTabIndex || 0]);
 
@@ -31,6 +32,7 @@ const CustomNavAndContents = (props) => {
         navTabMapping={navTabMapping}
         onNavSelected={setActiveTab}
         breakpointToHideInactiveTabsDown={breakpointToHideInactiveTabsDown}
+        emptyTrashButton={emptyTrashButton}
       />
       <CustomTabContent activeTab={activeTab} navTabMapping={navTabMapping} additionalClassNames={tabContentClasses} />
     </>
@@ -43,6 +45,7 @@ CustomNavAndContents.propTypes = {
   navigationMode: PropTypes.oneOf(['both', 'tab', 'dropdown']),
   tabContentClasses: PropTypes.arrayOf(PropTypes.string),
   breakpointToHideInactiveTabsDown: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
+  emptyTrashButton: PropTypes.element,
 };
 CustomNavAndContents.defaultProps = {
   navigationMode: 'tab',

+ 9 - 1
packages/app/src/components/PageDeleteModal.tsx

@@ -240,9 +240,17 @@ const PageDeleteModal: FC = () => {
         <div className="form-group grw-scrollable-modal-body pb-1">
           <label>{ t('modal_delete.deleting_page') }:</label><br />
           {/* Todo: change the way to show path on modal when too many pages are selected */}
-          {/* https://redmine.weseek.co.jp/issues/82787 */}
           {renderPagePathsToDelete()}
         </div>
+        {(() => {
+          if (emptyTrash) {
+            renderCompletelyDeleteAlert();
+          }
+          else {
+            if (isDeletable) renderDeleteRecursivelyForm();
+            if (isDeletable && !forceDeleteCompletelyMode) renderDeleteCompletelyForm();
+          }
+        })()}
         { isDeletable && !emptyTrash && renderDeleteRecursivelyForm()}
         { isDeletable && !forceDeleteCompletelyMode && !emptyTrash && renderDeleteCompletelyForm() }
         { emptyTrash && renderCompletelyDeleteAlert() }

+ 50 - 3
packages/app/src/components/TrashPageList.jsx

@@ -1,9 +1,56 @@
 import React, { useMemo } from 'react';
+
 import PropTypes from 'prop-types';
-import { withTranslation } from 'react-i18next';
-import PageListIcon from './Icons/PageListIcon';
+import { withTranslation, useTranslation } from 'react-i18next';
+
+import { usePageDeleteModal } from '~/stores/modal';
+import { useSWRxDescendantsPageListForCurrrentPath, useSWRxPageInfoForList } from '~/stores/page';
+
 import CustomNavAndContents from './CustomNavigation/CustomNavAndContents';
 import { DescendantsPageListForCurrentPath } from './DescendantsPageList';
+import PageListIcon from './Icons/PageListIcon';
+
+
+const EmptyTrashButton = () => {
+  const { t } = useTranslation();
+  const { open: openDeleteModal } = usePageDeleteModal();
+  const { data: pagingResult } = useSWRxDescendantsPageListForCurrrentPath();
+
+  const pageIds = pagingResult?.items?.map(page => page._id);
+  const { injectTo } = useSWRxPageInfoForList(pageIds, true, true);
+
+  let pageWithMetas = [];
+
+  const convertToIDataWithMeta = (page) => {
+    return { data: page };
+  };
+
+  if (pagingResult != null) {
+    const dataWithMetas = pagingResult.items.map(page => convertToIDataWithMeta(page));
+    pageWithMetas = injectTo(dataWithMetas);
+  }
+
+  const onDeletedHandler = (...args) => {
+    // process after multipe pages delete api
+  };
+
+  const emptyTrashClickHandler = () => {
+    openDeleteModal(pageWithMetas, { onDeleted: onDeletedHandler, emptyTrash: true });
+  };
+
+  return (
+    <div className="d-flex align-items-center">
+      <button
+        type="button"
+        className="btn btn-outline-secondary rounded-pill text-danger d-flex align-items-center"
+        onClick={() => emptyTrashClickHandler()}
+      >
+        <i className="icon-fw icon-trash"></i>
+        <div>{t('modal_delete.empty_trash')}</div>
+      </button>
+    </div>
+  );
+};
 
 
 const TrashPageList = (props) => {
@@ -22,7 +69,7 @@ const TrashPageList = (props) => {
 
   return (
     <div data-testid="trash-page-list" className="mt-5 d-edit-none">
-      <CustomNavAndContents navTabMapping={navTabMapping} />
+      <CustomNavAndContents navTabMapping={navTabMapping} emptyTrashButton={EmptyTrashButton()} />
     </div>
   );
 };