Explorar el Código

refactor SimpleItem as TreeItemLayout

Yuki Takei hace 1 año
padre
commit
f7c3eb047f

+ 2 - 2
apps/app/src/components/PageSelectModal/TreeItemForModal.tsx

@@ -1,7 +1,7 @@
 import type { FC } from 'react';
 
 import {
-  SimpleItem, useNewPageInput, type TreeItemProps,
+  TreeItemLayout, useNewPageInput, type TreeItemProps,
 } from '../TreeItem';
 
 
@@ -16,7 +16,7 @@ export const TreeItemForModal: FC<PageTreeItemProps> = (props) => {
   const { Input: NewPageInput, CreateButton: NewPageCreateButton } = useNewPageInput();
 
   return (
-    <SimpleItem
+    <TreeItemLayout
       key={props.key}
       targetPathOrId={props.targetPathOrId}
       itemNode={props.itemNode}

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

@@ -19,7 +19,7 @@ import loggerFactory from '~/utils/logger';
 
 import type { ItemNode } from '../../TreeItem';
 import {
-  SimpleItem, useNewPageInput, type TreeItemProps,
+  TreeItemLayout, useNewPageInput, type TreeItemProps,
 } from '../../TreeItem';
 
 import { CountBadgeForPageTreeItem } from './CountBadgeForPageTreeItem';
@@ -174,7 +174,7 @@ export const PageTreeItem: FC<TreeItemProps> = (props) => {
   const { isProcessingSubmission, Input: NewPageInput, CreateButton: NewPageCreateButton } = useNewPageInput();
 
   return (
-    <SimpleItem
+    <TreeItemLayout
       targetPathOrId={props.targetPathOrId}
       itemNode={props.itemNode}
       isOpen={isOpen}

+ 42 - 0
apps/app/src/components/TreeItem/SimpleItemContent.tsx

@@ -0,0 +1,42 @@
+import nodePath from 'path';
+
+import { useTranslation } from 'next-i18next';
+import { UncontrolledTooltip } from 'reactstrap';
+
+import type { IPageForItem } from '~/interfaces/page';
+import { shouldRecoverPagePaths } from '~/utils/page-operation';
+
+
+export const SimpleItemContent = ({ page }: { page: IPageForItem }): JSX.Element => {
+  const { t } = useTranslation();
+
+  const pageName = nodePath.basename(page.path ?? '') || '/';
+
+  const shouldShowAttentionIcon = page.processData != null ? shouldRecoverPagePaths(page.processData) : false;
+
+  return (
+    <div
+      className="flex-grow-1 d-flex align-items-center pe-none"
+      style={{ minWidth: 0 }}
+    >
+      {shouldShowAttentionIcon && (
+        <>
+          <span id="path-recovery" className="material-symbols-outlined mr-2 text-warning">warning</span>
+          <UncontrolledTooltip placement="top" target="path-recovery" fade={false}>
+            {t('tooltip.operation.attention.rename')}
+          </UncontrolledTooltip>
+        </>
+      )}
+      {page != null && page.path != null && page._id != null && (
+        <div className="grw-pagetree-title-anchor flex-grow-1">
+          <div className="d-flex align-items-center">
+            <span className={`text-truncate me-1 ${page.isEmpty && 'grw-sidebar-text-muted'}`}>{pageName}</span>
+            { page.wip && (
+              <span className="wip-page-badge badge rounded-pill me-1 text-bg-secondary">WIP</span>
+            )}
+          </div>
+        </div>
+      )}
+    </div>
+  );
+};

+ 1 - 1
apps/app/src/components/TreeItem/SimpleItem.module.scss → apps/app/src/components/TreeItem/TreeItemLayout.module.scss

@@ -1,5 +1,5 @@
 // show / hide on hover
-.simple-item {
+.tree-item-layout {
   :global {
     .list-group-item {
       &:hover {

+ 21 - 47
apps/app/src/components/TreeItem/SimpleItem.tsx → apps/app/src/components/TreeItem/TreeItemLayout.tsx

@@ -3,24 +3,19 @@ import React, {
   type FC, type RefObject, type RefCallback, type MouseEvent,
 } from 'react';
 
-import nodePath from 'path';
-
 import type { Nullable } from '@growi/core';
-import { useTranslation } from 'next-i18next';
-import { UncontrolledTooltip } from 'reactstrap';
 
-import type { IPageForItem } from '~/interfaces/page';
 import { useSWRxPageChildren } from '~/stores/page-listing';
 import { usePageTreeDescCountMap } from '~/stores/ui';
-import { shouldRecoverPagePaths } from '~/utils/page-operation';
 
 import { ItemNode } from './ItemNode';
+import { SimpleItemContent } from './SimpleItemContent';
 import type { TreeItemProps, TreeItemToolProps } from './interfaces';
 
 
-import styles from './SimpleItem.module.scss';
+import styles from './TreeItemLayout.module.scss';
 
-const moduleClass = styles['simple-item'] ?? '';
+const moduleClass = styles['tree-item-layout'] ?? '';
 
 
 // Utility to mark target
@@ -41,46 +36,11 @@ const markTarget = (children: ItemNode[], targetPathOrId?: Nullable<string>): vo
 };
 
 
-const SimpleItemContent = ({ page }: { page: IPageForItem }) => {
-  const { t } = useTranslation();
-
-  const pageName = nodePath.basename(page.path ?? '') || '/';
-
-  const shouldShowAttentionIcon = page.processData != null ? shouldRecoverPagePaths(page.processData) : false;
-
-  return (
-    <div
-      className="flex-grow-1 d-flex align-items-center pe-none"
-      style={{ minWidth: 0 }}
-    >
-      {shouldShowAttentionIcon && (
-        <>
-          <span id="path-recovery" className="material-symbols-outlined mr-2 text-warning">warning</span>
-          <UncontrolledTooltip placement="top" target="path-recovery" fade={false}>
-            {t('tooltip.operation.attention.rename')}
-          </UncontrolledTooltip>
-        </>
-      )}
-      {page != null && page.path != null && page._id != null && (
-        <div className="grw-pagetree-title-anchor flex-grow-1">
-          <div className="d-flex align-items-center">
-            <span className={`text-truncate me-1 ${page.isEmpty && 'grw-sidebar-text-muted'}`}>{pageName}</span>
-            { page.wip && (
-              <span className="wip-page-badge badge rounded-pill me-1 text-bg-secondary">WIP</span>
-            )}
-          </div>
-        </div>
-      )}
-    </div>
-  );
-};
-
-
-type SimpleItemProps = TreeItemProps & {
+type TreeItemLayoutProps = TreeItemProps & {
   itemRef?: RefObject<any> | RefCallback<any>,
 }
 
-export const SimpleItem: FC<SimpleItemProps> = (props) => {
+export const TreeItemLayout: FC<TreeItemLayoutProps> = (props) => {
   const {
     itemNode, targetPathOrId, isOpen: _isOpen = false,
     onRenamed, onClick, onClickDuplicateMenuItem, onClickDeleteMenuItem, isEnableActions, isReadOnlyUser, isWipPageShown = true,
@@ -91,6 +51,7 @@ export const SimpleItem: FC<SimpleItemProps> = (props) => {
 
   const [currentChildren, setCurrentChildren] = useState(children);
   const [isOpen, setIsOpen] = useState(_isOpen);
+  const [showAlternativeContent, setShowAlternativeContent] = useState(false);
 
   const { data } = useSWRxPageChildren(isOpen ? page._id : null);
 
@@ -122,6 +83,10 @@ export const SimpleItem: FC<SimpleItemProps> = (props) => {
     setIsOpen(!isOpen);
   }, [isOpen]);
 
+  const onSwitchToAlternativeContent = useCallback(() => {
+    setShowAlternativeContent(!showAlternativeContent);
+  }, [showAlternativeContent]);
+
   // didMount
   useEffect(() => {
     if (hasChildren()) setIsOpen(true);
@@ -148,7 +113,7 @@ export const SimpleItem: FC<SimpleItemProps> = (props) => {
     }
   }, [data, isOpen, targetPathOrId]);
 
-  const ItemClassFixed = itemClass ?? SimpleItem;
+  const ItemClassFixed = itemClass ?? TreeItemLayout;
 
   const baseProps: Omit<TreeItemProps, 'itemNode'> = {
     isEnableActions,
@@ -164,6 +129,7 @@ export const SimpleItem: FC<SimpleItemProps> = (props) => {
   const toolProps: TreeItemToolProps = {
     ...baseProps,
     itemNode,
+    onSwitchToAlternativeContent,
   };
 
   const EndComponents = props.customEndComponents;
@@ -204,7 +170,15 @@ export const SimpleItem: FC<SimpleItemProps> = (props) => {
           )}
         </div>
 
-        <SimpleItemContent page={page} />
+        { showAlternativeContent && AlternativeComponents != null
+          ? (
+            AlternativeComponents.map((AlternativeContent, index) => (
+              // eslint-disable-next-line react/no-array-index-key
+              <AlternativeContent key={index} {...toolProps} />
+            ))
+          )
+          : <SimpleItemContent page={page} />
+        }
 
         <div className="d-hover-none">
           {EndComponents?.map((EndComponent, index) => (

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

@@ -2,5 +2,5 @@ export * from './interfaces';
 
 export * from './NewPageInput';
 export * from './ItemNode';
-export * from './SimpleItem';
+export * from './TreeItemLayout';
 export * from './NotDraggableForClosableTextInput';

+ 3 - 1
apps/app/src/components/TreeItem/interfaces/index.ts

@@ -19,7 +19,9 @@ type TreeItemBaseProps = {
   },
 }
 
-export type TreeItemToolProps = TreeItemBaseProps;
+export type TreeItemToolProps = TreeItemBaseProps & {
+  onSwitchToAlternativeContent?(): void,
+};
 
 export type TreeItemProps = TreeItemBaseProps & {
   targetPathOrId?: Nullable<string>,