diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/ErrorFallback.tsx b/packages/core/client/src/schema-component/antd/error-fallback/ErrorFallback2.tsx similarity index 75% rename from packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/ErrorFallback.tsx rename to packages/core/client/src/schema-component/antd/error-fallback/ErrorFallback2.tsx index 995d6e843..56b32accc 100644 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/ErrorFallback.tsx +++ b/packages/core/client/src/schema-component/antd/error-fallback/ErrorFallback2.tsx @@ -11,8 +11,8 @@ export const ErrorFallback: FC = ({ error }) => { const subTitle = ( - {'This is likely a NocoBase internals bug. Please open an issue at '} - + {'This is likely a TachyCode internals bug. Please open an issue at '} + here @@ -26,7 +26,12 @@ export const ErrorFallback: FC = ({ error }) => { title={t('Render Failed')} subTitle={subTitle} extra={[ - , - - } - > - - - ); -}; diff --git a/packages/plugins/@hera/plugin-core/src/client/components/CustomAssociatedField.tsx b/packages/plugins/@hera/plugin-core/src/client/components/custom-components/CustomAssociatedField.tsx similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/components/CustomAssociatedField.tsx rename to packages/plugins/@hera/plugin-core/src/client/components/custom-components/CustomAssociatedField.tsx diff --git a/packages/plugins/@hera/plugin-core/src/client/components/CustomComponentDispatcher.tsx b/packages/plugins/@hera/plugin-core/src/client/components/custom-components/CustomComponentDispatcher.tsx similarity index 92% rename from packages/plugins/@hera/plugin-core/src/client/components/CustomComponentDispatcher.tsx rename to packages/plugins/@hera/plugin-core/src/client/components/custom-components/CustomComponentDispatcher.tsx index eb4214c2a..e2c212c6f 100644 --- a/packages/plugins/@hera/plugin-core/src/client/components/CustomComponentDispatcher.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/components/custom-components/CustomComponentDispatcher.tsx @@ -1,10 +1,10 @@ import { SchemaComponent, SchemaSettings, useApp, useDesignable, usePlugin } from '@nocobase/client'; import React from 'react'; -import { useTranslation } from '../locale'; +import { useTranslation } from '../../locale'; import { useField, useFieldSchema } from '@formily/react'; import { Field } from '@nocobase/database'; -import { useCustomComponent } from '../hooks/useCustomComponent'; -import { CustomComponentType } from '../custom-components'; +import { useCustomComponent } from '../../hooks/useCustomComponent'; +import { CustomComponentType } from './custom-components'; export const CustomComponentStub = (props) => { return
请选择组件
; diff --git a/packages/plugins/@hera/plugin-core/src/client/components/CustomField.tsx b/packages/plugins/@hera/plugin-core/src/client/components/custom-components/CustomField.tsx similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/components/CustomField.tsx rename to packages/plugins/@hera/plugin-core/src/client/components/custom-components/CustomField.tsx diff --git a/packages/plugins/@hera/plugin-core/src/client/custom-components.ts b/packages/plugins/@hera/plugin-core/src/client/components/custom-components/custom-components.ts similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/custom-components.ts rename to packages/plugins/@hera/plugin-core/src/client/components/custom-components/custom-components.ts diff --git a/packages/plugins/@hera/plugin-core/src/client/components/AssociatedField.tsx b/packages/plugins/@hera/plugin-core/src/client/components/fields/AssociatedField.tsx similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/components/AssociatedField.tsx rename to packages/plugins/@hera/plugin-core/src/client/components/fields/AssociatedField.tsx diff --git a/packages/plugins/@hera/plugin-core/src/client/components/CalcResult.tsx b/packages/plugins/@hera/plugin-core/src/client/components/fields/CalcResult.tsx similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/components/CalcResult.tsx rename to packages/plugins/@hera/plugin-core/src/client/components/fields/CalcResult.tsx diff --git a/packages/plugins/@hera/plugin-core/src/client/components/Expression.tsx b/packages/plugins/@hera/plugin-core/src/client/components/fields/Expression.tsx similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/components/Expression.tsx rename to packages/plugins/@hera/plugin-core/src/client/components/fields/Expression.tsx diff --git a/packages/plugins/@hera/plugin-core/src/client/components/MobileLink.tsx b/packages/plugins/@hera/plugin-core/src/client/components/system/MobileLink.tsx similarity index 94% rename from packages/plugins/@hera/plugin-core/src/client/components/MobileLink.tsx rename to packages/plugins/@hera/plugin-core/src/client/components/system/MobileLink.tsx index f20fe8fc1..0b777d06a 100644 --- a/packages/plugins/@hera/plugin-core/src/client/components/MobileLink.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/components/system/MobileLink.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { css } from '@nocobase/client'; import { Button, Tooltip } from 'antd'; import { MobileOutlined } from '@ant-design/icons'; -import { useTranslation } from '../locale'; +import { useTranslation } from '../../locale'; export const MobileLink = () => { const { t } = useTranslation(); diff --git a/packages/plugins/@hera/plugin-core/src/client/components/Notifications.tsx b/packages/plugins/@hera/plugin-core/src/client/components/system/Notifications.tsx similarity index 96% rename from packages/plugins/@hera/plugin-core/src/client/components/Notifications.tsx rename to packages/plugins/@hera/plugin-core/src/client/components/system/Notifications.tsx index 071321c87..5c9c94ebe 100644 --- a/packages/plugins/@hera/plugin-core/src/client/components/Notifications.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/components/system/Notifications.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { css, useRequest } from '@nocobase/client'; import { Badge, Button, Popover, List, message } from 'antd'; import { BellOutlined } from '@ant-design/icons'; -import { useLinkKey, useInitializationLinkKey } from '../hooks/useNotifications'; +import { useLinkKey, useInitializationLinkKey } from '../../hooks/useNotifications'; import { useNavigate } from 'react-router-dom'; import { dayjs } from '@nocobase/utils/client'; diff --git a/packages/plugins/@hera/plugin-core/src/client/components/OnlineUserProvider.tsx b/packages/plugins/@hera/plugin-core/src/client/components/system/OnlineUserProvider.tsx similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/components/OnlineUserProvider.tsx rename to packages/plugins/@hera/plugin-core/src/client/components/system/OnlineUserProvider.tsx diff --git a/packages/plugins/@hera/plugin-core/src/client/index.tsx b/packages/plugins/@hera/plugin-core/src/client/index.tsx index 94216ab1e..40a7fdf98 100644 --- a/packages/plugins/@hera/plugin-core/src/client/index.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/index.tsx @@ -8,16 +8,9 @@ import { SchemaSettingOptions, useCollection, } from '@nocobase/client'; -import { HeraAdminLayout } from './layouts'; import { remove } from 'lodash'; import { CalendarBlockInitializer } from './schema-initializer/CalendarBlockInitializer'; -import { MenuDesigner } from './components/ExtendedMenuDesigner'; -import { SessionSubmit, SessionUpdate } from './components/ExtendedActionDesigner'; -import { DetailsPage } from './pages/DetailsPage'; -import { OutboundPage } from './pages/OutboundPage'; -import { HomePageConfiguration } from './pages/HomePageConfiguration'; -import { Configuration } from './components/TokenConfiguration'; -import { HomePage } from './pages/Home'; +import { MenuDesigner } from './schema-components/deprecated/ExtendedMenuDesigner'; import { InternalPDFViewer } from './schema-components/PDFViewer'; import { PDFViewerBlockInitializer, @@ -26,21 +19,20 @@ import { pdfViewActionInitializer, usePDFViewerPrintActionProps, } from './schema-initializer/PDFVIewerBlockInitializer'; -import { OutboundButton } from './components/OutboundButton'; import { useCustomizeUpdateActionProps } from './hooks/useCustomizeUpdateActionProps'; -import { OutboundLinkActionInitializer } from './schema-initializer/OutboundLinkActionInitializer'; +import { OutboundButton, OutboundLinkActionInitializer } from './schema-initializer/OutboundLinkActionInitializer'; import { CreateSubmitActionInitializer } from './schema-initializer/CreateSubmitActionInitializer'; import { FilterAssociatedFields } from './schema-initializer/FilterAssociatedFields'; import { useFieldSchema } from '@formily/react'; import { isValid } from '@formily/shared'; import { useCreateActionProps } from './hooks/useCreateActionProps'; -import { PageLayout } from './pages/PageLayout'; import { useOutboundActionProps } from './hooks/useOutboundActionProps'; 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 { + SessionSubmit, + SessionUpdate, EditFormulaTitleField, IsTablePageSize, useFormulaTitleVisible, @@ -48,12 +40,12 @@ import { EditTitle, SetFilterScope, useSetFilterScopeVisible, -} from './components/SchemaSettingOptions'; + AfterSuccess, +} from './schema-settings'; import { SignatureInput } from './components/SignatureInput'; import { RemoteSelect } from './schema-components/remote-select'; import { Select } from './schema-components/select/Select'; import { Locale, tval } from './locale'; -import { LinkManager } from './components/LinkManager'; import { GroupBlockInitializer, GroupBlockProvider, @@ -71,24 +63,25 @@ import { CustomComponentDispatcher, CustomComponentStub, customComponentDispatcherSettings, -} from './components/CustomComponentDispatcher'; +} from './components/custom-components/CustomComponentDispatcher'; import { useFilterBlockActionProps } from './hooks/useFilterBlockActionProps'; -import { AfterSuccess } from './components/Action.Designer'; import { GroupBlockConfigure } from './components/GroupBlockConfigure/GroupBlockConfigure'; import { AssociatedFieldInterface } from './interfaces/associated'; import { CalcFieldInterface } from './interfaces/calc'; import { CustomFieldInterface } from './interfaces/custom'; import { CustomAssociatedFieldInterface } from './interfaces/customAssociated'; import { SignaturePadFieldInterface } from './interfaces/signatureSchema'; -import { CalcResult } from './components/CalcResult'; -import { CustomAssociatedField } from './components/CustomAssociatedField'; +import { CalcResult } from './components/fields/CalcResult'; +import { CustomAssociatedField } from './components/custom-components/CustomAssociatedField'; import Expression from './components/Expression'; -import { CustomField } from './components/CustomField'; +import { CustomField } from './components/custom-components/CustomField'; import { useGetCustomAssociatedComponents } from './hooks/useGetCustomAssociatedComponents'; import { useGetCustomComponents } from './hooks/useGetCustomComponents'; import { AutoComplete } from './schema-components/AutoComplete/AutoComplete'; +import { AdminLayout, DetailsPage, HomePage, OutboundPage, PageLayout } from './pages'; +import { Configuration, HomePageConfiguration, LinkManager } from './settings-manager-components'; export { usePDFViewerRef } from './schema-initializer/PDFVIewerBlockInitializer'; -export * from './custom-components'; +export * from './components/custom-components/custom-components'; export class PluginCoreClient extends Plugin { locale: Locale; @@ -157,7 +150,6 @@ export class PluginCoreClient extends Plugin { GroupBlockInitializer, GroupBlockToolbar, GroupBlockProvider, - Page, DatePicker, RemoteSelect, SignatureInput, @@ -165,7 +157,7 @@ export class PluginCoreClient extends Plugin { OutboundLinkActionInitializer, PDFViewerBlockInitializer, PDFViwer: InternalPDFViewer, - AdminLayout: HeraAdminLayout, + AdminLayout, ExtendedCalendarBlockInitializer: CalendarBlockInitializer, SettingBlock: SettingBlockInitializer, CreateSubmitActionInitializer, diff --git a/packages/plugins/@hera/plugin-core/src/client/layouts/index.tsx b/packages/plugins/@hera/plugin-core/src/client/pages/AdminLayout.tsx similarity index 98% rename from packages/plugins/@hera/plugin-core/src/client/layouts/index.tsx rename to packages/plugins/@hera/plugin-core/src/client/pages/AdminLayout.tsx index c0954df59..e2337d16b 100644 --- a/packages/plugins/@hera/plugin-core/src/client/layouts/index.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/pages/AdminLayout.tsx @@ -26,9 +26,9 @@ import { import { Tabs } from 'antd'; import type { TabsProps } from 'antd'; import { usePluginVersion } from '../hooks/usePluginVersion'; -import { OnlineUserDropdown } from '../components/OnlineUserProvider'; -import { MobileLink } from '../components/MobileLink'; -import { Notifications } from '../components/Notifications'; +import { OnlineUserDropdown } from '../components/system/OnlineUserProvider'; +import { MobileLink } from '../components/system/MobileLink'; +import { Notifications } from '../components/system/Notifications'; import { useTranslation } from '../locale'; export const useAppSpin = () => { @@ -451,7 +451,7 @@ const usePageStyle = () => { return useContext(PageStyleContext).style; }; -export const HeraAdminLayout = (props) => { +export const AdminLayout = (props) => { const { addMenuItem } = useCurrentUserSettingsMenu(); const [style, setStyle] = useState('classical'); const tabItem = useTabSettings({ style, setStyle }); diff --git a/packages/plugins/@hera/plugin-core/src/client/pages/DetailsPage.tsx b/packages/plugins/@hera/plugin-core/src/client/pages/DetailsPage.tsx index e1f5c9baf..3d90eb8d2 100644 --- a/packages/plugins/@hera/plugin-core/src/client/pages/DetailsPage.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/pages/DetailsPage.tsx @@ -8,7 +8,7 @@ import { } from '@nocobase/client'; import { useNavigate, useParams } from 'react-router-dom'; import pathToRegexp from 'path-to-regexp'; -import { useHeadStyles } from '../pages/style'; +import { useHeadStyles } from './style'; import { PageHeader as AntdPageHeader } from '@ant-design/pro-layout'; export const DetailsPage: React.FC = () => { diff --git a/packages/plugins/@hera/plugin-core/src/client/pages/Home.tsx b/packages/plugins/@hera/plugin-core/src/client/pages/Home.tsx index 07d7f1073..501292dfc 100644 --- a/packages/plugins/@hera/plugin-core/src/client/pages/Home.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/pages/Home.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { useStyles } from './style'; import { Carousel, Image } from 'antd'; import { useRequest } from '@nocobase/client'; -import { useAppSpin } from '../layouts'; +import { useAppSpin } from './AdminLayout'; export const HomePage: React.FC<{}> = () => { const { styles } = useStyles(); diff --git a/packages/plugins/@hera/plugin-core/src/client/pages/index.ts b/packages/plugins/@hera/plugin-core/src/client/pages/index.ts new file mode 100644 index 000000000..82bd00c35 --- /dev/null +++ b/packages/plugins/@hera/plugin-core/src/client/pages/index.ts @@ -0,0 +1,5 @@ +export * from './AdminLayout'; +export * from './DetailsPage'; +export * from './Home'; +export * from './OutboundPage'; +export * from './PageLayout'; diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/index.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/index.ts deleted file mode 100644 index 4d423984a..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './useConfig'; -export * from './usePrefixCls'; -export * from './useToken'; diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/useConfig.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/useConfig.ts deleted file mode 100644 index b9d05bd59..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/useConfig.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ConfigProvider } from 'antd'; -import { useContext } from 'react'; - -const { ConfigContext } = ConfigProvider; -export const useConfig = () => useContext(ConfigContext); diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/usePrefixCls.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/usePrefixCls.ts deleted file mode 100644 index ca782364c..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/usePrefixCls.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ConfigProvider } from 'antd'; -import { useContext } from 'react'; - -export const usePrefixCls = ( - tag?: string, - props?: { - prefixCls?: string; - }, -) => { - const { getPrefixCls } = useContext(ConfigProvider.ConfigContext) || {}; - if ('ConfigContext' in ConfigProvider) { - return getPrefixCls?.(tag, props?.prefixCls) || ''; - } else { - const prefix = props?.prefixCls ?? 'ant-'; - return `${prefix}${tag ?? ''}`; - } -}; diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/useToken.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/useToken.ts deleted file mode 100644 index f4ff65445..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/hooks/useToken.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { theme } from 'antd'; -import { CustomToken } from '../style'; - -interface Result extends ReturnType { - token: CustomToken; -} - -const useToken = () => { - const result = theme.useToken(); - return result as Result; -}; - -export { useToken }; diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/index.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/index.ts deleted file mode 100644 index d76631860..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './hooks'; -export * from './loading'; -export * from './portal'; -export * from './style'; diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/loading.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/loading.ts deleted file mode 100644 index 3746651f0..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/loading.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { message } from 'antd'; - -export const loading = async (title: React.ReactNode = 'Loading...', processor: () => Promise) => { - let hide: any = null; - const loading = setTimeout(() => { - hide = message.loading(title); - }, 100); - try { - return await processor(); - } finally { - hide?.(); - clearTimeout(loading); - } -}; diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/portal.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/portal.tsx deleted file mode 100644 index fb060dcbd..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/portal.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { Observer, ReactFC } from '@formily/react'; -import { observable } from '@formily/reactive'; -import React, { Fragment } from 'react'; -import { createPortal } from 'react-dom'; -import { render as reactRender, unmount as reactUnmount } from './render'; -export interface IPortalProps { - id?: string | symbol; -} - -const PortalMap = observable(new Map()); - -export const createPortalProvider = (id: string | symbol) => { - const Portal: ReactFC = (props) => { - if (props.id && !PortalMap.has(props.id)) { - PortalMap.set(props.id, null); - } - - return ( - - {props.children} - - {() => { - if (!props.id) return <>; - const portal = PortalMap.get(props.id); - if (portal) return createPortal(portal, document.body); - return <>; - }} - - - ); - }; - Portal.defaultProps = { - id, - }; - return Portal; -}; - -export function createPortalRoot(host: HTMLElement, id: string) { - function render(renderer?: () => T) { - if (PortalMap.has(id)) { - PortalMap.set(id, renderer?.()); - } else if (host) { - reactRender({renderer?.()}, host); - } - } - - function unmount() { - if (PortalMap.has(id)) { - PortalMap.set(id, null); - } - if (host) { - const unmountResult = reactUnmount(host); - if (unmountResult && host.parentNode) { - host.parentNode?.removeChild(host); - } - } - } - - return { - render, - unmount, - }; -} diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/render.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/render.ts deleted file mode 100644 index f1e04482f..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/render.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { ReactElement } from 'react'; -import * as ReactDOM from 'react-dom'; -import type { Root } from 'react-dom/client'; - -// 移植自rc-util: https://github.com/react-component/util/blob/master/src/React/render.ts - -type CreateRoot = (container: ContainerType) => Root; - -// Let compiler not to search module usage -const fullClone = { - ...ReactDOM, -} as typeof ReactDOM & { - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?: { - usingClientEntryPoint?: boolean; - }; - createRoot?: CreateRoot; -}; - -const { version, render: reactRender, unmountComponentAtNode } = fullClone; - -let createRoot: CreateRoot; -try { - const mainVersion = Number((version || '').split('.')[0]); - if (mainVersion >= 18 && fullClone.createRoot) { - // eslint-disable-next-line @typescript-eslint/no-var-requires - createRoot = fullClone.createRoot; - } -} catch (e) { - // Do nothing; -} - -function toggleWarning(skip: boolean) { - const { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } = fullClone; - - if ( - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED && - typeof __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED === 'object' - ) { - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.usingClientEntryPoint = skip; - } -} - -const MARK = '__antd_mobile_root__'; - -// ========================== Render ========================== -type ContainerType = (Element | DocumentFragment) & { - [MARK]?: Root; -}; - -function legacyRender(node: ReactElement, container: ContainerType) { - reactRender(node, container); -} - -function concurrentRender(node: ReactElement, container: ContainerType) { - toggleWarning(true); - const root = container[MARK] || createRoot(container); - toggleWarning(false); - root.render(node); - container[MARK] = root; -} - -export function render(node: ReactElement, container: ContainerType) { - if (createRoot as unknown) { - concurrentRender(node, container); - return; - } - legacyRender(node, container); -} - -// ========================== Unmount ========================= -function legacyUnmount(container: ContainerType) { - return unmountComponentAtNode(container); -} - -async function concurrentUnmount(container: ContainerType) { - // Delay to unmount to avoid React 18 sync warning - return Promise.resolve().then(() => { - container[MARK]?.unmount(); - delete container[MARK]; - }); -} - -export function unmount(container: ContainerType) { - if (createRoot as unknown) { - return concurrentUnmount(container); - } - - return legacyUnmount(container); -} diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/style.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/style.ts deleted file mode 100644 index 334074572..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/__builtins__/style.ts +++ /dev/null @@ -1,130 +0,0 @@ -import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs'; -import { useStyleRegister } from '@ant-design/cssinjs'; -import { merge } from '@formily/shared'; -import type { ComponentTokenMap, GlobalToken } from 'antd/es/theme/interface'; -import { AliasToken } from 'antd/es/theme/internal'; -import { useConfig, usePrefixCls, useToken } from './hooks'; - -export interface CustomToken extends AliasToken { - /** 顶部导航栏主色 */ - colorPrimaryHeader: string; - /** 导航栏背景色 */ - colorBgHeader: string; - /** 导航栏菜单背景色悬浮态 */ - colorBgHeaderMenuHover: string; - /** 导航栏菜单背景色激活态 */ - colorBgHeaderMenuActive: string; - /** 导航栏菜单文本色 */ - colorTextHeaderMenu: string; - /** 导航栏菜单文本色悬浮态 */ - colorTextHeaderMenuHover: string; - /** 导航栏菜单文本色激活态 */ - colorTextHeaderMenuActive: string; - - /** UI 配置色 */ - colorSettings: string; - /** 鼠标悬浮时显示的背景色 */ - colorBgSettingsHover: string; - /** 鼠标悬浮时显示的边框色 */ - colorBorderSettingsHover: string; -} - -export type OverrideComponent = keyof ComponentTokenMap | string; - -export interface StyleInfo { - hashId: string; - prefixCls: string; - rootPrefixCls: string; - iconPrefixCls: string; -} - -export type TokenWithCommonCls = T & { - /** Wrap component class with `.` prefix */ - componentCls: string; - /** Origin prefix which do not have `.` prefix */ - prefixCls: string; - /** Wrap icon class with `.` prefix */ - iconCls: string; - /** Wrap ant prefixCls class with `.` prefix */ - antCls: string; -}; - -export type GenerateStyle< - ComponentToken extends object = TokenWithCommonCls, - ReturnType = CSSInterpolation, -> = (token: ComponentToken, options?: any) => ReturnType; - -export const genCommonStyle = (token: any, componentPrefixCls: string): CSSObject => { - const { fontFamily, fontSize } = token; - - const rootPrefixSelector = `[class^="${componentPrefixCls}"], [class*=" ${componentPrefixCls}"]`; - - return { - [rootPrefixSelector]: { - fontFamily, - fontSize, - boxSizing: 'border-box', - - '&::before, &::after': { - boxSizing: 'border-box', - }, - - [rootPrefixSelector]: { - boxSizing: 'border-box', - - '&::before, &::after': { - boxSizing: 'border-box', - }, - }, - }, - }; -}; -export type UseComponentStyleResult = { - wrapSSR: ReturnType; - hashId: string; - componentCls: string; - rootPrefixCls: string; -}; - -export const genStyleHook = ( - component: ComponentName, - styleFn: (token: TokenWithCommonCls, props: any, info: StyleInfo) => CSSInterpolation, -) => { - return (props?: any): UseComponentStyleResult => { - const { theme, token, hashId } = useToken(); - const { getPrefixCls, iconPrefixCls } = useConfig(); - const prefixCls = usePrefixCls(component); - const rootPrefixCls = getPrefixCls(); - - return { - wrapSSR: useStyleRegister( - { - theme: theme as any, - token, - hashId, - path: ['formily-antd', component, prefixCls, iconPrefixCls], - }, - () => { - const componentCls = `.${prefixCls}`; - const mergedToken: TokenWithCommonCls = merge(token, { - componentCls, - prefixCls, - iconCls: `.${iconPrefixCls}`, - antCls: `.${rootPrefixCls}`, - }); - - const styleInterpolation = styleFn(mergedToken, props, { - hashId, - prefixCls, - rootPrefixCls, - iconPrefixCls, - }); - return [genCommonStyle(token, prefixCls), styleInterpolation]; - }, - ), - hashId, - componentCls: prefixCls, - rootPrefixCls, - }; - }; -}; diff --git a/packages/plugins/@hera/plugin-core/src/client/components/ExtendedMenuDesigner.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/deprecated/ExtendedMenuDesigner.tsx similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/components/ExtendedMenuDesigner.tsx rename to packages/plugins/@hera/plugin-core/src/client/schema-components/deprecated/ExtendedMenuDesigner.tsx diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/__tests__/error-fallback.test.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/__tests__/error-fallback.test.tsx deleted file mode 100644 index d03184e79..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/__tests__/error-fallback.test.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { render, screen } from 'testUtils'; -import App1 from '../demos/demo1'; - -describe('ErrorFallback', () => { - it('should render correctly', () => { - render(); - - expect(screen.getByText(/render failed/i)).toBeInTheDocument(); - expect(screen.getByText(/this is likely a nocobase internals bug\. please open an issue at/i)).toBeInTheDocument(); - expect(screen.getByRole('link', { name: /feedback/i })).toBeInTheDocument(); - expect(screen.getByText(/try again/i)).toBeInTheDocument(); - expect(screen.getByText(/error: error message/i)).toBeInTheDocument(); - - // 底部复制按钮 - expect(document.querySelector('.ant-typography-copy')).toBeInTheDocument(); - }); -}); diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/demos/demo1.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/demos/demo1.tsx deleted file mode 100644 index 183fcae57..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/demos/demo1.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { ErrorBoundary } from 'react-error-boundary'; -import { ErrorFallback } from '../ErrorFallback'; - -const App = () => { - throw new Error('error message'); -}; - -export default () => { - return ( - - - - ); -}; diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/index.md b/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/index.md deleted file mode 100644 index 3e6f1cdc6..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -group: - title: Schema Components ---- - -# ErrorFallback - -## Example - - diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/index.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/index.ts deleted file mode 100644 index 12bb8db1b..000000000 --- a/packages/plugins/@hera/plugin-core/src/client/schema-components/error-fallback/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './ErrorFallback'; 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; - 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 ( -
- {props.children} -
- ); -}; - -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 ( - { - 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 = (props) => { - const { height } = props; - const [fixedBlockUID, _setFixedBlock] = useState(false); - const fixedBlockUIDRef = useRef(fixedBlockUID); - const setFixedBlock = (v) => { - fixedBlockUIDRef.current = v; - _setFixedBlock(v); - }; - return ( - -
- {props.children} -
-
- ); -}; - -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( - -
- -
{ - setHeight(Math.floor(ref?.getBoundingClientRect().height || 0) + 1); - }} - > - {!disablePageHeader && ( - - { - setLoading(true); - setSearchParams([['tab', activeKey]]); - setTimeout(() => { - setLoading(false); - }, 50); - }} - tabBarExtraContent={ - dn.designable && ( - - ) - } - items={fieldSchema.mapProperties((schema) => { - return { - label: ( - - {schema['x-icon'] && } - {schema.title || t('Unnamed')} - - - ), - key: schema.name as string, - }; - })} - /> - - ) - } - /> - )} -
-
- - {PageContent(loading, disablePageHeader, enablePageTabs, fieldSchema, activeKey, height, props)} - -
-
-
, - ); -}; - -Page.displayName = 'Page'; - -function PageContent( - loading: boolean, - disablePageHeader: any, - enablePageTabs: any, - fieldSchema: Schema, - 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 ( - - - - ); - }) - ) : ( - -
{props.children}
-
- ); -} 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 ( - -
-
- - {render()} - -
-
-
- ); -}; - -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 ( - -
-
- - - - - {render()} - -
-
-
- ); -}; 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(, { - 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 ( - - - - - - ); -}; - -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 上。 - - 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, - }, - }, - }; -}); diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-initializer/FilterFormItemCustomInitializer/FilterFormItemCustom.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-initializer/FilterFormItemCustomInitializer/FilterFormItemCustom.tsx index 0c4af31d5..d6dcc4647 100644 --- a/packages/plugins/@hera/plugin-core/src/client/schema-initializer/FilterFormItemCustomInitializer/FilterFormItemCustom.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/schema-initializer/FilterFormItemCustomInitializer/FilterFormItemCustom.tsx @@ -22,7 +22,6 @@ import { SchemaSettingsDataScope, EditComponent, useFormBlockContext, - removeNullCondition, useAPIClient, } from '@nocobase/client'; import { ConfigProvider } from 'antd'; @@ -31,7 +30,7 @@ import { Schema, SchemaOptionsContext, observer, useField, useFieldSchema } from import { FormLayout } from '@formily/antd-v5'; import { uid } from '@formily/shared'; import { Field } from '@formily/core'; -import { EditFormulaTitleField, EditTitle, EditTitleField } from '../../components/SchemaSettingOptions'; +import { EditFormulaTitleField, EditTitle, EditTitleField } from '../../schema-settings'; import _ from 'lodash'; import { SchemaSettingsRemove } from '../../components/FormFilter/SchemaSettingsRemove'; import { useTranslation } from '../../locale'; diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-initializer/OutboundLinkActionInitializer.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-initializer/OutboundLinkActionInitializer.tsx index 59a85d25d..036bc2c42 100644 --- a/packages/plugins/@hera/plugin-core/src/client/schema-initializer/OutboundLinkActionInitializer.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/schema-initializer/OutboundLinkActionInitializer.tsx @@ -1,5 +1,9 @@ import React from 'react'; import { ActionInitializer } from '@nocobase/client'; +import { Popover, Space, Button, Input } from 'antd'; +import { useFieldSchema } from '@formily/react'; +import { useProps } from '@nocobase/client'; +import { ShareAltOutlined } from '@ant-design/icons'; export const OutboundLinkActionInitializer = (props) => { const schema = { @@ -14,3 +18,29 @@ export const OutboundLinkActionInitializer = (props) => { }; return ; }; + +export const OutboundButton = (props) => { + const { onClick } = useProps(props); + const schema = useFieldSchema(); + const url = window.location.href.split('/', 3).join('/'); + return ( + + + + + } + > + + + ); +}; diff --git a/packages/plugins/@hera/plugin-core/src/client/components/SchemaSettingOptions.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-settings/index.tsx similarity index 75% rename from packages/plugins/@hera/plugin-core/src/client/components/SchemaSettingOptions.tsx rename to packages/plugins/@hera/plugin-core/src/client/schema-settings/index.tsx index ddd4154f6..41ddac3dc 100644 --- a/packages/plugins/@hera/plugin-core/src/client/components/SchemaSettingOptions.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/schema-settings/index.tsx @@ -1,35 +1,25 @@ import { Field } from '@formily/core'; -import { ISchema, useField, useFieldSchema, useForm } from '@formily/react'; +import { ISchema, useField, useFieldSchema } from '@formily/react'; import { - SchemaSettingsLinkageRules, SchemaSettingsModalItem, SchemaSettingsSelectItem, SchemaSettingsSwitchItem, - css, - mergeFilter, - removeNullCondition, - useBlockRequestContext, useCollection_deprecated, useCollectionManager_deprecated, useCompile, useDesignable, - useFieldModeOptions, - useFilterFieldProps, - useFilterOptions, useFormBlockContext, useFormBlockType, useLinkageCollectionFilterOptions, useLocalVariables, - useProps, useRecord, useSchemaTemplateManager, - useSortFields, useVariables, } from '@nocobase/client'; -import _, { get } from 'lodash'; -import React, { useCallback, useContext, useMemo } from 'react'; +import _ from 'lodash'; +import React, { useCallback, useMemo } from 'react'; import { useTranslation } from '../locale'; -import { FormFilterScope } from './FormFilter/FormFilterScope'; +import { FormFilterScope } from '../components/FormFilter/FormFilterScope'; export const useFormulaTitleOptions = () => { const compile = useCompile(); @@ -376,3 +366,132 @@ export const SetFilterScope = (props) => { ); return ; }; + +export function AfterSuccess() { + const { dn } = useDesignable(); + const { t } = useTranslation(); + const fieldSchema = useFieldSchema(); + const component = fieldSchema.parent.parent['x-component']; + const schema = { + type: 'object', + title: t('After successful submission'), + properties: { + successMessage: { + title: t('Popup message'), + 'x-decorator': 'FormItem', + 'x-component': 'Input.TextArea', + 'x-component-props': {}, + }, + dataClear: { + title: t('Clear data method'), + enum: [ + { label: t('Automatic clear'), value: false }, + { label: t('Manually clear'), value: true }, + ], + 'x-decorator': 'FormItem', + 'x-component': 'Radio.Group', + 'x-component-props': {}, + }, + manualClose: { + title: t('Popup close method'), + enum: [ + { label: t('Automatic close'), value: false }, + { label: t('Manually close'), value: true }, + ], + 'x-decorator': 'FormItem', + 'x-component': 'Radio.Group', + 'x-component-props': {}, + }, + redirecting: { + title: t('Then'), + enum: [ + { label: t('Stay on current page'), value: false }, + { label: t('Redirect to'), value: true }, + ], + 'x-decorator': 'FormItem', + 'x-component': 'Radio.Group', + 'x-component-props': {}, + 'x-reactions': { + target: 'redirectTo', + fulfill: { + state: { + visible: '{{!!$self.value}}', + }, + }, + }, + }, + redirectTo: { + title: t('Link'), + 'x-decorator': 'FormItem', + 'x-component': 'Input', + 'x-component-props': {}, + }, + }, + }; + if (!(component as string).includes('Form')) { + delete schema.properties.dataClear; + } + return ( + { + fieldSchema['x-action-settings']['onSuccess'] = onSuccess; + dn.emit('patch', { + schema: { + ['x-uid']: fieldSchema['x-uid'], + 'x-action-settings': fieldSchema['x-action-settings'], + }, + }); + }} + /> + ); +} + +// 添加跳转页面选项 +export const SessionSubmit = () => { + const { dn } = useDesignable(); + const { t } = useTranslation(); + const fieldSchema = useFieldSchema(); + return ( + { + fieldSchema['x-action-settings'].sessionSubmit = value; + dn.emit('patch', { + schema: { + ['x-uid']: fieldSchema['x-uid'], + 'x-action-settings': { + ...fieldSchema['x-action-settings'], + }, + }, + }); + }} + /> + ); +}; + +export function SessionUpdate() { + const { dn } = useDesignable(); + const { t } = useTranslation(); + const fieldSchema = useFieldSchema(); + return ( + { + fieldSchema['x-action-settings'].sessionUpdate = value; + dn.emit('patch', { + schema: { + ['x-uid']: fieldSchema['x-uid'], + 'x-action-settings': { + ...fieldSchema['x-action-settings'], + }, + }, + }); + }} + /> + ); +} diff --git a/packages/plugins/@hera/plugin-core/src/client/pages/HomePageConfiguration.tsx b/packages/plugins/@hera/plugin-core/src/client/settings-manager-components/HomePageConfiguration.tsx similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/pages/HomePageConfiguration.tsx rename to packages/plugins/@hera/plugin-core/src/client/settings-manager-components/HomePageConfiguration.tsx diff --git a/packages/plugins/@hera/plugin-core/src/client/components/LinkManager.tsx b/packages/plugins/@hera/plugin-core/src/client/settings-manager-components/LinkManager.tsx similarity index 98% rename from packages/plugins/@hera/plugin-core/src/client/components/LinkManager.tsx rename to packages/plugins/@hera/plugin-core/src/client/settings-manager-components/LinkManager.tsx index e1c308d80..90bbaf732 100644 --- a/packages/plugins/@hera/plugin-core/src/client/components/LinkManager.tsx +++ b/packages/plugins/@hera/plugin-core/src/client/settings-manager-components/LinkManager.tsx @@ -29,7 +29,7 @@ export const LinkManager = () => { updateLink(); // 更新表格数据 const mergedArray = tableData.map((item) => { - const matchingItem = item.id == formData.id; + const matchingItem = item.id === formData.id; if (matchingItem) { return formData; } diff --git a/packages/plugins/@hera/plugin-core/src/client/components/TokenConfiguration.tsx b/packages/plugins/@hera/plugin-core/src/client/settings-manager-components/TokenConfiguration.tsx similarity index 100% rename from packages/plugins/@hera/plugin-core/src/client/components/TokenConfiguration.tsx rename to packages/plugins/@hera/plugin-core/src/client/settings-manager-components/TokenConfiguration.tsx diff --git a/packages/plugins/@hera/plugin-core/src/client/settings-manager-components/index.ts b/packages/plugins/@hera/plugin-core/src/client/settings-manager-components/index.ts new file mode 100644 index 000000000..9f6162f1a --- /dev/null +++ b/packages/plugins/@hera/plugin-core/src/client/settings-manager-components/index.ts @@ -0,0 +1,3 @@ +export * from './HomePageConfiguration'; +export * from './LinkManager'; +export * from './TokenConfiguration';