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

Merge pull request #5241 from weseek/imprv/87210-page-duplicate-modal-swr

open pageDuplicateModal with swr
cao 4 лет назад
Родитель
Сommit
14d55a4c99

+ 2 - 0
packages/app/src/client/base.jsx

@@ -8,6 +8,7 @@ import GrowiNavbarBottom from '../components/Navbar/GrowiNavbarBottom';
 import HotkeysManager from '../components/Hotkeys/HotkeysManager';
 import PageCreateModal from '../components/PageCreateModal';
 import PageDeleteModal from '../components/PageDeleteModal';
+import PageDuplicateModal from '../components/PageDuplicateModal';
 
 import AppContainer from '~/client/services/AppContainer';
 import SocketIoContainer from '~/client/services/SocketIoContainer';
@@ -42,6 +43,7 @@ const componentMappings = {
 
   'page-create-modal': <PageCreateModal />,
   'page-delete-modal': <PageDeleteModal />,
+  'page-duplicate-modal': <PageDuplicateModal />,
 
   'grw-hotkeys-manager': <HotkeysManager />,
 

+ 15 - 15
packages/app/src/components/PageDuplicateModal.jsx

@@ -9,6 +9,7 @@ import { withTranslation } from 'react-i18next';
 import { debounce } from 'throttle-debounce';
 import { withUnstatedContainers } from './UnstatedUtils';
 import { toastError } from '~/client/util/apiNotification';
+import { usePageDuplicateModalStatus, usePageDuplicateModalOpened } from '~/stores/ui';
 
 import AppContainer from '~/client/services/AppContainer';
 import PagePathAutoComplete from './PagePathAutoComplete';
@@ -20,12 +21,16 @@ const LIMIT_FOR_LIST = 10;
 
 const PageDuplicateModal = (props) => {
   const {
-    t, appContainer, pageId, path,
+    t, appContainer,
   } = props;
 
   const config = appContainer.getConfig();
   const isReachable = config.isSearchServiceReachable;
   const { crowi } = appContainer.config;
+  const { data: pagesDataToDuplicate, close: closeDuplicateModal } = usePageDuplicateModalStatus();
+  const { data: isOpened } = usePageDuplicateModalOpened();
+
+  const { path, pageId } = pagesDataToDuplicate;
 
   const [pageNameInput, setPageNameInput] = useState(path);
 
@@ -50,14 +55,14 @@ const PageDuplicateModal = (props) => {
 
   // eslint-disable-next-line react-hooks/exhaustive-deps
   const checkExistPathsDebounce = useCallback(
-    debounce(1000, checkExistPaths), [],
+    debounce(1000, checkExistPaths), [pageId, path],
   );
 
   useEffect(() => {
-    if (pageNameInput !== path) {
+    if (pageId != null && pageNameInput !== path) {
       checkExistPathsDebounce(pageNameInput, subordinatedPages);
     }
-  }, [pageNameInput, subordinatedPages, path, checkExistPathsDebounce]);
+  }, [pageNameInput, subordinatedPages, path, pageId, checkExistPathsDebounce]);
 
   /**
    * change pageNameInput for PagePathAutoComplete
@@ -94,10 +99,11 @@ const PageDuplicateModal = (props) => {
   }, [appContainer, path, t]);
 
   useEffect(() => {
-    if (props.isOpen) {
+    if (isOpened) {
       getSubordinatedList();
+      setPageNameInput(path);
     }
-  }, [props.isOpen, getSubordinatedList]);
+  }, [isOpened, getSubordinatedList, path]);
 
   function changeIsDuplicateRecursivelyWithoutExistPathHandler() {
     setIsDuplicateRecursivelyWithoutExistPath(!isDuplicateRecursivelyWithoutExistPath);
@@ -120,8 +126,8 @@ const PageDuplicateModal = (props) => {
   }
 
   return (
-    <Modal size="lg" isOpen={props.isOpen} toggle={props.onClose} className="grw-duplicate-page" autoFocus={false}>
-      <ModalHeader tag="h4" toggle={props.onClose} className="bg-primary text-light">
+    <Modal size="lg" isOpen={isOpened} toggle={closeDuplicateModal} className="grw-duplicate-page" autoFocus={false}>
+      <ModalHeader tag="h4" toggle={closeDuplicateModal} className="bg-primary text-light">
         { t('modal_duplicate.label.Duplicate page') }
       </ModalHeader>
       <ModalBody>
@@ -188,7 +194,7 @@ const PageDuplicateModal = (props) => {
             )}
           </div>
           <div>
-            {isDuplicateRecursively && <ComparePathsTable path={path} subordinatedPages={subordinatedPages} newPagePath={pageNameInput} />}
+            {isDuplicateRecursively && path != null && <ComparePathsTable path={path} subordinatedPages={subordinatedPages} newPagePath={pageNameInput} />}
             {isDuplicateRecursively && existingPaths.length !== 0 && <DuplicatePathsTable existingPaths={existingPaths} oldPagePath={pageNameInput} />}
           </div>
         </div>
@@ -219,12 +225,6 @@ const PageDuplicateModallWrapper = withUnstatedContainers(PageDuplicateModal, [A
 PageDuplicateModal.propTypes = {
   t: PropTypes.func.isRequired, //  i18next
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
-
-  isOpen: PropTypes.bool.isRequired,
-  onClose: PropTypes.func.isRequired,
-
-  pageId: PropTypes.string.isRequired,
-  path: PropTypes.string.isRequired,
 };
 
 export default withTranslation()(PageDuplicateModallWrapper);

+ 1 - 0
packages/app/src/server/views/layout/layout.html

@@ -105,6 +105,7 @@
 
 <div id="page-create-modal"></div>
 <div id="page-delete-modal"></div>
+<div id="page-duplicate-modal"></div>
 {% include '../modal/shortcuts.html' %}
 
 {% block body_end %}

+ 39 - 1
packages/app/src/stores/ui.tsx

@@ -326,7 +326,7 @@ export const usePageDeleteModalStatus = (status?: DeleteModalStatus): SWRRespons
 
 export const usePageDeleteModalOpened = (): SWRResponse<boolean, Error> => {
   const { data } = usePageDeleteModalStatus();
-  return useSWR(
+  return useSWRImmutable(
     data != null ? ['isDeleteModalOpened', data] : null,
     () => {
       return data != null ? data.isOpened : false;
@@ -334,6 +334,44 @@ export const usePageDeleteModalOpened = (): SWRResponse<boolean, Error> => {
   );
 };
 
+// PageDuplicateModal
+export type IPageForPageDuplicateModal = {
+  pageId: string,
+  path: string
+}
+
+type DuplicateModalStatus = {
+  isOpened: boolean,
+  pageId?: string,
+  path?: string,
+}
+
+type DuplicateModalStatusUtils = {
+  open(pageId: string, path: string): Promise<DuplicateModalStatus | undefined>
+  close(): Promise<DuplicateModalStatus | undefined>
+}
+
+export const usePageDuplicateModalStatus = (status?: DuplicateModalStatus): SWRResponse<DuplicateModalStatus, Error> & DuplicateModalStatusUtils => {
+  const initialData: DuplicateModalStatus = { isOpened: false, pageId: '', path: '' };
+  const swrResponse = useStaticSWR<DuplicateModalStatus, Error>('duplicateModalStatus', status, { fallbackData: initialData });
+
+  return {
+    ...swrResponse,
+    open: (pageId: string, path: string) => swrResponse.mutate({ isOpened: true, pageId, path }),
+    close: () => swrResponse.mutate({ isOpened: false }),
+  };
+};
+
+export const usePageDuplicateModalOpened = (): SWRResponse<boolean, Error> => {
+  const { data } = usePageDuplicateModalStatus();
+  return useSWRImmutable(
+    data != null ? ['isDuplicateModalOpened', data] : null,
+    () => {
+      return data != null ? data.isOpened : false;
+    },
+  );
+};
+
 
 export const useSelectedGrant = (initialData?: Nullable<number>): SWRResponse<Nullable<number>, Error> => {
   return useStaticSWR<Nullable<number>, Error>('grant', initialData);