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

Merge pull request #5261 from weseek/feat/86349-delete-operation-from-the-delete-modal

Shun Miyazawa 4 лет назад
Родитель
Сommit
0e8fd98bee

+ 33 - 30
packages/app/src/components/PageDeleteModal.tsx

@@ -1,12 +1,13 @@
 import React, { useState, FC } from 'react';
-import toastr from 'toastr';
 import {
   Modal, ModalHeader, ModalBody, ModalFooter,
 } from 'reactstrap';
 import { useTranslation } from 'react-i18next';
 
-// import { apiPost } from '~/client/util/apiv1-client';
-import { usePageDeleteModalStatus, usePageDeleteModalOpened } from '~/stores/ui';
+import { apiPost } from '~/client/util/apiv1-client';
+import { usePageDeleteModal, usePageDeleteModalOpened } from '~/stores/ui';
+
+import { IPageApiv1Result } from '~/interfaces/page';
 
 import ApiErrorMessageList from './PageManagement/ApiErrorMessageList';
 
@@ -25,7 +26,6 @@ const deleteIconAndKey = {
 };
 
 type Props = {
-  isOpen: boolean,
   isDeleteCompletelyModal: boolean,
   isAbleToDeleteCompletely: boolean,
   onClose?: () => void,
@@ -37,9 +37,10 @@ const PageDeleteModal: FC<Props> = (props: Props) => {
     isDeleteCompletelyModal, isAbleToDeleteCompletely,
   } = props;
 
+  const { data: pagesDataToDelete, close: closeDeleteModal } = usePageDeleteModal();
+  const { data: pageDeleteModalOpened } = usePageDeleteModalOpened();
 
-  const { data: pagesDataToDelete, close: closeDeleteModal } = usePageDeleteModalStatus();
-  const { data: isOpened } = usePageDeleteModalOpened();
+  const isOpened = pageDeleteModalOpened?.isOpend != null ? pageDeleteModalOpened.isOpend : false;
 
   const [isDeleteRecursively, setIsDeleteRecursively] = useState(true);
   const [isDeleteCompletely, setIsDeleteCompletely] = useState(isDeleteCompletelyModal && isAbleToDeleteCompletely);
@@ -60,29 +61,32 @@ const PageDeleteModal: FC<Props> = (props: Props) => {
   }
 
   async function deletePage() {
-    toastr.warning(t('search_result.currently_not_implemented'));
+    // toastr.warning(t('search_result.currently_not_implemented'));
     // Todo implement page delete function at https://redmine.weseek.co.jp/issues/82222
     // setErrs(null);
 
-    // try {
-    //   // control flag
-    //   // If is it not true, Request value must be `null`.
-    //   const recursively = isDeleteRecursively ? true : null;
-    //   const completely = isDeleteCompletely ? true : null;
-
-    //   const response = await apiPost('/pages.remove', {
-    //     page_id: pageId,
-    //     revision_id: revisionId,
-    //     recursively,
-    //     completely,
-    //   });
-
-    //   const trashPagePath = response.page.path;
-    //   window.location.href = encodeURI(trashPagePath);
-    // }
-    // catch (err) {
-    //   setErrs(err);
-    // }
+    if (pagesDataToDelete?.pages != null && (pagesDataToDelete.pages.length > 0)) {
+      try {
+        const recursively = isDeleteRecursively === true ? true : undefined;
+        const completely = isDeleteCompletely === true ? true : undefined;
+
+        // TODO: Create an endpoint (pages.removeMany)
+        const result = await apiPost('/pages.removeMany', {
+          pages: pagesDataToDelete.pages,
+          recursively,
+          completely,
+        }) as IPageApiv1Result;
+
+        const redirectPagePath = result.page.path;
+
+        if (pageDeleteModalOpened?.onDeleted) {
+          pageDeleteModalOpened.onDeleted(redirectPagePath);
+        }
+      }
+      catch (err) {
+        setErrs(err);
+      }
+    }
   }
 
   async function deleteButtonHandler() {
@@ -96,10 +100,9 @@ const PageDeleteModal: FC<Props> = (props: Props) => {
           className="custom-control-input"
           id="deleteRecursively"
           type="checkbox"
-          // checked={isDeleteRecursively}
-          checked={false}
+          checked={isDeleteRecursively}
           onChange={changeIsDeleteRecursivelyHandler}
-          disabled // Todo: enable this at https://redmine.weseek.co.jp/issues/82222
+          // disabled // Todo: enable this at https://redmine.weseek.co.jp/issues/82222
         />
         <label className="custom-control-label" htmlFor="deleteRecursively">
           { t('modal_delete.delete_recursively') }
@@ -123,7 +126,7 @@ const PageDeleteModal: FC<Props> = (props: Props) => {
           id="deleteCompletely"
           type="checkbox"
           // disabled={!isAbleToDeleteCompletely}
-          disabled // Todo: will be implemented at https://redmine.weseek.co.jp/issues/82222
+          // disabled // Todo: will be implemented at https://redmine.weseek.co.jp/issues/82222
           checked={isDeleteCompletely}
           onChange={changeIsDeleteCompletelyHandler}
         />

+ 6 - 6
packages/app/src/components/Sidebar/PageTree/Item.tsx

@@ -29,7 +29,7 @@ interface ItemProps {
   isOpen?: boolean
   onClickDuplicateMenuItem?(pageId: string, path: string): void
   onClickRenameMenuItem?(pageId: string, revisionId: string, path: string): void
-  onClickDeleteByPage?(pageToDelete: IPageForPageDeleteModal | null): void
+  onClickDeleteMenuItem?(pageToDelete: IPageForPageDeleteModal | null): void
 }
 
 // Utility to mark target
@@ -70,7 +70,7 @@ const ItemCount: FC<ItemCountProps> = (props:ItemCountProps) => {
 const Item: FC<ItemProps> = (props: ItemProps) => {
   const { t } = useTranslation();
   const {
-    itemNode, targetPathOrId, isOpen: _isOpen = false, onClickDuplicateMenuItem, onClickRenameMenuItem, onClickDeleteByPage, isEnableActions,
+    itemNode, targetPathOrId, isOpen: _isOpen = false, onClickDuplicateMenuItem, onClickRenameMenuItem, onClickDeleteMenuItem, isEnableActions,
   } = props;
 
   const { page, children } = itemNode;
@@ -184,7 +184,7 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
   }, [onClickRenameMenuItem, page]);
 
   const onClickDeleteButton = useCallback(async(_pageId: string): Promise<void> => {
-    if (onClickDeleteByPage == null) {
+    if (onClickDeleteMenuItem == null) {
       return;
     }
 
@@ -200,8 +200,8 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
       path,
     };
 
-    onClickDeleteByPage(pageToDelete);
-  }, [page, onClickDeleteByPage]);
+    onClickDeleteMenuItem(pageToDelete);
+  }, [page, onClickDeleteMenuItem]);
 
   const onPressEnterForCreateHandler = (inputText: string) => {
     setNewPageInputShown(false);
@@ -338,7 +338,7 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
               targetPathOrId={targetPathOrId}
               onClickDuplicateMenuItem={onClickDuplicateMenuItem}
               onClickRenameMenuItem={onClickRenameMenuItem}
-              onClickDeleteByPage={onClickDeleteByPage}
+              onClickDeleteMenuItem={onClickDeleteMenuItem}
             />
           </div>
         ))

+ 12 - 8
packages/app/src/components/Sidebar/PageTree/ItemsTree.tsx

@@ -7,7 +7,7 @@ import { useSWRxPageAncestorsChildren, useSWRxRootPage } from '../../../stores/p
 import { TargetAndAncestors } from '~/interfaces/page-listing-results';
 import { toastError } from '~/client/util/apiNotification';
 import {
-  IPageForPageDeleteModal, usePageDuplicateModalStatus, usePageRenameModalStatus, usePageDeleteModalStatus,
+  IPageForPageDeleteModal, usePageDuplicateModalStatus, usePageRenameModalStatus, usePageDeleteModal,
 } from '~/stores/ui';
 import { smoothScrollIntoView } from '~/client/util/smooth-scroll';
 
@@ -63,7 +63,7 @@ const renderByInitialNode = (
     targetPathOrId?: string,
     onClickDuplicateMenuItem?: (pageId: string, path: string) => void,
     onClickRenameMenuItem?: (pageId: string, revisionId: string, path: string) => void,
-    onClickDeleteByPage?: (pageToDelete: IPageForPageDeleteModal | null) => void,
+    onClickDeleteMenuItem?: (pageToDelete: IPageForPageDeleteModal | null) => void,
 ): JSX.Element => {
 
   return (
@@ -76,7 +76,7 @@ const renderByInitialNode = (
         isEnableActions={isEnableActions}
         onClickDuplicateMenuItem={onClickDuplicateMenuItem}
         onClickRenameMenuItem={onClickRenameMenuItem}
-        onClickDeleteByPage={onClickDeleteByPage}
+        onClickDeleteMenuItem={onClickDeleteMenuItem}
       />
     </ul>
   );
@@ -95,7 +95,7 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
   const { data: rootPageData, error: error2 } = useSWRxRootPage();
   const { open: openDuplicateModal } = usePageDuplicateModalStatus();
   const { open: openRenameModal } = usePageRenameModalStatus();
-  const { open: openDeleteModal } = usePageDeleteModalStatus();
+  const { open: openDeleteModal } = usePageDeleteModal();
 
   useEffect(() => {
     const startFrom = document.getElementById('grw-sidebar-contents-scroll-target');
@@ -114,8 +114,12 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
     openRenameModal(pageId, revisionId, path);
   };
 
-  const onClickDeleteByPage = (pageToDelete: IPageForPageDeleteModal) => {
-    openDeleteModal([pageToDelete]);
+  const onDeletedHandler = (pagePath) => {
+    window.location.href = encodeURI(pagePath);
+  };
+
+  const onClickDeleteMenuItem = (pageToDelete: IPageForPageDeleteModal) => {
+    openDeleteModal([pageToDelete], onDeletedHandler);
   };
 
   if (error1 != null || error2 != null) {
@@ -129,7 +133,7 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
    */
   if (ancestorsChildrenData != null && rootPageData != null) {
     const initialNode = generateInitialNodeAfterResponse(ancestorsChildrenData.ancestorsChildren, new ItemNode(rootPageData.rootPage));
-    return renderByInitialNode(initialNode, isEnableActions, targetPathOrId, onClickDuplicateMenuItem, onClickRenameMenuItem, onClickDeleteByPage);
+    return renderByInitialNode(initialNode, isEnableActions, targetPathOrId, onClickDuplicateMenuItem, onClickRenameMenuItem, onClickDeleteMenuItem);
   }
 
   /*
@@ -137,7 +141,7 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
    */
   if (targetAndAncestorsData != null) {
     const initialNode = generateInitialNodeBeforeResponse(targetAndAncestorsData.targetAndAncestors);
-    return renderByInitialNode(initialNode, isEnableActions, targetPathOrId, onClickDuplicateMenuItem, onClickRenameMenuItem, onClickDeleteByPage);
+    return renderByInitialNode(initialNode, isEnableActions, targetPathOrId, onClickDuplicateMenuItem, onClickRenameMenuItem, onClickDeleteMenuItem);
   }
 
   return null;

+ 5 - 0
packages/app/src/interfaces/page.ts

@@ -97,3 +97,8 @@ export type IPageWithMeta<M = IPageInfoAll> = {
   pageData: IPageHasId,
   pageMeta?: M,
 };
+
+export type IPageApiv1Result = {
+  ok: boolean
+  page: IPageHasId,
+};

+ 12 - 6
packages/app/src/stores/ui.tsx

@@ -306,30 +306,36 @@ export type IPageForPageDeleteModal = {
 type DeleteModalStatus = {
   isOpened: boolean,
   pages?: IPageForPageDeleteModal[],
+  onDeleted?: (pagePath: string) => void,
+}
+
+type DeleteModalOpened = {
+  isOpend: boolean,
+  onDeleted?: (pagePath: string) => void,
 }
 
 type DeleteModalStatusUtils = {
-  open(pages?: IPageForPageDeleteModal[]): Promise<DeleteModalStatus | undefined>
+  open(pages?: IPageForPageDeleteModal[], onDeleted?: (pagePath: string) => void): Promise<DeleteModalStatus | undefined>
   close(): Promise<DeleteModalStatus | undefined>
 }
 
-export const usePageDeleteModalStatus = (status?: DeleteModalStatus): SWRResponse<DeleteModalStatus, Error> & DeleteModalStatusUtils => {
+export const usePageDeleteModal = (status?: DeleteModalStatus): SWRResponse<DeleteModalStatus, Error> & DeleteModalStatusUtils => {
   const initialData: DeleteModalStatus = { isOpened: false };
   const swrResponse = useStaticSWR<DeleteModalStatus, Error>('deleteModalStatus', status, { fallbackData: initialData });
 
   return {
     ...swrResponse,
-    open: (pages?: IPageForPageDeleteModal[]) => swrResponse.mutate({ isOpened: true, pages }),
+    open: (pages?: IPageForPageDeleteModal[], onDeleted?:(pagePath: string) => void) => swrResponse.mutate({ isOpened: true, pages, onDeleted }),
     close: () => swrResponse.mutate({ isOpened: false }),
   };
 };
 
-export const usePageDeleteModalOpened = (): SWRResponse<boolean, Error> => {
-  const { data } = usePageDeleteModalStatus();
+export const usePageDeleteModalOpened = (): SWRResponse<(DeleteModalOpened | null), Error> => {
+  const { data } = usePageDeleteModal();
   return useSWRImmutable(
     data != null ? ['isDeleteModalOpened', data] : null,
     () => {
-      return data != null ? data.isOpened : false;
+      return data != null ? { isOpend: data.isOpened, onDeleted: data?.onDeleted } : null;
     },
   );
 };