From a5145e64f7badbc8116155b3dd26bce207e0e819 Mon Sep 17 00:00:00 2001
From: sealday <sealday@gmail.com>
Date: Sun, 17 Mar 2024 12:28:32 +0800
Subject: [PATCH] refactor: remove page

---
 .../@hera/plugin-core/src/client/index.tsx    |   2 -
 .../schema-components/page/FixedBlock.tsx     | 145 -----------
 .../schema-components/page/Page.Settings.tsx  | 139 -----------
 .../client/schema-components/page/Page.tsx    | 235 ------------------
 .../page/PageTab.Settings.tsx                 |  83 -------
 .../page/PageTabDesigner.tsx                  |  56 -----
 .../page/__tests__/page.test.tsx              |  22 --
 .../schema-components/page/demos/demo1.tsx    |  37 ---
 .../page/hooks/useGetAriaLabelOfDesigner.ts   |  28 ---
 .../useGetAriaLabelOfSchemaInitializer.ts     |  25 --
 .../page/hooks/useIsBlockInPage.ts            |  15 --
 .../client/schema-components/page/index.md    |  11 -
 .../client/schema-components/page/index.ts    |   4 -
 .../client/schema-components/page/style.ts    | 132 ----------
 14 files changed, 934 deletions(-)
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/FixedBlock.tsx
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/Page.Settings.tsx
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/Page.tsx
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/PageTab.Settings.tsx
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/PageTabDesigner.tsx
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/__tests__/page.test.tsx
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/demos/demo1.tsx
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useGetAriaLabelOfDesigner.ts
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useGetAriaLabelOfSchemaInitializer.ts
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useIsBlockInPage.ts
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/index.md
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/index.ts
 delete mode 100644 packages/plugins/@hera/plugin-core/src/client/schema-components/page/style.ts

diff --git a/packages/plugins/@hera/plugin-core/src/client/index.tsx b/packages/plugins/@hera/plugin-core/src/client/index.tsx
index 858d950d6..0ffb5f89b 100644
--- a/packages/plugins/@hera/plugin-core/src/client/index.tsx
+++ b/packages/plugins/@hera/plugin-core/src/client/index.tsx
@@ -39,7 +39,6 @@ import { useOutboundActionProps } from './hooks/useOutboundActionProps';
 import { ExtendedAssociationField } from './schema-components/association-field/Editable';
 import { AssociatedField } from './components/AssociatedField';
 import { DatePicker } from './schema-components/date-picker';
-import { Page } from './schema-components/page';
 import { SettingBlockInitializer } from './schema-initializer/SettingBlockInitializer';
 import {
   EditFormulaTitleField,
@@ -158,7 +157,6 @@ export class PluginCoreClient extends Plugin {
       GroupBlockInitializer,
       GroupBlockToolbar,
       GroupBlockProvider,
-      Page,
       DatePicker,
       RemoteSelect,
       SignatureInput,
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/FixedBlock.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/FixedBlock.tsx
deleted file mode 100644
index ffec81289..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/FixedBlock.tsx
+++ /dev/null
@@ -1,145 +0,0 @@
-import { css } from '@emotion/css';
-import { useField, useFieldSchema } from '@formily/react';
-import React, { useContext, useEffect, useRef, useState } from 'react';
-import { useTranslation } from 'react-i18next';
-import { useRecord, useDesignable, SchemaSettingsSwitchItem } from '@nocobase/client';
-import { useIsBlockInPage } from './hooks/useIsBlockInPage';
-
-const FixedBlockContext = React.createContext<{
-  setFixedBlock: (value: string | false) => void;
-  height: number | string;
-  fixedBlockUID: boolean | string;
-  fixedBlockUIDRef: React.MutableRefObject<boolean | string>;
-  inFixedBlock: boolean;
-}>({
-  setFixedBlock: () => {},
-  height: 0,
-  fixedBlockUID: false,
-  fixedBlockUIDRef: { current: false },
-  inFixedBlock: false,
-});
-
-export const useFixedSchema = () => {
-  const field = useField();
-  const fieldSchema = useFieldSchema();
-  const { setFixedBlock, fixedBlockUID, fixedBlockUIDRef } = useFixedBlock();
-  const hasSet = useRef(false);
-
-  useEffect(() => {
-    if (!fixedBlockUIDRef.current || hasSet.current) {
-      setFixedBlock(field?.decoratorProps?.fixedBlock ? fieldSchema['x-uid'] : false);
-      hasSet.current = true;
-    }
-  }, [field?.decoratorProps?.fixedBlock]);
-
-  return fieldSchema['x-uid'] === fixedBlockUID;
-};
-
-export const useFixedBlock = () => {
-  return useContext(FixedBlockContext);
-};
-
-export const FixedBlockWrapper: React.FC = (props) => {
-  const fixedBlock = useFixedSchema();
-  const { height, fixedBlockUID } = useFixedBlock();
-  const record = useRecord();
-  const isPopup = Object.keys(record).length;
-  if (isPopup) {
-    return <>{props.children}</>;
-  }
-  /**
-   * The fixedBlockUID of false means that the page has no fixed blocks
-   * isPopup means that the FixedBlock is in the popup mode
-   */
-  if (!fixedBlock && fixedBlockUID) return null;
-  return (
-    <div
-      className="nb-fixed-block"
-      style={{
-        height: fixedBlockUID ? `calc(100vh - ${height})` : undefined,
-      }}
-    >
-      {props.children}
-    </div>
-  );
-};
-
-export const FixedBlockDesignerItem = () => {
-  const field = useField();
-  const { t } = useTranslation();
-  const fieldSchema = useFieldSchema();
-  const { dn } = useDesignable();
-  const { inFixedBlock } = useFixedBlock();
-  const { isBlockInPage } = useIsBlockInPage();
-
-  if (!isBlockInPage() || !inFixedBlock) {
-    return null;
-  }
-  return (
-    <SchemaSettingsSwitchItem
-      title={t('Fix block')}
-      checked={fieldSchema['x-decorator-props']?.fixedBlock}
-      onChange={async (fixedBlock) => {
-        const decoratorProps = {
-          ...fieldSchema['x-decorator-props'],
-          fixedBlock,
-        };
-        await dn.emit('patch', {
-          schema: {
-            ['x-uid']: fieldSchema['x-uid'],
-            'x-decorator-props': decoratorProps,
-          },
-        });
-        field.decoratorProps = fieldSchema['x-decorator-props'] = decoratorProps;
-      }}
-    />
-  );
-};
-
-interface FixedBlockProps {
-  height: number | string;
-}
-
-const fixedBlockCss = css`
-  overflow: hidden;
-  position: relative;
-  .noco-card-item {
-    height: 100%;
-    .ant-card {
-      display: flex;
-      flex-direction: column;
-      height: 100%;
-      .ant-card-body {
-        height: 1px;
-        flex: 1;
-        display: flex;
-        flex-direction: column;
-        overflow: hidden;
-      }
-    }
-  }
-`;
-
-const FixedBlock: React.FC<FixedBlockProps> = (props) => {
-  const { height } = props;
-  const [fixedBlockUID, _setFixedBlock] = useState<false | string>(false);
-  const fixedBlockUIDRef = useRef(fixedBlockUID);
-  const setFixedBlock = (v) => {
-    fixedBlockUIDRef.current = v;
-    _setFixedBlock(v);
-  };
-  return (
-    <FixedBlockContext.Provider value={{ inFixedBlock: true, height, setFixedBlock, fixedBlockUID, fixedBlockUIDRef }}>
-      <div
-        className={fixedBlockUID ? fixedBlockCss : ''}
-        style={{
-          height: fixedBlockUID ? `calc(100vh - ${height})` : undefined,
-        }}
-      >
-        {props.children}
-      </div>
-    </FixedBlockContext.Provider>
-  );
-};
-
-export default FixedBlock;
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/Page.Settings.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/Page.Settings.tsx
deleted file mode 100644
index c3effc603..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/Page.Settings.tsx
+++ /dev/null
@@ -1,139 +0,0 @@
-import { useTranslation } from 'react-i18next';
-import { ISchema, useField, useFieldSchema } from '@formily/react';
-import { SchemaSettings, useDesignable, useSchemaToolbar } from '@nocobase/client';
-
-function useNotDisableHeader() {
-  const fieldSchema = useFieldSchema();
-  return !fieldSchema['x-component-props']?.disablePageHeader;
-}
-
-export const pageSettings = new SchemaSettings({
-  name: 'PageSettings',
-  items: [
-    {
-      name: 'enablePageHeader',
-      type: 'switch',
-      useComponentProps() {
-        const { dn } = useDesignable();
-        const { t } = useTranslation();
-        const fieldSchema = useFieldSchema();
-        return {
-          title: t('Enable page header'),
-          checked: !fieldSchema['x-component-props']?.disablePageHeader,
-          onChange(v) {
-            fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
-            fieldSchema['x-component-props']['disablePageHeader'] = !v;
-            dn.emit('patch', {
-              schema: {
-                ['x-uid']: fieldSchema['x-uid'],
-                ['x-component-props']: fieldSchema['x-component-props'],
-              },
-            });
-            dn.refresh();
-          },
-        };
-      },
-    },
-    {
-      name: 'divider',
-      type: 'divider',
-      useVisible: useNotDisableHeader,
-    },
-    {
-      name: 'displayPageTitle',
-      type: 'switch',
-      useVisible: useNotDisableHeader,
-      useComponentProps() {
-        const { dn } = useDesignable();
-        const { t } = useTranslation();
-        const fieldSchema = useFieldSchema();
-        return {
-          title: t('Display page title'),
-          checked: !fieldSchema['x-component-props']?.hidePageTitle,
-          onChange(v) {
-            fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
-            fieldSchema['x-component-props']['hidePageTitle'] = !v;
-            dn.emit('patch', {
-              schema: {
-                ['x-uid']: fieldSchema['x-uid'],
-                ['x-component-props']: fieldSchema['x-component-props'],
-              },
-            });
-            dn.refresh();
-          },
-        };
-      },
-    },
-    {
-      name: 'editPageTitle',
-      type: 'modal',
-      useVisible() {
-        const notDisablePageHeader = useNotDisableHeader();
-        const fieldSchema = useFieldSchema();
-        const notHidePageTitle = !fieldSchema['x-component-props']?.hidePageTitle;
-
-        return notDisablePageHeader && notHidePageTitle;
-      },
-      useComponentProps() {
-        const { dn } = useDesignable();
-        const { t } = useTranslation();
-        const field = useField();
-        const fieldSchema = useFieldSchema();
-        const { title } = useSchemaToolbar();
-        return {
-          hide: true,
-          title: t('Edit page title'),
-          schema: {
-            type: 'object',
-            title: t('Edit page title'),
-            properties: {
-              title: {
-                title: t('Title'),
-                required: true,
-                'x-decorator': 'FormItem',
-                'x-component': 'Input',
-                'x-component-props': {},
-              },
-            },
-          } as ISchema,
-          initialValues: { title },
-          onSubmit({ title }) {
-            field.title = title;
-            fieldSchema['title'] = title;
-            dn.emit('patch', {
-              schema: {
-                ['x-uid']: fieldSchema['x-uid'],
-                title,
-              },
-            });
-          },
-        };
-      },
-    },
-    {
-      name: 'enablePageTabs',
-      type: 'switch',
-      useVisible: useNotDisableHeader,
-      useComponentProps() {
-        const { dn } = useDesignable();
-        const { t } = useTranslation();
-        const fieldSchema = useFieldSchema();
-        return {
-          title: t('Enable page tabs'),
-          checked: fieldSchema['x-component-props']?.enablePageTabs,
-          onChange(v) {
-            fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
-            fieldSchema['x-component-props']['enablePageTabs'] = v;
-            dn.emit('patch', {
-              schema: {
-                ['x-uid']: fieldSchema['x-uid'],
-                ['x-component-props']: fieldSchema['x-component-props'],
-              },
-            });
-            dn.refresh();
-          },
-        };
-      },
-    },
-  ],
-});
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/Page.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/Page.tsx
deleted file mode 100644
index 804718b3c..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/Page.tsx
+++ /dev/null
@@ -1,235 +0,0 @@
-import { PlusOutlined } from '@ant-design/icons';
-import { PageHeader as AntdPageHeader } from '@ant-design/pro-layout';
-import { FormLayout } from '@formily/antd-v5';
-import { Schema, SchemaOptionsContext, useFieldSchema } from '@formily/react';
-import { Button, Tabs } from 'antd';
-import classNames from 'classnames';
-import React, { useContext, useEffect, useMemo, useState } from 'react';
-import { ErrorBoundary } from 'react-error-boundary';
-import { useTranslation } from 'react-i18next';
-import { useSearchParams } from 'react-router-dom';
-import FixedBlock from './FixedBlock';
-import { PageDesigner, PageTabDesigner } from './PageTabDesigner';
-import { useAClStyles, useStyles } from './style';
-import {
-  DndContext,
-  FilterBlockProvider,
-  FormDialog,
-  Icon,
-  SchemaComponent,
-  SchemaComponentOptions,
-  SortableItem,
-  useCompile,
-  useDesignable,
-  useDocumentTitle,
-  useGlobalTheme,
-  useToken,
-} from '@nocobase/client';
-import { useAppSpin } from '../../layouts';
-import { useGetAriaLabelOfSchemaInitializer } from './hooks/useGetAriaLabelOfSchemaInitializer';
-import { ErrorFallback } from '../error-fallback';
-
-export const Page = (props) => {
-  const { children, ...others } = props;
-  const { t } = useTranslation();
-  const compile = useCompile();
-  const { title, setTitle } = useDocumentTitle();
-  const fieldSchema = useFieldSchema();
-  const dn = useDesignable();
-  const { theme } = useGlobalTheme();
-  const { getAriaLabel } = useGetAriaLabelOfSchemaInitializer();
-
-  // react18  tab 动画会卡顿,所以第一个 tab 时,动画禁用,后面的 tab 才启用
-  const [hasMounted, setHasMounted] = useState(false);
-  useEffect(() => {
-    setTimeout(() => {
-      setHasMounted(true);
-    });
-  }, []);
-
-  useEffect(() => {
-    if (!title) {
-      setTitle(t(fieldSchema.title));
-    }
-  }, [fieldSchema.title, title]);
-  const disablePageHeader = fieldSchema['x-component-props']?.disablePageHeader;
-  const enablePageTabs = fieldSchema['x-component-props']?.enablePageTabs;
-  const hidePageTitle = fieldSchema['x-component-props']?.hidePageTitle;
-  const options = useContext(SchemaOptionsContext);
-  const [searchParams, setSearchParams] = useSearchParams();
-  const [loading, setLoading] = useState(false);
-  const activeKey = useMemo(
-    () => searchParams.get('tab') || Object.keys(fieldSchema.properties || {}).shift(),
-    [fieldSchema.properties, searchParams],
-  );
-  const [height, setHeight] = useState(0);
-  const { wrapSSR, hashId, componentCls } = useStyles();
-  const aclStyles = useAClStyles();
-
-  const handleErrors = (error) => {
-    console.error(error);
-  };
-
-  const pageHeaderTitle = hidePageTitle ? undefined : fieldSchema.title || compile(title);
-  return wrapSSR(
-    <FilterBlockProvider>
-      <div className={`${componentCls} ${hashId} ${aclStyles.styles}`}>
-        <PageDesigner title={fieldSchema.title || title} />
-        <div
-          ref={(ref) => {
-            setHeight(Math.floor(ref?.getBoundingClientRect().height || 0) + 1);
-          }}
-        >
-          {!disablePageHeader && (
-            <AntdPageHeader
-              className={classNames('pageHeaderCss', pageHeaderTitle || enablePageTabs ? '' : 'height0')}
-              ghost={false}
-              // 如果标题为空的时候会导致 PageHeader 不渲染,所以这里设置一个空白字符,然后再设置高度为 0
-              title={pageHeaderTitle || ' '}
-              {...others}
-              footer={
-                enablePageTabs && (
-                  <DndContext>
-                    <Tabs
-                      size={'small'}
-                      animated={hasMounted}
-                      activeKey={activeKey}
-                      onTabClick={(activeKey) => {
-                        setLoading(true);
-                        setSearchParams([['tab', activeKey]]);
-                        setTimeout(() => {
-                          setLoading(false);
-                        }, 50);
-                      }}
-                      tabBarExtraContent={
-                        dn.designable && (
-                          <Button
-                            aria-label={getAriaLabel('tabs')}
-                            icon={<PlusOutlined />}
-                            className={'addTabBtn'}
-                            type={'dashed'}
-                            onClick={async () => {
-                              const values = await FormDialog(
-                                t('Add tab'),
-                                () => {
-                                  return (
-                                    <SchemaComponentOptions
-                                      scope={options.scope}
-                                      components={{ ...options.components }}
-                                    >
-                                      <FormLayout layout={'vertical'}>
-                                        <SchemaComponent
-                                          schema={{
-                                            properties: {
-                                              title: {
-                                                title: t('Tab name'),
-                                                'x-component': 'Input',
-                                                'x-decorator': 'FormItem',
-                                                required: true,
-                                              },
-                                              icon: {
-                                                title: t('Icon'),
-                                                'x-component': 'IconPicker',
-                                                'x-decorator': 'FormItem',
-                                              },
-                                            },
-                                          }}
-                                        />
-                                      </FormLayout>
-                                    </SchemaComponentOptions>
-                                  );
-                                },
-                                theme,
-                              ).open({
-                                initialValues: {},
-                              });
-                              const { title, icon } = values;
-                              dn.insertBeforeEnd({
-                                type: 'void',
-                                title,
-                                'x-icon': icon,
-                                'x-component': 'Grid',
-                                'x-initializer': 'BlockInitializers',
-                                properties: {},
-                              });
-                            }}
-                          >
-                            {t('Add tab')}
-                          </Button>
-                        )
-                      }
-                      items={fieldSchema.mapProperties((schema) => {
-                        return {
-                          label: (
-                            <SortableItem
-                              id={schema.name as string}
-                              schema={schema}
-                              className={classNames('nb-action-link', 'designerCss', props.className)}
-                            >
-                              {schema['x-icon'] && <Icon style={{ marginRight: 8 }} type={schema['x-icon']} />}
-                              <span>{schema.title || t('Unnamed')}</span>
-                              <PageTabDesigner schema={schema} />
-                            </SortableItem>
-                          ),
-                          key: schema.name as string,
-                        };
-                      })}
-                    />
-                  </DndContext>
-                )
-              }
-            />
-          )}
-        </div>
-        <div className="nb-page-wrapper">
-          <ErrorBoundary FallbackComponent={ErrorFallback} onError={handleErrors}>
-            {PageContent(loading, disablePageHeader, enablePageTabs, fieldSchema, activeKey, height, props)}
-          </ErrorBoundary>
-        </div>
-      </div>
-    </FilterBlockProvider>,
-  );
-};
-
-Page.displayName = 'Page';
-
-function PageContent(
-  loading: boolean,
-  disablePageHeader: any,
-  enablePageTabs: any,
-  fieldSchema: Schema<any, any, any, any, any, any, any, any, any>,
-  activeKey: string,
-  height: number,
-  props: any,
-): React.ReactNode {
-  const { token } = useToken();
-  const { render } = useAppSpin();
-
-  if (loading) {
-    return render();
-  }
-
-  return !disablePageHeader && enablePageTabs ? (
-    fieldSchema.mapProperties((schema) => {
-      if (schema.name !== activeKey) return null;
-
-      return (
-        <FixedBlock key={schema.name} height={`calc(${height}px + 46px + ${token.marginLG}px * 2)`}>
-          <SchemaComponent
-            schema={
-              new Schema({
-                properties: {
-                  [schema.name]: schema,
-                },
-              })
-            }
-          />
-        </FixedBlock>
-      );
-    })
-  ) : (
-    <FixedBlock height={`calc(${height}px + 46px + ${token.marginLG}px * 2)`}>
-      <div className={`pageWithFixedBlockCss nb-page-content`}>{props.children}</div>
-    </FixedBlock>
-  );
-}
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/PageTab.Settings.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/PageTab.Settings.tsx
deleted file mode 100644
index 3fb36244a..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/PageTab.Settings.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import { App } from 'antd';
-import { useTranslation } from 'react-i18next';
-import { ISchema } from '@formily/json-schema';
-import { useDesignable, useSchemaToolbar, SchemaSettings } from '@nocobase/client';
-
-export const pageTabSettings = new SchemaSettings({
-  name: 'PageTabSettings',
-  items: [
-    {
-      name: 'edit',
-      type: 'modal',
-      useComponentProps() {
-        const { t } = useTranslation();
-        const { schema } = useSchemaToolbar<{ schema: ISchema }>();
-        const { dn } = useDesignable();
-        return {
-          title: t('Edit'),
-          schema: {
-            type: 'object',
-            title: t('Edit tab'),
-            properties: {
-              title: {
-                title: t('Tab name'),
-                required: true,
-                'x-decorator': 'FormItem',
-                'x-component': 'Input',
-                'x-component-props': {},
-              },
-              icon: {
-                title: t('Icon'),
-                'x-decorator': 'FormItem',
-                'x-component': 'IconPicker',
-                'x-component-props': {},
-              },
-            },
-          } as ISchema,
-          initialValues: { title: schema.title, icon: schema['x-icon'] },
-          onSubmit: ({ title, icon }) => {
-            schema.title = title;
-            schema['x-icon'] = icon;
-            dn.emit('patch', {
-              schema: {
-                ['x-uid']: schema['x-uid'],
-                title,
-                'x-icon': icon,
-              },
-            });
-            dn.refresh();
-          },
-        };
-      },
-    },
-    {
-      name: 'divider',
-      type: 'divider',
-    },
-    {
-      name: 'delete',
-      type: 'item',
-      useComponentProps() {
-        const { modal } = App.useApp();
-        const { dn } = useDesignable();
-        const { t } = useTranslation();
-        const { schema } = useSchemaToolbar();
-        return {
-          title: 'Delete',
-          eventKey: 'remove',
-          onClick() {
-            modal.confirm({
-              title: t('Delete block'),
-              content: t('Are you sure you want to delete it?'),
-              ...confirm,
-              onOk() {
-                dn.remove(schema);
-              },
-            });
-          },
-          children: t('Delete'),
-        };
-      },
-    },
-  ],
-});
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/PageTabDesigner.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/PageTabDesigner.tsx
deleted file mode 100644
index bf9319880..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/PageTabDesigner.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { DragOutlined } from '@ant-design/icons';
-import { useFieldSchema } from '@formily/react';
-import { DragHandler, SchemaToolbarProvider, useDesignable, useSchemaSettingsRender } from '@nocobase/client';
-import { Space } from 'antd';
-import React from 'react';
-import { useGetAriaLabelOfDesigner } from './hooks/useGetAriaLabelOfDesigner';
-
-export const PageDesigner = ({ title }) => {
-  const { designable } = useDesignable();
-  const fieldSchema = useFieldSchema();
-  const { render } = useSchemaSettingsRender(
-    fieldSchema['x-settings'] || 'PageSettings',
-    fieldSchema['x-settings-props'],
-  );
-  if (!designable) {
-    return null;
-  }
-  return (
-    <SchemaToolbarProvider title={title}>
-      <div className={'general-schema-designer'}>
-        <div className={'general-schema-designer-icons'}>
-          <Space size={2} align={'center'}>
-            {render()}
-          </Space>
-        </div>
-      </div>
-    </SchemaToolbarProvider>
-  );
-};
-
-export const PageTabDesigner = ({ schema }) => {
-  const { designable } = useDesignable();
-  const { getAriaLabel } = useGetAriaLabelOfDesigner();
-  const fieldSchema = useFieldSchema();
-  const { render } = useSchemaSettingsRender(
-    fieldSchema['x-settings'] || 'PageTabSettings',
-    fieldSchema['x-settings-props'],
-  );
-  if (!designable) {
-    return null;
-  }
-  return (
-    <SchemaToolbarProvider schema={schema}>
-      <div className={'general-schema-designer'}>
-        <div className={'general-schema-designer-icons'}>
-          <Space size={3} align={'center'}>
-            <DragHandler>
-              <DragOutlined style={{ marginRight: 0 }} role="button" aria-label={getAriaLabel('drag-handler', 'tab')} />
-            </DragHandler>
-            {render()}
-          </Space>
-        </div>
-      </div>
-    </SchemaToolbarProvider>
-  );
-};
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/__tests__/page.test.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/__tests__/page.test.tsx
deleted file mode 100644
index 3398ac0da..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/__tests__/page.test.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import React from 'react';
-import { render, screen, waitFor } from 'testUtils';
-import App1 from '../demos/demo1';
-import { GlobalThemeProvider } from '@nocobase/client';
-
-describe('Page', () => {
-  it('should render correctly', async () => {
-    render(<App1 />, {
-      wrapper: GlobalThemeProvider,
-    });
-
-    await waitFor(() => {
-      expect(screen.getByText(/page title/i)).toBeInTheDocument();
-    });
-    await waitFor(() => {
-      expect(screen.getByText(/page content/i)).toBeInTheDocument();
-    });
-    await waitFor(() => {
-      expect(document.title).toBe('Page Title - NocoBase');
-    });
-  });
-});
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/demos/demo1.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/demos/demo1.tsx
deleted file mode 100644
index 4ed02b45c..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/demos/demo1.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { ISchema } from '@formily/react';
-import { DocumentTitleProvider, Page, SchemaComponent, SchemaComponentProvider, Application } from '@nocobase/client';
-import React from 'react';
-
-const schema: ISchema = {
-  type: 'object',
-  properties: {
-    page1: {
-      type: 'void',
-      'x-component': 'Page',
-      title: 'Page Title',
-      properties: {
-        content: {
-          type: 'void',
-          'x-component': 'div',
-          'x-content': 'Page Content',
-        },
-      },
-    },
-  },
-};
-
-const Root = () => {
-  return (
-    <SchemaComponentProvider components={{ Page }}>
-      <DocumentTitleProvider addonAfter={'NocoBase'}>
-        <SchemaComponent schema={schema} />
-      </DocumentTitleProvider>
-    </SchemaComponentProvider>
-  );
-};
-
-const app = new Application({
-  providers: [Root],
-});
-
-export default app.getRootComponent();
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useGetAriaLabelOfDesigner.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useGetAriaLabelOfDesigner.ts
deleted file mode 100644
index 13494aab4..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useGetAriaLabelOfDesigner.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { useFieldSchema } from '@formily/react';
-import { useCollection_deprecated } from '@nocobase/client';
-import { useCallback } from 'react';
-
-/**
- * label = 'designer' + name + x-component + [x-designer] + [collectionName] + [x-collection-field] + [postfix]
- * @returns
- */
-export const useGetAriaLabelOfDesigner = () => {
-  const fieldSchema = useFieldSchema();
-  const { name: _collectionName } = useCollection_deprecated();
-  const getAriaLabel = useCallback(
-    (name: string, postfix?: string) => {
-      if (!fieldSchema) return '';
-
-      const component = fieldSchema['x-component'];
-      const designer = fieldSchema['x-designer'] ? `-${fieldSchema['x-designer']}` : '';
-      const collectionField = fieldSchema['x-collection-field'] ? `-${fieldSchema['x-collection-field']}` : '';
-      const collectionName = _collectionName ? `-${_collectionName}` : '';
-      postfix = postfix ? `-${postfix}` : '';
-
-      return `designer-${name}-${component}${designer}${collectionName}${collectionField}${postfix}`;
-    },
-    [fieldSchema, _collectionName],
-  );
-
-  return { getAriaLabel };
-};
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useGetAriaLabelOfSchemaInitializer.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useGetAriaLabelOfSchemaInitializer.ts
deleted file mode 100644
index f6b72f313..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useGetAriaLabelOfSchemaInitializer.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useFieldSchema } from '@formily/react';
-import { useCollection_deprecated } from '@nocobase/client';
-import { useCallback } from 'react';
-
-/**
- * label = 'schema-initializer' + x-component + [x-initializer] + [collectionName] + [postfix]
- * @returns
- */
-export const useGetAriaLabelOfSchemaInitializer = () => {
-  const fieldSchema = useFieldSchema();
-  const { name } = useCollection_deprecated();
-  const getAriaLabel = useCallback(
-    (postfix?: string) => {
-      if (!fieldSchema) return '';
-      const initializer = fieldSchema['x-initializer'] ? `-${fieldSchema['x-initializer']}` : '';
-      const collectionName = name ? `-${name}` : '';
-      postfix = postfix ? `-${postfix}` : '';
-
-      return `schema-initializer-${fieldSchema['x-component']}${initializer}${collectionName}${postfix}`;
-    },
-    [fieldSchema, name],
-  );
-
-  return { getAriaLabel };
-};
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useIsBlockInPage.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useIsBlockInPage.ts
deleted file mode 100644
index 7fe7b535f..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/hooks/useIsBlockInPage.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { useActionContext } from '@nocobase/client';
-import { useCallback } from 'react';
-
-/**
- * 判断当前区块是否在页面而不是在弹窗中
- */
-export const useIsBlockInPage = () => {
-  const { visible } = useActionContext();
-
-  const isBlockInPage = useCallback(() => {
-    return !visible;
-  }, [visible]);
-
-  return { isBlockInPage };
-};
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/index.md b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/index.md
deleted file mode 100644
index 163876dd8..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/index.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-group:
-  title: Schema Components
-  order: 3
----
-
-# Page
-
-可以与 DocumentTitleProvider 搭配使用,将 page title 显示在 document.title 上。
-
-<code src="./demos/demo1.tsx"></code>
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/index.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/index.ts
deleted file mode 100644
index ef348690f..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from './Page';
-export * from './FixedBlock';
-export * from './PageTab.Settings';
-export * from './Page.Settings';
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/style.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/page/style.ts
deleted file mode 100644
index 7c821136c..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/page/style.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-import { createStyles } from 'antd-style';
-import { genStyleHook } from '../__builtins__';
-
-export const useAClStyles = createStyles(({ css }) => {
-  return css`
-    .ant-table-cell {
-      > .ant-space-horizontal {
-        .ant-space-item-split:has(+ .ant-space-item:empty) {
-          display: none;
-        }
-      }
-    }
-  `;
-});
-
-export const useStyles = genStyleHook('nb-page', (token) => {
-  const { componentCls } = token;
-
-  return {
-    [componentCls]: {
-      position: 'relative',
-      zIndex: 20,
-      flex: 1,
-      display: 'flex',
-      flexDirection: 'column',
-      '&:hover': { '> .general-schema-designer': { display: 'block' } },
-      '.ant-page-header': { zIndex: 1, position: 'relative' },
-      '> .general-schema-designer': {
-        position: 'absolute',
-        zIndex: 999,
-        top: '0',
-        bottom: '0',
-        left: '0',
-        right: '0',
-        display: 'none',
-        border: '0',
-        pointerEvents: 'none',
-        '> .general-schema-designer-icons': {
-          zIndex: 9999,
-          position: 'absolute',
-          right: '2px',
-          top: '2px',
-          lineHeight: '16px',
-          pointerEvents: 'all',
-          '.ant-space-item': {
-            backgroundColor: 'var(--colorSettings)',
-            color: '#fff',
-            lineHeight: '16px',
-            width: '16px',
-            paddingLeft: '1px',
-          },
-        },
-      },
-
-      '.pageHeaderCss': {
-        backgroundColor: token.colorBgContainer,
-        paddingInline: token.paddingLG,
-        '&.ant-page-header-has-footer': {
-          paddingTop: token.paddingSM,
-          paddingBottom: '0',
-          '.ant-page-header-heading-left': {},
-          '.ant-page-header-footer': { marginBlockStart: '0' },
-        },
-        '.ant-tabs-nav': { marginBottom: '0' },
-        '.ant-page-header-heading-title': {
-          color: token.colorText,
-        },
-      },
-
-      '.height0': {
-        fontSize: 0,
-        height: 0,
-      },
-
-      '.addTabBtn': {
-        borderColor: 'var(--colorSettings)',
-        color: 'var(--colorSettings)',
-      },
-
-      '.designerCss': {
-        position: 'relative',
-        '&:hover': { '> .general-schema-designer': { display: 'block' } },
-        '&.nb-action-link': {
-          '> .general-schema-designer': {
-            top: '-10px',
-            bottom: '-10px',
-            left: '-10px',
-            right: '-10px',
-          },
-        },
-        '> .general-schema-designer': {
-          position: 'absolute',
-          zIndex: 999,
-          top: '0',
-          bottom: '0',
-          left: '0',
-          right: '0',
-          display: 'none',
-          background: 'var(--colorBgSettingsHover)',
-          border: '0',
-          pointerEvents: 'none',
-          '> .general-schema-designer-icons': {
-            position: 'absolute',
-            right: '2px',
-            top: '2px',
-            lineHeight: '16px',
-            pointerEvents: 'all',
-            '.ant-space-item': {
-              backgroundColor: 'var(--colorSettings)',
-              color: '#fff',
-              lineHeight: '16px',
-              width: '16px',
-              paddingLeft: '1px',
-            },
-          },
-        },
-      },
-
-      '.pageWithFixedBlockCss': {
-        height: '100%',
-        '> .nb-grid:not(:last-child)': {
-          '> .nb-schema-initializer-button': { display: 'none' },
-        },
-      },
-
-      '.nb-page-wrapper': {
-        margin: token.marginLG,
-        flex: 1,
-      },
-    },
-  };
-});