Mudana-Grune пре 3 година
родитељ
комит
c2966b45e4

+ 12 - 0
packages/app/src/client/util/bookmark-utils.ts

@@ -0,0 +1,12 @@
+import { BookmarkFolderItems } from '~/interfaces/bookmark-info';
+
+
+export const hasChildren = (item: BookmarkFolderItems | BookmarkFolderItems[]): boolean => {
+  if (item === null) {
+    return false;
+  }
+  if (Array.isArray(item)) {
+    return item.length > 0;
+  }
+  return item.children && item.children.length > 0;
+};

+ 15 - 0
packages/app/src/client/util/input-validator-utils.ts

@@ -0,0 +1,15 @@
+import i18n from 'i18next';
+
+import { AlertInfo, AlertType } from '~/components/Common/ClosableTextInput';
+
+// Validator for closeable text input
+export const inputValidator = (title: string | null): AlertInfo | null => {
+
+  if (title == null || title === '' || title.trim() === '') {
+    return {
+      type: AlertType.WARNING,
+      message: i18n.t('form_validation.title_required'),
+    };
+  }
+  return null;
+};

+ 6 - 6
packages/app/src/components/Bookmarks/BookmarkFolderItem.tsx

@@ -7,6 +7,7 @@ import { useDrag, useDrop } from 'react-dnd';
 import { DropdownToggle } from 'reactstrap';
 
 import { apiv3Post, apiv3Put } from '~/client/util/apiv3-client';
+import { hasChildren } from '~/client/util/bookmark-utils';
 import { toastError, toastSuccess } from '~/client/util/toastr';
 import { FolderIcon } from '~/components/Icons/FolderIcon';
 import { TriangleIcon } from '~/components/Icons/TriangleIcon';
@@ -57,9 +58,8 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
   const { open: openDeleteModal } = usePageDeleteModal();
   const { open: openDeleteBookmarkFolderModal } = useBookmarkFolderDeleteModal();
 
-  const hasChildren = useCallback((): boolean => {
-    return children != null && children.length > 0;
-  }, [children]);
+  const childrenExists = hasChildren(children);
+
 
   const loadChildFolder = useCallback(async() => {
     setIsOpen(!isOpen);
@@ -98,11 +98,11 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
 
   const onClickPlusButton = useCallback(async(e) => {
     e.stopPropagation();
-    if (!isOpen && hasChildren()) {
+    if (!isOpen && childrenExists) {
       setIsOpen(true);
     }
     setIsCreateAction(true);
-  }, [hasChildren, isOpen]);
+  }, [childrenExists, isOpen]);
 
   const onClickDeleteBookmarkHandler = useCallback((pageToDelete: IPageToDeleteWithMeta) => {
     const pageDeletedHandler: OnDeletedFunction = (pathOrPathsToDelete, _isRecursively, isCompletely) => {
@@ -257,7 +257,7 @@ export const BookmarkFolderItem: FC<BookmarkFolderItemProps> = (props: BookmarkF
         onClick={loadChildFolder}
       >
         <div className="grw-triangle-container d-flex justify-content-center">
-          {hasChildren() && (
+          {childrenExists && (
             <button
               type="button"
               className={`grw-foldertree-triangle-btn btn ${isOpen ? 'grw-foldertree-open' : ''}`}

+ 9 - 9
packages/app/src/components/Bookmarks/BookmarkFolderMenuItem.tsx

@@ -7,6 +7,7 @@ import {
 } from 'reactstrap';
 
 import { apiv3Post, apiv3Put } from '~/client/util/apiv3-client';
+import { hasChildren } from '~/client/util/bookmark-utils';
 import { toastError, toastSuccess } from '~/client/util/toastr';
 import { BookmarkFolderItems } from '~/interfaces/bookmark-info';
 import { onDeletedBookmarkFolderFunction } from '~/interfaces/ui';
@@ -42,9 +43,7 @@ export const BookmarkFolderMenuItem = (props: Props): JSX.Element => {
 
   const isBookmarked = userBookmarkInfo?.isBookmarked;
 
-  const hasChildren = useCallback((): boolean => {
-    return item.children.length > 0;
-  }, [item.children.length]);
+  const childrenExists = hasChildren(item);
 
   const onPressEnterHandlerForCreate = useCallback(async(folderName: string) => {
     try {
@@ -143,7 +142,7 @@ export const BookmarkFolderMenuItem = (props: Props): JSX.Element => {
           </DropdownItem>
         )}
 
-        {hasChildren() && (<DropdownItem divider />)}
+        {childrenExists && (<DropdownItem divider />)}
 
         {item.children?.map(child => (
           <div key={child._id} >
@@ -161,14 +160,15 @@ export const BookmarkFolderMenuItem = (props: Props): JSX.Element => {
         ))}
       </DropdownMenu>
     );
-  }, [hasChildren,
+  }, [isOpen,
       isCreateAction,
-      isOpen, item.children,
-      onClickChildMenuItemHandler,
-      onClickNewBookmarkFolder,
       onPressEnterHandlerForCreate,
       t,
+      childrenExists,
+      item.children,
+      onClickNewBookmarkFolder,
       selectedItem,
+      onClickChildMenuItemHandler,
   ]);
 
   return (
@@ -207,7 +207,7 @@ export const BookmarkFolderMenuItem = (props: Props): JSX.Element => {
           onClick={e => e.stopPropagation()}
           onMouseEnter={onMouseEnterHandler}
         >
-          {hasChildren()
+          {childrenExists
             ? <TriangleIcon />
             : (
               <i className="icon-plus d-block pl-0" />

+ 2 - 12
packages/app/src/components/Bookmarks/BookmarkFolderNameInput.tsx

@@ -1,6 +1,7 @@
 import { useTranslation } from 'next-i18next';
 
-import ClosableTextInput, { AlertInfo, AlertType } from '~/components/Common/ClosableTextInput';
+import { inputValidator } from '~/client/util/input-validator-utils';
+import ClosableTextInput from '~/components/Common/ClosableTextInput';
 
 
 type Props = {
@@ -15,17 +16,6 @@ export const BookmarkFolderNameInput = (props: Props): JSX.Element => {
   } = props;
   const { t } = useTranslation();
 
-
-  const inputValidator = (title: string | null): AlertInfo | null => {
-    if (title == null || title === '' || title.trim() === '') {
-      return {
-        type: AlertType.WARNING,
-        message: t('form_validation.title_required'),
-      };
-    }
-    return null;
-  };
-
   return (
     <div className="flex-fill folder-name-input">
       <ClosableTextInput

+ 2 - 11
packages/app/src/components/Bookmarks/BookmarkItem.tsx

@@ -9,13 +9,14 @@ import { UncontrolledTooltip, DropdownToggle } from 'reactstrap';
 
 import { unbookmark } from '~/client/services/page-operation';
 import { apiv3Put } from '~/client/util/apiv3-client';
+import { inputValidator } from '~/client/util/input-validator-utils';
 import { toastError, toastSuccess } from '~/client/util/toastr';
 import { BookmarkFolderItems, DRAG_ITEM_TYPE } from '~/interfaces/bookmark-info';
 import { IPageHasId, IPageInfoAll, IPageToDeleteWithMeta } from '~/interfaces/page';
 import { useSWRxBookamrkFolderAndChild } from '~/stores/bookmark-folder';
 import { useSWRxPageInfo } from '~/stores/page';
 
-import ClosableTextInput, { AlertInfo, AlertType } from '../Common/ClosableTextInput';
+import ClosableTextInput from '../Common/ClosableTextInput';
 import { MenuItemType, PageItemControl } from '../Common/Dropdown/PageItemControl';
 import { PageListItemS } from '../PageList/PageListItemS';
 
@@ -53,16 +54,6 @@ export const BookmarkItem = (props: Props): JSX.Element => {
     setRenameInputShown(true);
   }, []);
 
-  const inputValidator = (title: string | null): AlertInfo | null => {
-    if (title == null || title === '' || title.trim() === '') {
-      return {
-        type: AlertType.WARNING,
-        message: t('form_validation.title_required'),
-      };
-    }
-
-    return null;
-  };
 
   const pressEnterForRenameHandler = useCallback(async(inputText: string) => {
     const parentPath = pathUtils.addTrailingSlash(nodePath.dirname(bookmarkedPage.path ?? ''));

+ 2 - 12
packages/app/src/components/PageList/BookmarkList.tsx

@@ -11,10 +11,11 @@ import { DropdownToggle } from 'reactstrap';
 import { unbookmark } from '~/client/services/page-operation';
 import { toastError, toastSuccess } from '~/client/util/apiNotification';
 import { apiv3Put } from '~/client/util/apiv3-client';
+import { inputValidator } from '~/client/util/input-validator-utils';
 import { IPageHasId } from '~/interfaces/page';
 import loggerFactory from '~/utils/logger';
 
-import ClosableTextInput, { AlertInfo, AlertType } from '../Common/ClosableTextInput';
+import ClosableTextInput from '../Common/ClosableTextInput';
 import { MenuItemType, PageItemControl } from '../Common/Dropdown/PageItemControl';
 
 import { PageListItemS } from './PageListItemS';
@@ -34,17 +35,6 @@ export const BookmarkList = (props:Props): JSX.Element => {
   const { t } = useTranslation();
   const [isRenameInputShown, setIsRenameInputShown] = useState(false);
 
-  const inputValidator = (title: string | null): AlertInfo | null => {
-    if (title == null || title === '' || title.trim() === '') {
-      return {
-        type: AlertType.WARNING,
-        message: t('form_validation.title_required'),
-      };
-    }
-
-    return null;
-  };
-
   const bookmarkMenuItemClickHandler = useCallback(async() => {
     await unbookmark(page._id);
     onUnbookmarked();

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

@@ -13,6 +13,7 @@ import { UncontrolledTooltip, DropdownToggle } from 'reactstrap';
 import { bookmark, unbookmark, resumeRenameOperation } from '~/client/services/page-operation';
 import { toastWarning, toastError, toastSuccess } from '~/client/util/apiNotification';
 import { apiv3Put, apiv3Post } from '~/client/util/apiv3-client';
+import { inputValidator } from '~/client/util/input-validator-utils';
 import { TriangleIcon } from '~/components/Icons/TriangleIcon';
 import { NotAvailableForGuest } from '~/components/NotAvailableForGuest';
 import {
@@ -25,7 +26,7 @@ import { usePageTreeDescCountMap } from '~/stores/ui';
 import loggerFactory from '~/utils/logger';
 import { shouldRecoverPagePaths } from '~/utils/page-operation';
 
-import ClosableTextInput, { AlertInfo, AlertType } from '../../Common/ClosableTextInput';
+import ClosableTextInput from '../../Common/ClosableTextInput';
 import CountBadge from '../../Common/CountBadge';
 import { PageItemControl } from '../../Common/Dropdown/PageItemControl';
 
@@ -370,16 +371,6 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
     }
   };
 
-  const inputValidator = (title: string | null): AlertInfo | null => {
-    if (title == null || title === '' || title.trim() === '') {
-      return {
-        type: AlertType.WARNING,
-        message: t('form_validation.title_required'),
-      };
-    }
-
-    return null;
-  };
 
   /**
    * Users do not need to know if all pages have been renamed.