diff --git a/packages/core/client/src/hoc/withTooltipComponent.tsx b/packages/core/client/src/hoc/withTooltipComponent.tsx new file mode 100644 index 00000000000..d057a033f78 --- /dev/null +++ b/packages/core/client/src/hoc/withTooltipComponent.tsx @@ -0,0 +1,37 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import React from 'react'; +import { Tooltip } from 'antd'; +import { QuestionCircleOutlined } from '@ant-design/icons'; + +const titleWrapperStyle = { + display: 'flex', + alignItems: 'center', + gap: 4, +}; + +export const withTooltipComponent = (Component: React.FC) => { + return (props) => { + const { tooltip } = props; + + if (!tooltip) { + return ; + } + + return ( +
+ + + + +
+ ); + }; +}; diff --git a/packages/core/client/src/index.ts b/packages/core/client/src/index.ts index 964e16f96ad..2da90be0221 100644 --- a/packages/core/client/src/index.ts +++ b/packages/core/client/src/index.ts @@ -88,6 +88,5 @@ export { IsInNocoBaseRecursionFieldContext, NocoBaseRecursionField, RefreshComponentProvider, - useRefreshFieldSchema + useRefreshFieldSchema, } from './formily/NocoBaseRecursionField'; - diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer.test.ts b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer.test.ts index 669ca57babf..352afc0fdb9 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer.test.ts @@ -306,6 +306,9 @@ test.describe('configure actions column', () => { await page.getByText('Actions', { exact: true }).hover(); await page.getByLabel('designer-schema-initializer-TableV2.Column-TableV2.ActionColumnDesigner-').hover(); await page.getByRole('menuitem', { name: 'Delete' }).click(); + + await page.getByText('Actions', { exact: true }).hover(); + await page.getByLabel('designer-schema-initializer-TableV2.Column-TableV2.ActionColumnDesigner-').hover(); await page.getByRole('menuitem', { name: 'Duplicate' }).click(); await page.mouse.move(300, 0); diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/tableColumnSettings.tsx b/packages/core/client/src/modules/blocks/data-blocks/table/tableColumnSettings.tsx index ef3d410750a..a6b05d7227b 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/table/tableColumnSettings.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/table/tableColumnSettings.tsx @@ -82,6 +82,43 @@ export const tableColumnSettings = new SchemaSettings({ }; }, }, + { + name: 'editTooltip', + type: 'modal', + useComponentProps() { + const { t } = useTranslation(); + const { dn } = useDesignable(); + const field = useField(); + const columnSchema = useFieldSchema(); + + return { + title: t('Edit tooltip'), + schema: { + type: 'object', + title: t('Edit tooltip'), + properties: { + tooltip: { + default: columnSchema?.['x-component-props']?.tooltip || '', + 'x-decorator': 'FormItem', + 'x-component': 'Input.TextArea', + 'x-component-props': {}, + }, + }, + } as ISchema, + onSubmit({ tooltip }) { + field.componentProps.tooltip = tooltip; + columnSchema['x-component-props'] = columnSchema['x-component-props'] || {}; + columnSchema['x-component-props']['tooltip'] = tooltip; + dn.emit('patch', { + schema: { + 'x-uid': columnSchema['x-uid'], + 'x-component-props': columnSchema['x-component-props'], + }, + }); + }, + }; + }, + }, { name: 'style', Component: (props) => { diff --git a/packages/core/client/src/modules/menu/__e2e__/schemaSettings.test.ts b/packages/core/client/src/modules/menu/__e2e__/schemaSettings.test.ts index 786996bb1ff..ba6f06a3f7d 100644 --- a/packages/core/client/src/modules/menu/__e2e__/schemaSettings.test.ts +++ b/packages/core/client/src/modules/menu/__e2e__/schemaSettings.test.ts @@ -17,7 +17,7 @@ test.describe('group page side menus schema settings', () => { await expectSettingsMenu({ page, showMenu: () => showSettingsInSide(page, 'group page in side'), - supportedOptions: ['Edit', 'Move to', 'Insert before', 'Insert after', 'Insert inner', 'Delete'], + supportedOptions: ['Edit', 'Edit tooltip', 'Move to', 'Insert before', 'Insert after', 'Insert inner', 'Delete'], }); }); @@ -28,7 +28,7 @@ test.describe('group page side menus schema settings', () => { await expectSettingsMenu({ page, showMenu: () => showSettingsInSide(page, 'link page in side'), - supportedOptions: ['Edit', 'Move to', 'Insert before', 'Insert after', 'Delete'], + supportedOptions: ['Edit', 'Edit tooltip', 'Move to', 'Insert before', 'Insert after', 'Delete'], }); }); @@ -39,7 +39,7 @@ test.describe('group page side menus schema settings', () => { await expectSettingsMenu({ page, showMenu: () => showSettingsInSide(page, 'single page in side'), - supportedOptions: ['Edit', 'Move to', 'Insert before', 'Insert after', 'Delete'], + supportedOptions: ['Edit', 'Edit tooltip', 'Move to', 'Insert before', 'Insert after', 'Delete'], }); }); }); diff --git a/packages/core/client/src/modules/menu/__e2e__/schemaSettings1.test.ts b/packages/core/client/src/modules/menu/__e2e__/schemaSettings1.test.ts index b52fcb9cb48..ef5799f1114 100644 --- a/packages/core/client/src/modules/menu/__e2e__/schemaSettings1.test.ts +++ b/packages/core/client/src/modules/menu/__e2e__/schemaSettings1.test.ts @@ -13,7 +13,7 @@ test.describe('group page menus schema settings', () => { test('edit', async ({ page, mockPage }) => { await mockPage({ type: 'group', name: 'group page' }).goto(); await showSettings(page, 'group page'); - await page.getByRole('menuitem', { name: 'Edit' }).click(); + await page.getByRole('menuitem', { name: 'Edit', exact: true }).click(); await page.mouse.move(300, 0); // 设置一个新名称 diff --git a/packages/core/client/src/route-switch/antd/admin-layout/convertRoutesToSchema.ts b/packages/core/client/src/route-switch/antd/admin-layout/convertRoutesToSchema.ts index 16fbf9ea858..ab351cd9ccd 100644 --- a/packages/core/client/src/route-switch/antd/admin-layout/convertRoutesToSchema.ts +++ b/packages/core/client/src/route-switch/antd/admin-layout/convertRoutesToSchema.ts @@ -23,6 +23,7 @@ export interface NocoBaseDesktopRoute { children?: NocoBaseDesktopRoute[]; title?: string; + tooltip?: string; icon?: string; schemaUid?: string; menuSchemaUid?: string; diff --git a/packages/core/client/src/route-switch/antd/admin-layout/index.tsx b/packages/core/client/src/route-switch/antd/admin-layout/index.tsx index 448c4c32675..354db02fe3b 100644 --- a/packages/core/client/src/route-switch/antd/admin-layout/index.tsx +++ b/packages/core/client/src/route-switch/antd/admin-layout/index.tsx @@ -50,6 +50,7 @@ import { KeepAlive } from './KeepAlive'; import { NocoBaseDesktopRoute, NocoBaseDesktopRouteType } from './convertRoutesToSchema'; import { MenuSchemaToolbar, ResetThemeTokenAndKeepAlgorithm } from './menuItemSettings'; import { userCenterSettings } from './userCenterSettings'; +import { withTooltipComponent } from '../../../hoc/withTooltipComponent'; export { KeepAlive, NocoBaseDesktopRouteType }; @@ -434,16 +435,26 @@ const actionsRender: any = (props) => { return ; }; +const MenuItemTitle: React.FC = (props) => { + return <>{props.children}; +}; + +const MenuItemTitleWithTooltip = withTooltipComponent(MenuItemTitle); + const menuItemRender = (item, dom, options) => { return ( - {dom} + {dom} ); }; const subMenuItemRender = (item, dom) => { - return {dom}; + return ( + + {dom} + + ); }; const CollapsedButton: FC<{ collapsed: boolean }> = (props) => { @@ -753,6 +764,8 @@ function convertRoutesToLayout(routes: NocoBaseDesktopRoute[], { designable, par name: , path: '/', disabled: true, + _route: {}, + _parentRoute: {}, icon: , }; }; diff --git a/packages/core/client/src/route-switch/antd/admin-layout/menuItemSettings.tsx b/packages/core/client/src/route-switch/antd/admin-layout/menuItemSettings.tsx index 316a47bf312..3b91f08ef0d 100644 --- a/packages/core/client/src/route-switch/antd/admin-layout/menuItemSettings.tsx +++ b/packages/core/client/src/route-switch/antd/admin-layout/menuItemSettings.tsx @@ -525,6 +525,53 @@ const MoveToMenuItem = () => { ); }; +const EditTooltip = () => { + const { t } = useTranslation(); + const currentRoute = useCurrentRoute(); + const { updateRoute } = useNocoBaseRoutes(); + + const editTooltipSchema = useMemo(() => { + return { + type: 'object', + title: t('Edit tooltip'), + properties: { + tooltip: { + 'x-decorator': 'FormItem', + 'x-component': 'Input.TextArea', + 'x-component-props': {}, + }, + }, + }; + }, [t]); + const initialTooltipValues = useMemo(() => { + return { + tooltip: currentRoute.tooltip, + }; + }, [currentRoute.tooltip]); + + const onEditTooltipSubmit: (values: any) => void = useCallback( + ({ tooltip }) => { + // 更新菜单对应的路由 + if (currentRoute.id !== undefined) { + updateRoute(currentRoute.id, { + tooltip, + }); + } + }, + [currentRoute.id, updateRoute], + ); + + return ( + + ); +}; + export const menuItemSettings = new SchemaSettings({ name: 'menuSettings:menuItem', items: [ @@ -532,6 +579,10 @@ export const menuItemSettings = new SchemaSettings({ name: 'edit', Component: EditMenuItem, }, + { + name: 'editTooltip', + Component: EditTooltip, + }, { name: 'hidden', Component: HiddenMenuItem, diff --git a/packages/core/client/src/schema-component/antd/association-field/Table.tsx b/packages/core/client/src/schema-component/antd/association-field/Table.tsx index 3d22ebb7f86..d50eb018b1c 100644 --- a/packages/core/client/src/schema-component/antd/association-field/Table.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/Table.tsx @@ -45,6 +45,7 @@ import { useToken } from '../__builtins__'; import { SubFormProvider, useAssociationFieldContext } from '../association-field/hooks'; import { ColumnFieldProvider } from '../table-v2/components/ColumnFieldProvider'; import { extractIndex, isCollectionFieldComponent, isColumnComponent } from '../table-v2/utils'; +import { withTooltipComponent } from '../../../hoc/withTooltipComponent'; const InViewContext = React.createContext(false); @@ -85,6 +86,8 @@ export const useColumnsDeepMemoized = (columns: any[]) => { return oldObj.value; }; +const TableColumnTitle = withTooltipComponent(RecursionField); + const useTableColumns = (props: { showDel?: any; isSubTable?: boolean }, paginationProps) => { const { token } = useToken(); const field = useArrayField(props); @@ -112,7 +115,6 @@ const useTableColumns = (props: { showDel?: any; isSubTable?: boolean }, paginat }, [token.paddingContentVerticalLG, token.marginSM]); const collection = useCollection(); - const columns = useMemo( () => columnsSchema?.map((s: Schema) => { @@ -124,7 +126,7 @@ const useTableColumns = (props: { showDel?: any; isSubTable?: boolean }, paginat const dataIndex = collectionFields?.length > 0 ? collectionFields[0].name : s.name; const columnHidden = !!s['x-component-props']?.['columnHidden']; return { - title: , + title: , dataIndex, key: s.name, sorter: s['x-component-props']?.['sorter'], diff --git a/packages/core/client/src/schema-component/antd/menu/Menu.Designer.tsx b/packages/core/client/src/schema-component/antd/menu/Menu.Designer.tsx index d6ba0d0371f..5aca7495b70 100644 --- a/packages/core/client/src/schema-component/antd/menu/Menu.Designer.tsx +++ b/packages/core/client/src/schema-component/antd/menu/Menu.Designer.tsx @@ -286,14 +286,14 @@ export const MenuDesigner = () => { f.dataSource = component === 'Menu.SubMenu' ? [ - { label: t('Before'), value: 'beforeBegin' }, - { label: t('After'), value: 'afterEnd' }, - { label: t('Inner'), value: 'beforeEnd' }, - ] + { label: t('Before'), value: 'beforeBegin' }, + { label: t('After'), value: 'afterEnd' }, + { label: t('Inner'), value: 'beforeEnd' }, + ] : [ - { label: t('Before'), value: 'beforeBegin' }, - { label: t('After'), value: 'afterEnd' }, - ]; + { label: t('Before'), value: 'beforeBegin' }, + { label: t('After'), value: 'afterEnd' }, + ]; }); }); }, @@ -325,6 +325,24 @@ export const MenuDesigner = () => { icon: field.componentProps.icon, }; }, [field.title, field.componentProps.icon]); + const editTooltipSchema = useMemo(() => { + return { + type: 'object', + title: t('Edit tooltip'), + properties: { + tooltip: { + 'x-decorator': 'FormItem', + 'x-component': 'Input.TextArea', + 'x-component-props': {}, + }, + }, + }; + }, [t]); + const initialTooltipValues = useMemo(() => { + return { + tooltip: field.componentProps.tooltip, + }; + }, [field.componentProps.tooltip]); if (fieldSchema['x-component'] === 'Menu.URL') { schema.properties['href'] = urlSchema; schema.properties['params'] = paramsSchema; @@ -369,15 +387,26 @@ export const MenuDesigner = () => { options: href || params ? { - href, - params, - } + href, + params, + } : undefined, }); } }, [fieldSchema, field, dn, refresh, onSelect], ); + const onEditTooltipSubmit: (values: any) => void = useCallback( + ({ tooltip }) => { + // 更新菜单对应的路由 + if (fieldSchema['__route__']?.id) { + updateRoute(fieldSchema['__route__'].id, { + tooltip, + }); + } + }, + [fieldSchema, field, dn, refresh, onSelect], + ); const modalSchema = useMemo(() => { return { @@ -471,6 +500,13 @@ export const MenuDesigner = () => { initialValues={initialValues} onSubmit={onEditSubmit} /> + & { Designer?: React.FC; }; +const MenuItemTitle: React.FC<{ + schema: any; + style?: React.CSSProperties; +}> = ({ schema, style }) => { + const { t } = useMenuTranslation(); + return {t(schema.title)}; +}; + +const MenuItemTitleWithTooltip = withTooltipComponent(MenuItemTitle); + export const ParentRouteContext = createContext(null); ParentRouteContext.displayName = 'ParentRouteContext'; @@ -668,8 +679,9 @@ const menuItemTitleStyle = { overflow: 'hidden', textOverflow: 'ellipsis', display: 'inline-block', - width: '100%', + // width: '100%', verticalAlign: 'middle', + // marginInlineEnd: '4px', }; Menu.Item = observer( @@ -698,7 +710,11 @@ Menu.Item = observer( removeParentsIfNoChildren={false} > - {t(schema.title)} + @@ -720,6 +736,7 @@ Menu.Item = observer( const MenuURLButton = ({ href, params, icon }) => { const field = useField(); + const schema = useFieldSchema(); const { t } = useMenuTranslation(); const Designer = useContext(MenuItemDesignerContext); const { parseURLAndParams } = useParseURLAndParams(); @@ -749,17 +766,11 @@ const MenuURLButton = ({ href, params, icon }) => { aria-label={t(field.title)} > - - {t(field.title)} - + ); @@ -814,6 +825,7 @@ Menu.SubMenu = observer( const field = useField(); const mode = useContext(MenuModeContext); const Designer = useContext(MenuItemDesignerContext); + const submenu = useMemo(() => { return { ...others, @@ -830,7 +842,11 @@ Menu.SubMenu = observer( aria-label={t(field.title)} > - {t(field.title)} + diff --git a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx index d6c7d561e63..78f6128d7d1 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx @@ -66,6 +66,7 @@ import { useToken } from '../__builtins__'; import { useAssociationFieldContext } from '../association-field/hooks'; import { TableSkeleton } from './TableSkeleton'; import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils'; +import { withTooltipComponent } from '../../../hoc/withTooltipComponent'; type BodyRowComponentProps = { rowIndex?: number; @@ -198,6 +199,9 @@ const useTableColumns = ( const collection = useCollection(); + // 不能提取到外部,否则 NocoBaseRecursionField 的值在一开始会是 undefined。原因未知 + const TableColumnTitle = useMemo(() => withTooltipComponent(NocoBaseRecursionField), []); + const columns = useMemo( () => columnsSchemas?.map((columnSchema: Schema) => { @@ -217,11 +221,12 @@ const useTableColumns = ( return { title: ( - ), diff --git a/packages/core/test/src/e2e/e2eUtils.ts b/packages/core/test/src/e2e/e2eUtils.ts index 0f2a11c16d6..35fd5835072 100644 --- a/packages/core/test/src/e2e/e2eUtils.ts +++ b/packages/core/test/src/e2e/e2eUtils.ts @@ -1396,11 +1396,11 @@ export async function expectSettingsMenu({ await page.waitForTimeout(100); await showMenu(); for (const option of supportedOptions) { - await expect(page.getByRole('menuitem', { name: option })).toBeVisible(); + await expect(page.getByRole('menuitem', { name: option, exact: option === 'Edit' })).toBeVisible(); } if (unsupportedOptions) { for (const option of unsupportedOptions) { - await expect(page.getByRole('menuitem', { name: option })).not.toBeVisible(); + await expect(page.getByRole('menuitem', { name: option, exact: option === 'Edit' })).not.toBeVisible(); } } } diff --git a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/MenuPermissions.tsx b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/MenuPermissions.tsx index 2aebfaf4b63..ca15caf7b1b 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/MenuPermissions.tsx +++ b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/MenuPermissions.tsx @@ -9,7 +9,14 @@ import { createForm, Form, onFormValuesChange } from '@formily/core'; import { uid } from '@formily/shared'; -import { css, SchemaComponent, useAllAccessDesktopRoutes, useAPIClient, useCompile, useRequest } from '@nocobase/client'; +import { + css, + SchemaComponent, + useAllAccessDesktopRoutes, + useAPIClient, + useCompile, + useRequest, +} from '@nocobase/client'; import { useMemoizedFn } from 'ahooks'; import { Checkbox, message, Table } from 'antd'; import { uniq } from 'lodash'; @@ -68,7 +75,8 @@ const style = css` const translateTitle = (menus: any[], t, compile) => { return menus.map((menu) => { - const title = (menu.title?.match(/^\s*\{\{\s*.+?\s*\}\}\s*$/) ? compile(menu.title) : t(menu.title)) || t('Unnamed'); + const title = + (menu.title?.match(/^\s*\{\{\s*.+?\s*\}\}\s*$/) ? compile(menu.title) : t(menu.title)) || t('Unnamed'); if (menu.children) { return { ...menu, @@ -123,7 +131,7 @@ const DesktopRoutesProvider: FC<{ }; export const DesktopAllRoutesProvider: React.FC<{ active: boolean }> = ({ children, active }) => { - const refreshRef = React.useRef(() => { }); + const refreshRef = React.useRef(() => {}); useEffect(() => { if (active) { diff --git a/packages/plugins/@nocobase/plugin-calendar/src/client/calendar/Calendar.tsx b/packages/plugins/@nocobase/plugin-calendar/src/client/calendar/Calendar.tsx index 653ffc6219b..287fdc2c5f3 100644 --- a/packages/plugins/@nocobase/plugin-calendar/src/client/calendar/Calendar.tsx +++ b/packages/plugins/@nocobase/plugin-calendar/src/client/calendar/Calendar.tsx @@ -29,7 +29,7 @@ import { usePopupUtils, useProps, withDynamicSchemaProps, - withSkeletonComponent + withSkeletonComponent, } from '@nocobase/client'; import type { Dayjs } from 'dayjs'; import dayjs from 'dayjs'; @@ -75,7 +75,7 @@ const getColorString = ( }; export const DeleteEventContext = React.createContext({ - close: () => { }, + close: () => {}, allowDeleteEvent: false, }); diff --git a/packages/plugins/@nocobase/plugin-calendar/src/client/index.tsx b/packages/plugins/@nocobase/plugin-calendar/src/client/index.tsx index 7ad775475f1..5dc9ba6ca8a 100644 --- a/packages/plugins/@nocobase/plugin-calendar/src/client/index.tsx +++ b/packages/plugins/@nocobase/plugin-calendar/src/client/index.tsx @@ -70,9 +70,9 @@ export class PluginCalendarClient extends Plugin { colorFieldInterfaces: { [T: string]: { useGetColor: (field: any) => ColorFunctions }; } = { - select: { useGetColor }, - radioGroup: { useGetColor }, - }; + select: { useGetColor }, + radioGroup: { useGetColor }, + }; dateTimeFieldInterfaces = ['date', 'datetime', 'dateOnly', 'datetimeNoTz', 'unixTimestamp', 'createdAt', 'updatedAt']; diff --git a/packages/plugins/@nocobase/plugin-client/src/client/routesTableSchema.tsx b/packages/plugins/@nocobase/plugin-client/src/client/routesTableSchema.tsx index c2613291840..f3b71bb6b29 100644 --- a/packages/plugins/@nocobase/plugin-client/src/client/routesTableSchema.tsx +++ b/packages/plugins/@nocobase/plugin-client/src/client/routesTableSchema.tsx @@ -236,13 +236,13 @@ export const createRoutesTableSchema = (collectionName: string, basename: string 'x-component': 'IconPicker', 'x-reactions': isMobile ? { - dependencies: ['type'], - fulfill: { - state: { - required: '{{$deps[0] !== "tabs"}}', + dependencies: ['type'], + fulfill: { + state: { + required: '{{$deps[0] !== "tabs"}}', + }, }, - }, - } + } : undefined, }, // 由于历史原因,桌面端使用的是 'href' 作为 key,移动端使用的是 'url' 作为 key @@ -574,8 +574,9 @@ export const createRoutesTableSchema = (collectionName: string, basename: string } if (recordData.type === NocoBaseDesktopRouteType.page) { - const path = `${basenameOfCurrentRouter.slice(0, -1)}${basename}/${isMobile ? recordData.schemaUid : recordData.menuSchemaUid - }`; + const path = `${basenameOfCurrentRouter.slice(0, -1)}${basename}/${ + isMobile ? recordData.schemaUid : recordData.menuSchemaUid + }`; // 在点击 Access 按钮时,会用到 recordData._path = path; @@ -695,13 +696,13 @@ export const createRoutesTableSchema = (collectionName: string, basename: string 'x-component': 'IconPicker', 'x-reactions': isMobile ? { - dependencies: ['type'], - fulfill: { - state: { - required: '{{$deps[0] !== "tabs"}}', + dependencies: ['type'], + fulfill: { + state: { + required: '{{$deps[0] !== "tabs"}}', + }, }, - }, - } + } : undefined, }, // 由于历史原因,桌面端使用的是 'href' 作为 key,移动端使用的是 'url' 作为 key @@ -984,13 +985,13 @@ export const createRoutesTableSchema = (collectionName: string, basename: string 'x-component': 'IconPicker', 'x-reactions': isMobile ? { - dependencies: ['type'], - fulfill: { - state: { - required: '{{$deps[0] !== "tabs"}}', + dependencies: ['type'], + fulfill: { + state: { + required: '{{$deps[0] !== "tabs"}}', + }, }, - }, - } + } : undefined, }, // 由于历史原因,桌面端使用的是 'href' 作为 key,移动端使用的是 'url' 作为 key @@ -1245,11 +1246,7 @@ function useCreateRouteSchema(isMobile: boolean) { const insertPageSchema = useInsertPageSchema(); const createRouteSchema = useCallback( - async ({ - type, - }: { - type: NocoBaseDesktopRouteType; - }) => { + async ({ type }: { type: NocoBaseDesktopRouteType }) => { const menuSchemaUid = isMobile ? undefined : uid(); const pageSchemaUid = uid(); const tabSchemaName = uid(); @@ -1259,10 +1256,10 @@ function useCreateRouteSchema(isMobile: boolean) { [NocoBaseDesktopRouteType.page]: isMobile ? getMobilePageSchema(pageSchemaUid, tabSchemaUid).schema : getPageMenuSchema({ - pageSchemaUid, - tabSchemaUid, - tabSchemaName, - }), + pageSchemaUid, + tabSchemaUid, + tabSchemaName, + }), }; if (!typeToSchema[type]) { diff --git a/packages/plugins/@nocobase/plugin-client/src/collections/desktopRoutes.ts b/packages/plugins/@nocobase/plugin-client/src/collections/desktopRoutes.ts index 2a46b2c4754..06f0b999e9b 100644 --- a/packages/plugins/@nocobase/plugin-client/src/collections/desktopRoutes.ts +++ b/packages/plugins/@nocobase/plugin-client/src/collections/desktopRoutes.ts @@ -205,6 +205,21 @@ export default { title: '{{t("Title")}}', }, }, + { + key: 'brt6tz4hgin', + name: 'tooltip', + type: 'string', + interface: 'textarea', + description: null, + collectionName: 'desktopRoutes', + parentKey: null, + reverseKey: null, + uiSchema: { + type: 'string', + 'x-component': 'Input.TextArea', + title: '{{t("Tooltip")}}', + }, + }, { key: 'ozl5d8t2d5e', name: 'icon', diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client/index.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client/index.tsx index 2fb72f36408..de637a69f19 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/client/index.tsx +++ b/packages/plugins/@nocobase/plugin-workflow/src/client/index.tsx @@ -76,7 +76,7 @@ export default class PluginWorkflowClient extends Plugin { return this.triggers.get(workflow.type)?.sync ?? workflow.sync; } - registerTrigger(type: string, trigger: Trigger | { new(): Trigger }) { + registerTrigger(type: string, trigger: Trigger | { new (): Trigger }) { if (typeof trigger === 'function') { this.triggers.register(type, new trigger()); } else if (trigger) { @@ -86,7 +86,7 @@ export default class PluginWorkflowClient extends Plugin { } } - registerInstruction(type: string, instruction: Instruction | { new(): Instruction }) { + registerInstruction(type: string, instruction: Instruction | { new (): Instruction }) { if (typeof instruction === 'function') { this.instructions.register(type, new instruction()); } else if (instruction instanceof Instruction) { @@ -193,4 +193,3 @@ export { default as useStyles } from './style'; export { Trigger, useTrigger } from './triggers'; export * from './utils'; export * from './variable'; -