Yuki Takei 4 месяцев назад
Родитель
Сommit
acef8d772e

+ 0 - 4
apps/app/src/client/components/ItemsTree/ItemsTree.module.scss

@@ -1,4 +0,0 @@
-/* stylelint-disable-next-line block-no-empty */
-.items-tree :global {
-
-}

+ 0 - 164
apps/app/src/client/components/ItemsTree/ItemsTree.tsx

@@ -1,164 +0,0 @@
-import React, { useEffect, useCallback, type JSX } from 'react';
-
-import path from 'path';
-
-import type { IPageToDeleteWithMeta } from '@growi/core';
-import { useTranslation } from 'next-i18next';
-import { useRouter } from 'next/router';
-
-import { toastError, toastSuccess } from '~/client/util/toastr';
-import type { IPageForItem } from '~/interfaces/page';
-import type { OnDuplicatedFunction, OnDeletedFunction } from '~/interfaces/ui';
-import type { UpdateDescCountData, UpdateDescCountRawData } from '~/interfaces/websocket';
-import { SocketEventName } from '~/interfaces/websocket';
-import { useCurrentPagePath, useFetchCurrentPage } from '~/states/page';
-import { useGlobalSocket } from '~/states/socket-io';
-import { usePageDeleteModalActions } from '~/states/ui/modal/page-delete';
-import type { IPageForPageDuplicateModal } from '~/states/ui/modal/page-duplicate';
-import { usePageDuplicateModalActions } from '~/states/ui/modal/page-duplicate';
-import { usePageTreeDescCountMapAction } from '~/features/page-tree/states';
-import { mutateAllPageInfo } from '~/stores/page';
-import {
-  useSWRxRootPage, mutatePageTree, mutatePageList,
-} from '~/stores/page-listing';
-import { mutateSearching } from '~/stores/search';
-import loggerFactory from '~/utils/logger';
-
-import { ItemNode, type TreeItemProps } from '../TreeItem';
-
-import ItemsTreeContentSkeleton from './ItemsTreeContentSkeleton';
-
-import styles from './ItemsTree.module.scss';
-
-const moduleClass = styles['items-tree'] ?? '';
-
-const logger = loggerFactory('growi:cli:ItemsTree');
-
-type ItemsTreeProps = {
-  isEnableActions: boolean
-  isReadOnlyUser: boolean
-  isWipPageShown?: boolean
-  targetPath: string
-  targetPathOrId?: string,
-  CustomTreeItem: React.FunctionComponent<TreeItemProps>
-  onClickTreeItem?: (page: IPageForItem) => void;
-}
-
-/*
- * ItemsTree
- */
-export const ItemsTree = (props: ItemsTreeProps): JSX.Element => {
-  const {
-    targetPath, targetPathOrId, isEnableActions, isReadOnlyUser, isWipPageShown, CustomTreeItem, onClickTreeItem,
-  } = props;
-
-  const { t } = useTranslation();
-  const router = useRouter();
-
-  const { data: rootPageResult, error } = useSWRxRootPage({ suspense: true });
-  const currentPagePath = useCurrentPagePath();
-  const { open: openDuplicateModal } = usePageDuplicateModalActions();
-  const { open: openDeleteModal } = usePageDeleteModalActions();
-
-  const socket = useGlobalSocket();
-  const { update: updatePtDescCountMap } = usePageTreeDescCountMapAction();
-
-  // for mutation
-  const { fetchCurrentPage } = useFetchCurrentPage();
-
-  useEffect(() => {
-    if (socket == null) {
-      return;
-    }
-
-    socket.on(SocketEventName.UpdateDescCount, (data: UpdateDescCountRawData) => {
-      // save to global state
-      const newData: UpdateDescCountData = new Map(Object.entries(data));
-
-      updatePtDescCountMap(newData);
-    });
-
-    return () => { socket.off(SocketEventName.UpdateDescCount) };
-
-  }, [socket, updatePtDescCountMap]);
-
-  const onRenamed = useCallback((fromPath: string | undefined, toPath: string) => {
-    mutatePageTree();
-    mutateSearching();
-    mutatePageList();
-
-    if (currentPagePath === fromPath || currentPagePath === toPath) {
-      fetchCurrentPage({ force: true });
-    }
-  }, [currentPagePath, fetchCurrentPage]);
-
-  const onClickDuplicateMenuItem = useCallback((pageToDuplicate: IPageForPageDuplicateModal) => {
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    const duplicatedHandler: OnDuplicatedFunction = (fromPath, toPath) => {
-      toastSuccess(t('duplicated_pages', { fromPath }));
-
-      mutatePageTree();
-      mutateSearching();
-      mutatePageList();
-    };
-
-    openDuplicateModal(pageToDuplicate, { onDuplicated: duplicatedHandler });
-  }, [openDuplicateModal, t]);
-
-  const onClickDeleteMenuItem = useCallback((pageToDelete: IPageToDeleteWithMeta) => {
-    const onDeletedHandler: OnDeletedFunction = (pathOrPathsToDelete, isRecursively, isCompletely) => {
-      if (typeof pathOrPathsToDelete !== 'string') {
-        return;
-      }
-
-      if (isCompletely) {
-        toastSuccess(t('deleted_pages_completely', { path: pathOrPathsToDelete }));
-      }
-      else {
-        toastSuccess(t('deleted_pages', { path: pathOrPathsToDelete }));
-      }
-
-      mutatePageTree();
-      mutateSearching();
-      mutatePageList();
-      mutateAllPageInfo();
-
-      if (currentPagePath === pathOrPathsToDelete) {
-        fetchCurrentPage({ force: true });
-        router.push(isCompletely ? path.dirname(pathOrPathsToDelete) : `/trash${pathOrPathsToDelete}`);
-      }
-    };
-
-    openDeleteModal([pageToDelete], { onDeleted: onDeletedHandler });
-  }, [currentPagePath, fetchCurrentPage, openDeleteModal, router, t]);
-
-
-  if (error != null) {
-    toastError(t('pagetree.error_retrieving_the_pagetree'));
-    return <></>;
-  }
-
-  const initialItemNode = rootPageResult ? new ItemNode(rootPageResult.rootPage) : null;
-  if (initialItemNode != null) {
-    return (
-      <ul className={`${moduleClass} list-group`}>
-        <CustomTreeItem
-          key={initialItemNode.page.path}
-          targetPath={targetPath}
-          targetPathOrId={targetPathOrId}
-          itemNode={initialItemNode}
-          isOpen
-          isEnableActions={isEnableActions}
-          isWipPageShown={isWipPageShown}
-          isReadOnlyUser={isReadOnlyUser}
-          onRenamed={onRenamed}
-          onClickDuplicateMenuItem={onClickDuplicateMenuItem}
-          onClickDeleteMenuItem={onClickDeleteMenuItem}
-          onClick={onClickTreeItem}
-        />
-      </ul>
-    );
-  }
-
-  return <ItemsTreeContentSkeleton />;
-};

+ 0 - 6
apps/app/src/client/components/ItemsTree/index.ts

@@ -1,6 +0,0 @@
-// Re-export from features/page-tree (new implementation)
-export { SimplifiedItemsTree } from '~/features/page-tree/components';
-
-// Legacy exports (for old implementation - will be deprecated)
-export { ItemNode } from '../TreeItem';
-export * from './ItemsTree';

+ 0 - 40
apps/app/src/client/components/PageSelectModal/TreeItemForModal.tsx

@@ -1,40 +0,0 @@
-import type { FC } from 'react';
-
-import {
-  TreeItemLayout, useNewPageInput, type TreeItemProps,
-} from '../TreeItem';
-
-
-import styles from './TreeItemForModal.module.scss';
-
-const moduleClass = styles['tree-item-for-modal'];
-
-
-type TreeItemForModalProps = TreeItemProps & {
-  key?: React.Key | null,
-};
-
-export const TreeItemForModal: FC<TreeItemForModalProps> = (props) => {
-
-  const { itemNode, targetPathOrId } = props;
-  const { page } = itemNode;
-
-  const { Input: NewPageInput, CreateButton: NewPageCreateButton } = useNewPageInput();
-
-  const isSelected = page._id === targetPathOrId || page.path === targetPathOrId;
-
-  const itemClassNames = [
-    isSelected ? 'active' : '',
-  ];
-
-  return (
-    <TreeItemLayout
-      {...props}
-      className={moduleClass}
-      itemClass={TreeItemForModal}
-      itemClassName={itemClassNames.join(' ')}
-      customHeadOfChildrenComponents={[NewPageInput]}
-      customHoveredEndComponents={[NewPageCreateButton]}
-    />
-  );
-};

+ 1 - 1
apps/app/src/client/components/Sidebar/PageTree/PageTreeSubstance.tsx

@@ -13,7 +13,7 @@ import {
 } from '~/stores/page-listing';
 import loggerFactory from '~/utils/logger';
 
-import { SimplifiedItemsTree } from '../../ItemsTree';
+import { SimplifiedItemsTree } from '~/features/page-tree/components';
 import { SimplifiedPageTreeItem, simplifiedPageTreeItemSize } from '../PageTreeItem';
 import { SidebarHeaderReloadButton } from '../SidebarHeaderReloadButton';
 

+ 1 - 1
apps/app/src/client/components/Sidebar/PageTreeItem/CountBadgeForPageTreeItem.tsx

@@ -1,7 +1,7 @@
 import type { JSX } from 'react';
 
 import CountBadge from '~/client/components/Common/CountBadge';
-import type { TreeItemToolProps } from '~/client/components/TreeItem';
+import type { TreeItemToolProps } from '~/features/page-tree/interfaces';
 import { usePageTreeDescCountMap } from '~/features/page-tree/states';
 
 

+ 0 - 211
apps/app/src/client/components/Sidebar/PageTreeItem/PageTreeItem.tsx

@@ -1,211 +0,0 @@
-import React, {
-  useCallback, useState, type JSX,
-} from 'react';
-
-import nodePath from 'path';
-
-import type { IPageHasId } from '@growi/core';
-import { pagePathUtils, pathUtils } from '@growi/core/dist/utils';
-import { useTranslation } from 'next-i18next';
-import { useRouter } from 'next/router';
-import { useDrag, useDrop } from 'react-dnd';
-
-import { apiv3Put } from '~/client/util/apiv3-client';
-import { toastWarning, toastError } from '~/client/util/toastr';
-import type { IPageForItem } from '~/interfaces/page';
-import { mutatePageTree, useSWRxPageChildren } from '~/stores/page-listing';
-import loggerFactory from '~/utils/logger';
-
-import type { ItemNode } from '../../TreeItem';
-import {
-  TreeItemLayout, useNewPageInput, type TreeItemProps,
-} from '../../TreeItem';
-
-import { CountBadgeForPageTreeItem } from './CountBadgeForPageTreeItem';
-import { CreatingNewPageSpinner } from './CreatingNewPageSpinner';
-import { usePageItemControl } from './use-page-item-control';
-
-
-import styles from './PageTreeItem.module.scss';
-
-const moduleClass = styles['page-tree-item'] ?? '';
-
-
-const logger = loggerFactory('growi:cli:Item');
-
-export const PageTreeItem = (props:TreeItemProps): JSX.Element => {
-  const router = useRouter();
-
-  const getNewPathAfterMoved = (droppedPagePath: string, newParentPagePath: string): string => {
-    const pageTitle = nodePath.basename(droppedPagePath);
-    return nodePath.join(newParentPagePath, pageTitle);
-  };
-
-  const isDroppable = (fromPage?: Partial<IPageHasId>, newParentPage?: Partial<IPageHasId>, printLog = false): boolean => {
-    if (fromPage == null || newParentPage == null || fromPage.path == null || newParentPage.path == null) {
-      if (printLog) {
-        logger.warn('Any of page, page.path or droppedPage.path is null');
-      }
-      return false;
-    }
-
-    const newPathAfterMoved = getNewPathAfterMoved(fromPage.path, newParentPage.path);
-    return pagePathUtils.canMoveByPath(fromPage.path, newPathAfterMoved) && !pagePathUtils.isUsersTopPage(newParentPage.path);
-  };
-
-  const { t } = useTranslation();
-
-  const {
-    itemNode, targetPathOrId, isOpen: _isOpen = false, onRenamed,
-  } = props;
-
-  const { page } = itemNode;
-  const [isOpen, setIsOpen] = useState(_isOpen);
-
-  const { mutate: mutateChildren } = useSWRxPageChildren(isOpen ? page._id : null);
-
-  const {
-    showRenameInput, Control, RenameInput,
-  } = usePageItemControl();
-  const { isProcessingSubmission, Input: NewPageInput, CreateButton: NewPageCreateButton } = useNewPageInput();
-
-  const itemSelectedHandler = useCallback((page: IPageForItem) => {
-    if (page.path == null || page._id == null) {
-      return;
-    }
-
-    const link = pathUtils.returnPathForURL(page.path, page._id);
-
-    router.push(link);
-  }, [router]);
-
-  const itemSelectedByWheelClickHandler = useCallback((page: IPageForItem) => {
-    if (page.path == null || page._id == null) {
-      return;
-    }
-
-    const url = pathUtils.returnPathForURL(page.path, page._id);
-
-    window.open(url, '_blank');
-  }, []);
-
-  const [, drag] = useDrag({
-    type: 'PAGE_TREE',
-    item: { page },
-    canDrag: () => {
-      if (page.path == null) {
-        return false;
-      }
-      return !pagePathUtils.isUsersProtectedPages(page.path);
-    },
-    end: (item, monitor) => {
-      // in order to set d-none to dropped Item
-      const dropResult = monitor.getDropResult();
-    },
-    collect: monitor => ({
-      isDragging: monitor.isDragging(),
-      canDrag: monitor.canDrag(),
-    }),
-  });
-
-  const pageItemDropHandler = async(item: ItemNode) => {
-    const { page: droppedPage } = item;
-    if (!isDroppable(droppedPage, page, true)) {
-      return;
-    }
-    if (droppedPage.path == null || page.path == null) {
-      return;
-    }
-    const newPagePath = getNewPathAfterMoved(droppedPage.path, page.path);
-    try {
-      await apiv3Put('/pages/rename', {
-        pageId: droppedPage._id,
-        revisionId: droppedPage.revision,
-        newPagePath,
-        isRenameRedirect: false,
-        updateMetadata: true,
-      });
-      await mutatePageTree();
-      await mutateChildren();
-      if (onRenamed != null) {
-        onRenamed(page.path, newPagePath);
-      }
-      // force open
-      setIsOpen(true);
-    }
-    catch (err) {
-      if (err.code === 'operation__blocked') {
-        toastWarning(t('pagetree.you_cannot_move_this_page_now'));
-      }
-      else {
-        toastError(t('pagetree.something_went_wrong_with_moving_page'));
-      }
-    }
-  };
-
-  const [{ isOver }, drop] = useDrop<ItemNode, Promise<void>, { isOver: boolean }>(
-    () => ({
-      accept: 'PAGE_TREE',
-      drop: pageItemDropHandler,
-      hover: (item, monitor) => {
-        // when a drag item is overlapped more than 1 sec, the drop target item will be opened.
-        if (monitor.isOver()) {
-          setTimeout(() => {
-            if (monitor.isOver()) {
-              setIsOpen(true);
-            }
-          }, 600);
-        }
-      },
-      canDrop: (item) => {
-        const { page: droppedPage } = item;
-        return isDroppable(droppedPage, page);
-      },
-      collect: monitor => ({
-        isOver: monitor.isOver(),
-      }),
-    }),
-    [page],
-  );
-
-  const itemRef = (c) => {
-    // do not apply when RenameInput is shown
-    if (showRenameInput) return;
-
-    drag(c);
-    drop(c);
-  };
-
-  const isSelected = page._id === targetPathOrId || page.path === targetPathOrId;
-  const itemClassNames = [
-    isOver ? 'drag-over' : '',
-    page.path !== '/' && isSelected ? 'active' : '', // set 'active' except the root page
-  ];
-
-  return (
-    <TreeItemLayout
-      className={moduleClass}
-      targetPath={props.targetPath}
-      targetPathOrId={props.targetPathOrId}
-      itemLevel={props.itemLevel}
-      itemNode={props.itemNode}
-      isOpen={isOpen}
-      isEnableActions={props.isEnableActions}
-      isReadOnlyUser={props.isReadOnlyUser}
-      isWipPageShown={props.isWipPageShown}
-      onClick={itemSelectedHandler}
-      onClickDuplicateMenuItem={props.onClickDuplicateMenuItem}
-      onClickDeleteMenuItem={props.onClickDeleteMenuItem}
-      onWheelClick={itemSelectedByWheelClickHandler}
-      onRenamed={props.onRenamed}
-      itemRef={itemRef}
-      itemClass={PageTreeItem}
-      itemClassName={itemClassNames.join(' ')}
-      customEndComponents={[CountBadgeForPageTreeItem]}
-      customHoveredEndComponents={[Control, NewPageCreateButton]}
-      customHeadOfChildrenComponents={[NewPageInput, () => <CreatingNewPageSpinner show={isProcessingSubmission} />]}
-      showAlternativeContent={showRenameInput}
-      customAlternativeComponents={[RenameInput]}
-    />
-  );
-};

+ 2 - 2
apps/app/src/client/components/Sidebar/PageTreeItem/SimplifiedPageTreeItem.tsx

@@ -25,8 +25,8 @@ import { mutateAllPageInfo } from '~/stores/page';
 import { mutatePageTree, mutatePageList } from '~/stores/page-listing';
 import { mutateSearching } from '~/stores/search';
 
-import type { TreeItemProps } from '../../TreeItem';
-import { TreeItemLayout } from '../../TreeItem';
+import type { TreeItemProps } from '~/features/page-tree/interfaces';
+import { TreeItemLayout } from '~/features/page-tree/components';
 
 import { CountBadgeForPageTreeItem } from './CountBadgeForPageTreeItem';
 import { usePageItemControl } from './use-page-item-control';

+ 0 - 1
apps/app/src/client/components/Sidebar/PageTreeItem/index.ts

@@ -1,2 +1 @@
-export * from './PageTreeItem';
 export * from './SimplifiedPageTreeItem';

+ 1 - 1
apps/app/src/client/components/Sidebar/PageTreeItem/use-page-item-control.tsx

@@ -13,7 +13,7 @@ import { useSWRMUTxCurrentUserBookmarks } from '~/stores/bookmark';
 import { useSWRMUTxPageInfo } from '~/stores/page';
 
 import { PageItemControl } from '../../Common/Dropdown/PageItemControl';
-import type { TreeItemToolProps } from '../../TreeItem';
+import type { TreeItemToolProps } from '~/features/page-tree/interfaces';
 
 
 type UsePageItemControl = {

+ 0 - 18
apps/app/src/client/components/TreeItem/ItemNode.ts

@@ -1,18 +0,0 @@
-import type { IPageForItem } from '../../../interfaces/page';
-
-export class ItemNode {
-
-  page: IPageForItem;
-
-  children: ItemNode[];
-
-  constructor(page: IPageForItem, children: ItemNode[] = []) {
-    this.page = page;
-    this.children = children;
-  }
-
-  static generateNodesFromPages(pages: IPageForItem[]): ItemNode[] {
-    return pages.map(page => new ItemNode(page));
-  }
-
-}

+ 0 - 37
apps/app/src/client/components/TreeItem/NewPageInput/NewPageCreateButton.tsx

@@ -1,37 +0,0 @@
-import React, { type FC } from 'react';
-
-import { pagePathUtils } from '@growi/core/dist/utils';
-
-import { NotAvailableForGuest } from '~/client/components/NotAvailableForGuest';
-import { NotAvailableForReadOnlyUser } from '~/client/components/NotAvailableForReadOnlyUser';
-import type { IPageForItem } from '~/interfaces/page';
-
-type NewPageCreateButtonProps = {
-  page: IPageForItem,
-  onClick?: () => void,
-};
-
-export const NewPageCreateButton: FC<NewPageCreateButtonProps> = (props) => {
-  const {
-    page, onClick,
-  } = props;
-
-  return (
-    <>
-      {!pagePathUtils.isUsersTopPage(page.path ?? '') && (
-        <NotAvailableForGuest>
-          <NotAvailableForReadOnlyUser>
-            <button
-              id="page-create-button-in-page-tree"
-              type="button"
-              className="border-0 rounded btn btn-page-item-control p-0"
-              onClick={onClick}
-            >
-              <span className="material-symbols-outlined p-0">add_circle</span>
-            </button>
-          </NotAvailableForReadOnlyUser>
-        </NotAvailableForGuest>
-      )}
-    </>
-  );
-};

+ 0 - 6
apps/app/src/client/components/TreeItem/NewPageInput/NewPageInput.module.scss

@@ -1,6 +0,0 @@
-@use '../../../../features/page-tree/components/tree-item-variables';
-
-.new-page-input-container {
-  width: calc(100% - tree-item-variables.$btn-triangle-min-width);
-  padding-left: 24px;
-}

+ 0 - 1
apps/app/src/client/components/TreeItem/NewPageInput/index.ts

@@ -1 +0,0 @@
-export * from './use-new-page-input';

+ 0 - 180
apps/app/src/client/components/TreeItem/NewPageInput/use-new-page-input.tsx

@@ -1,180 +0,0 @@
-import type { ChangeEvent } from 'react';
-import React, {
-  useState, type FC, useCallback, useRef,
-} from 'react';
-
-import nodePath from 'path';
-
-import { Origin } from '@growi/core';
-import { pathUtils, pagePathUtils } from '@growi/core/dist/utils';
-import { useRect } from '@growi/ui/dist/utils';
-import { useTranslation } from 'next-i18next';
-import { debounce } from 'throttle-debounce';
-
-import { AutosizeSubmittableInput, getAdjustedMaxWidthForAutosizeInput } from '~/client/components/Common/SubmittableInput';
-import { useCreatePage } from '~/client/services/create-page';
-import { toastWarning, toastError, toastSuccess } from '~/client/util/toastr';
-import type { InputValidationResult } from '~/client/util/use-input-validator';
-import { ValidationTarget, useInputValidator } from '~/client/util/use-input-validator';
-import { usePageTreeDescCountMap } from '~/features/page-tree/states';
-import { mutatePageTree, mutateRecentlyUpdated } from '~/stores/page-listing';
-
-import { shouldCreateWipPage } from '../../../../utils/should-create-wip-page';
-import type { TreeItemToolProps } from '..';
-
-import { NewPageCreateButton } from './NewPageCreateButton';
-
-
-import newPageInputStyles from './NewPageInput.module.scss';
-
-
-type UseNewPageInput = {
-  Input: FC<TreeItemToolProps>,
-  CreateButton: FC<TreeItemToolProps>,
-  isProcessingSubmission: boolean,
-}
-
-export const useNewPageInput = (): UseNewPageInput => {
-
-  const [showInput, setShowInput] = useState(false);
-  const [isProcessingSubmission, setProcessingSubmission] = useState(false);
-
-  const CreateButton: FC<TreeItemToolProps> = (props) => {
-
-    const { itemNode, stateHandlers } = props;
-    const { page } = itemNode;
-
-    const onClick = useCallback(() => {
-      setShowInput(true);
-      stateHandlers?.setIsOpen(true);
-    }, [stateHandlers]);
-
-    return (
-      <NewPageCreateButton
-        page={page}
-        onClick={onClick}
-      />
-    );
-  };
-
-  const Input: FC<TreeItemToolProps> = (props) => {
-
-    const { t } = useTranslation();
-    const { create: createPage } = useCreatePage();
-
-    const { itemNode, stateHandlers, isEnableActions } = props;
-    const { page, children } = itemNode;
-
-    const { getDescCount } = usePageTreeDescCountMap();
-    const descendantCount = getDescCount(page._id) || page.descendantCount || 0;
-
-    const isChildrenLoaded = children?.length > 0;
-    const hasDescendants = descendantCount > 0 || isChildrenLoaded;
-
-    const parentRef = useRef<HTMLDivElement>(null);
-    const [parentRect] = useRect(parentRef);
-
-    const [validationResult, setValidationResult] = useState<InputValidationResult>();
-
-    const inputValidator = useInputValidator(ValidationTarget.PAGE);
-
-    const changeHandler = useCallback(async (e: ChangeEvent<HTMLInputElement>) => {
-      const validationResult = inputValidator(e.target.value);
-      setValidationResult(validationResult ?? undefined);
-    }, [inputValidator]);
-    const changeHandlerDebounced = debounce(300, changeHandler);
-
-    const cancel = useCallback(() => {
-      setValidationResult(undefined);
-      setShowInput(false);
-    }, []);
-
-    const create = useCallback(async (inputText) => {
-      if (inputText.trim() === '') {
-        return cancel();
-      }
-
-      const parentPath = pathUtils.addTrailingSlash(page.path as string);
-      const newPagePath = nodePath.resolve(parentPath, inputText);
-      const isCreatable = pagePathUtils.isCreatablePage(newPagePath);
-
-      if (!isCreatable) {
-        toastWarning(t('you_can_not_create_page_with_this_name_or_hierarchy'));
-        return;
-      }
-
-      setProcessingSubmission(true);
-
-      setShowInput(false);
-
-      try {
-        await createPage(
-          {
-            path: newPagePath,
-            parentPath,
-            body: undefined,
-            // keep grant info undefined to inherit from parent
-            grant: undefined,
-            grantUserGroupIds: undefined,
-            origin: Origin.View,
-            wip: shouldCreateWipPage(newPagePath),
-          },
-          {
-            skipTransition: true,
-            onCreated: () => {
-              mutatePageTree();
-              mutateRecentlyUpdated();
-
-              if (!hasDescendants) {
-                stateHandlers?.setIsOpen(true);
-              }
-
-              toastSuccess(t('successfully_saved_the_page'));
-            },
-          },
-        );
-      }
-      catch (err) {
-        toastError(err);
-      }
-      finally {
-        setProcessingSubmission(false);
-      }
-    }, [cancel, hasDescendants, page.path, stateHandlers, t, createPage]);
-
-    const inputContainerClass = newPageInputStyles['new-page-input-container'] ?? '';
-    const isInvalid = validationResult != null;
-
-    const maxWidth = parentRect != null
-      ? getAdjustedMaxWidthForAutosizeInput(parentRect.width, 'sm', validationResult != null ? false : undefined)
-      : undefined;
-
-    return isEnableActions && showInput
-      ? (
-        <div ref={parentRef} className={inputContainerClass}>
-          <AutosizeSubmittableInput
-            inputClassName={`form-control ${isInvalid ? 'is-invalid' : ''}`}
-            inputStyle={{ maxWidth }}
-            placeholder={t('Input page name')}
-            aria-describedby={isInvalid ? 'new-page-input-feedback' : undefined}
-            onChange={changeHandlerDebounced}
-            onSubmit={create}
-            onCancel={cancel}
-            autoFocus
-          />
-          {isInvalid && (
-            <div id="new-page-input" className="invalid-feedback d-block my-1">
-              {validationResult.message}
-            </div>
-          )}
-        </div>
-      )
-      : <></>;
-  };
-
-  return {
-    Input,
-    CreateButton,
-    isProcessingSubmission,
-  };
-};

+ 0 - 9
apps/app/src/client/components/TreeItem/index.ts

@@ -1,9 +0,0 @@
-// Re-export from features/page-tree (new implementation)
-// Components
-export { TreeItemLayout, SimpleItemContent } from '~/features/page-tree/components';
-// Interfaces
-export type { TreeItemProps, TreeItemToolProps } from '~/features/page-tree/interfaces';
-
-// Legacy exports (for old implementation - will be deprecated)
-export * from './NewPageInput';
-export * from './ItemNode';