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

calculate conditions to delete

Yuki Takei 4 лет назад
Родитель
Сommit
f97095c143
1 измененных файлов с 39 добавлено и 12 удалено
  1. 39 12
      packages/app/src/components/PageDeleteModal.tsx

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

@@ -7,16 +7,21 @@ import { useTranslation } from 'react-i18next';
 import { apiPost } from '~/client/util/apiv1-client';
 import { apiPost } from '~/client/util/apiv1-client';
 import { apiv3Post } from '~/client/util/apiv3-client';
 import { apiv3Post } from '~/client/util/apiv3-client';
 import { usePageDeleteModal } from '~/stores/modal';
 import { usePageDeleteModal } from '~/stores/modal';
+import loggerFactory from '~/utils/logger';
 
 
 import {
 import {
   IDeleteSinglePageApiv1Result, IDeleteManyPageApiv3Result, isIPageInfoForOperation, IPageToDeleteWithMeta, IDataWithMeta, IPageInfoForOperation,
   IDeleteSinglePageApiv1Result, IDeleteManyPageApiv3Result, isIPageInfoForOperation, IPageToDeleteWithMeta, IDataWithMeta, IPageInfoForOperation,
 } from '~/interfaces/page';
 } from '~/interfaces/page';
+import { HasObjectId } from '~/interfaces/has-object-id';
 
 
 import ApiErrorMessageList from './PageManagement/ApiErrorMessageList';
 import ApiErrorMessageList from './PageManagement/ApiErrorMessageList';
 import { isTrashPage } from '^/../core/src/utils/page-path-utils';
 import { isTrashPage } from '^/../core/src/utils/page-path-utils';
 import { useSWRxPageInfoForList } from '~/stores/page';
 import { useSWRxPageInfoForList } from '~/stores/page';
 
 
 
 
+const logger = loggerFactory('growi:cli:PageDeleteModal');
+
+
 const deleteIconAndKey = {
 const deleteIconAndKey = {
   completely: {
   completely: {
     color: 'danger',
     color: 'danger',
@@ -43,16 +48,23 @@ const PageDeleteModal: FC = () => {
 
 
   const { injectTo } = useSWRxPageInfoForList(notOperatablePageIds);
   const { injectTo } = useSWRxPageInfoForList(notOperatablePageIds);
 
 
-  const isAbleToDeleteCompletely = useMemo(() => {
-    let injectedPages: IDataWithMeta<unknown, IPageInfoForOperation>[];
-    if (deleteModalData?.pages != null && notOperatablePageIds.length > 0) {
-      injectedPages = injectTo(deleteModalData?.pages);
+  // inject IPageInfo to operate
+  let injectedPages: IDataWithMeta<HasObjectId & { path: string }, IPageInfoForOperation>[] | null = null;
+  if (deleteModalData?.pages != null && notOperatablePageIds.length > 0) {
+    injectedPages = injectTo(deleteModalData?.pages);
+  }
 
 
-      return injectedPages.every(pageWithMeta => pageWithMeta.meta?.isAbleToDeleteCompletely);
+  // calculate conditions to delete
+  const [isDeletable, isAbleToDeleteCompletely] = useMemo(() => {
+    if (injectedPages != null && injectedPages.length > 0) {
+      const isDeletable = injectedPages.every(pageWithMeta => pageWithMeta.meta?.isDeletable);
+      const isAbleToDeleteCompletely = injectedPages.every(pageWithMeta => pageWithMeta.meta?.isAbleToDeleteCompletely);
+      return [isDeletable, isAbleToDeleteCompletely];
     }
     }
-    return true;
-  }, [deleteModalData?.pages, injectTo, notOperatablePageIds.length]);
+    return [true, true];
+  }, [injectedPages]);
 
 
+  // calculate condition to determine modal status
   const forceDeleteCompletelyMode = useMemo(() => {
   const forceDeleteCompletelyMode = useMemo(() => {
     if (deleteModalData != null && deleteModalData.pages != null && deleteModalData.pages.length > 0) {
     if (deleteModalData != null && deleteModalData.pages != null && deleteModalData.pages.length > 0) {
       return deleteModalData.pages.every(pageWithMeta => isTrashPage(pageWithMeta.data?.path ?? ''));
       return deleteModalData.pages.every(pageWithMeta => isTrashPage(pageWithMeta.data?.path ?? ''));
@@ -83,6 +95,11 @@ const PageDeleteModal: FC = () => {
       return;
       return;
     }
     }
 
 
+    if (!isDeletable) {
+      logger.error('At least one page is not deletable.');
+      return;
+    }
+
     /*
     /*
      * When multiple pages
      * When multiple pages
      */
      */
@@ -188,8 +205,13 @@ const PageDeleteModal: FC = () => {
   }
   }
 
 
   const renderPagePathsToDelete = () => {
   const renderPagePathsToDelete = () => {
-    if (deleteModalData != null && deleteModalData.pages != null) {
-      return deleteModalData.pages.map(page => <div key={page.data._id}><code>{ page.data.path }</code></div>);
+    if (injectedPages != null && injectedPages != null) {
+      return injectedPages.map(page => (
+        <div key={page.data._id}>
+          <code>{ page.data.path }</code>
+          { !page.meta?.isDeletable && <span className="ml-3 text-danger"><strong>(CAN NOT TO DELETE)</strong></span> }
+        </div>
+      ));
     }
     }
     return <></>;
     return <></>;
   };
   };
@@ -207,12 +229,17 @@ const PageDeleteModal: FC = () => {
           {/* https://redmine.weseek.co.jp/issues/82787 */}
           {/* https://redmine.weseek.co.jp/issues/82787 */}
           {renderPagePathsToDelete()}
           {renderPagePathsToDelete()}
         </div>
         </div>
-        {renderDeleteRecursivelyForm()}
-        { !forceDeleteCompletelyMode && renderDeleteCompletelyForm() }
+        { isDeletable && renderDeleteRecursivelyForm()}
+        { isDeletable && !forceDeleteCompletelyMode && renderDeleteCompletelyForm() }
       </ModalBody>
       </ModalBody>
       <ModalFooter>
       <ModalFooter>
         <ApiErrorMessageList errs={errs} />
         <ApiErrorMessageList errs={errs} />
-        <button type="button" className={`btn btn-${deleteIconAndKey[deleteMode].color}`} onClick={deleteButtonHandler}>
+        <button
+          type="button"
+          className={`btn btn-${deleteIconAndKey[deleteMode].color}`}
+          disabled={!isDeletable}
+          onClick={deleteButtonHandler}
+        >
           <i className={`icon-${deleteIconAndKey[deleteMode].icon}`} aria-hidden="true"></i>
           <i className={`icon-${deleteIconAndKey[deleteMode].icon}`} aria-hidden="true"></i>
           { t(`modal_delete.delete_${deleteIconAndKey[deleteMode].translationKey}`) }
           { t(`modal_delete.delete_${deleteIconAndKey[deleteMode].translationKey}`) }
         </button>
         </button>