yuken 4 лет назад
Родитель
Сommit
465263de2a

+ 63 - 1
packages/app/src/components/CustomNavigation/CustomNav.jsx

@@ -1,11 +1,20 @@
 import React, {
   useEffect, useState, useRef, useMemo, useCallback,
 } from 'react';
+
 import PropTypes from 'prop-types';
 import {
   Nav, NavItem, NavLink,
 } from 'reactstrap';
 
+import { toastSuccess } from '~/client/util/apiNotification';
+import { useCurrentPagePath } from '~/stores/context';
+import { usePageDeleteModal } from '~/stores/modal';
+import { useSWRxDescendantsPageListForCurrrentPath, useSWRxPageInfoForList } from '~/stores/page';
+import { usePageTreeTermManager } from '~/stores/page-listing';
+
+import { isTrashPage } from '^/../core/src/utils/page-path-utils';
+
 
 function getBreakpointOneLevelLarger(breakpoint) {
   switch (breakpoint) {
@@ -85,6 +94,10 @@ export const CustomNavTab = (props) => {
   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 { advance: advancePt } = usePageTreeTermManager();
 
   const {
     activeTab, navTabMapping, onNavSelected, hideBorderBottom, breakpointToHideInactiveTabsDown,
@@ -104,6 +117,40 @@ 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 };
+  };
+
+  // initial data
+  if (pagingResult != null) {
+    // convert without meta at first
+    console.log(pagingResult);
+    const dataWithMetas = pagingResult.items.map(page => convertToIDataWithMeta(page));
+    // inject data for listing
+    pageWithMetas = injectTo(dataWithMetas);
+  }
+
+  const deonDeleteHandler = (...args) => {
+    // alert(pagingResult.items.length);
+    toastSuccess(args[2] ? 'あいうえお' : 'かきくけこ');
+
+    advancePt();
+
+    if (mutate != null) {
+      mutate(...args);
+    }
+  };
+
+  const allDeleteButtonClickHandler = () => {
+
+    openDeleteModal(pageWithMetas, { onDeleted: mutate });
+  };
+
   function registerNavLink(key, elm) {
     if (elm != null) {
       navTabRefs[key] = elm;
@@ -147,9 +194,12 @@ export const CustomNavTab = (props) => {
     inactiveClassnames.push(`d-${breakpointOneLevelLarger}-block`);
   }
 
+  // trash page flag
+  const isTrash = isTrashPage(currentPath);
+
   return (
     <div className="grw-custom-nav-tab">
-      <div ref={navContainer}>
+      <div ref={navContainer} className="d-flex justify-content-between">
         <Nav className="nav-title">
           {Object.entries(navTabMapping).map(([key, value]) => {
 
@@ -169,6 +219,18 @@ 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={() => allDeleteButtonClickHandler()}
+            >
+              <i className="icon-fw icon-trash"></i>
+              <div>全て削除</div>
+            </button>
+          </div>
+        )}
       </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" /> }

+ 3 - 2
packages/app/src/components/DescendantsPageList.tsx

@@ -1,5 +1,7 @@
 import React, { useCallback, useState } from 'react';
+
 import { useTranslation } from 'react-i18next';
+
 import { toastSuccess } from '~/client/util/apiNotification';
 import {
   IDataWithMeta,
@@ -9,13 +11,12 @@ import {
 import { IPagingResult } from '~/interfaces/paging-result';
 import { OnDeletedFunction, OnPutBackedFunction } from '~/interfaces/ui';
 import { useIsGuestUser, useIsSharedUser, useIsTrashPage } from '~/stores/context';
-
 import {
   useSWRxDescendantsPageListForCurrrentPath, useSWRxPageInfoForList, useSWRxPageList, useDescendantsPageListForCurrentPathTermManager,
 } from '~/stores/page';
 import { usePageTreeTermManager } from '~/stores/page-listing';
-import { ForceHideMenuItems, MenuItemType } from './Common/Dropdown/PageItemControl';
 
+import { ForceHideMenuItems, MenuItemType } from './Common/Dropdown/PageItemControl';
 import PageList from './PageList/PageList';
 import PaginationWrapper from './PaginationWrapper';
 

+ 12 - 7
packages/app/src/components/PageDeleteModal.tsx

@@ -1,22 +1,25 @@
 import React, { useState, FC, useMemo } from 'react';
+
+import { useTranslation } from 'react-i18next';
 import {
   Modal, ModalHeader, ModalBody, ModalFooter,
 } from 'reactstrap';
-import { useTranslation } from 'react-i18next';
 
 import { apiPost } from '~/client/util/apiv1-client';
 import { apiv3Post } from '~/client/util/apiv3-client';
-import { usePageDeleteModal } from '~/stores/modal';
-import loggerFactory from '~/utils/logger';
-
+import { HasObjectId } from '~/interfaces/has-object-id';
 import {
   IDeleteSinglePageApiv1Result, IDeleteManyPageApiv3Result, IPageToDeleteWithMeta, IDataWithMeta, isIPageInfoForEntity, IPageInfoForEntity,
 } from '~/interfaces/page';
-import { HasObjectId } from '~/interfaces/has-object-id';
+import { useCurrentPagePath } from '~/stores/context';
+import { usePageDeleteModal } from '~/stores/modal';
+import { useSWRxPageInfoForList } from '~/stores/page';
+import loggerFactory from '~/utils/logger';
+
 
 import ApiErrorMessageList from './PageManagement/ApiErrorMessageList';
+
 import { isTrashPage } from '^/../core/src/utils/page-path-utils';
-import { useSWRxPageInfoForList } from '~/stores/page';
 
 
 const logger = loggerFactory('growi:cli:PageDeleteModal');
@@ -39,6 +42,7 @@ const PageDeleteModal: FC = () => {
   const { t } = useTranslation();
 
   const { data: deleteModalData, close: closeDeleteModal } = usePageDeleteModal();
+  const { data: currentPath } = useCurrentPagePath();
 
   const isOpened = deleteModalData?.isOpened ?? false;
 
@@ -119,7 +123,8 @@ const PageDeleteModal: FC = () => {
 
         const onDeleted = deleteModalData.opts?.onDeleted;
         if (onDeleted != null) {
-          onDeleted(data.paths, data.isRecursively, data.isCompletely);
+          console.log('q');
+          onDeleted(currentPath != null ? currentPath : '', isRecursively, isCompletely);
         }
 
         closeDeleteModal();