diff --git a/packages/core/client/src/common/useFieldComponentName.tsx b/packages/core/client/src/common/useFieldComponentName.tsx index 6e0393d8d..23fa902d2 100644 --- a/packages/core/client/src/common/useFieldComponentName.tsx +++ b/packages/core/client/src/common/useFieldComponentName.tsx @@ -30,6 +30,7 @@ export function useFieldComponentName(): string { fieldSchema?.['x-component-props']?.['mode'] || field?.componentProps?.['mode'] || (isFileField ? 'FileManager' : '') || + fieldSchema?.['x-component-props']?.['component'] || collectionField?.uiSchema?.['x-component']; return map[fieldComponentName] || fieldComponentName; } diff --git a/packages/core/client/src/data-source/collection-field/CollectionField.tsx b/packages/core/client/src/data-source/collection-field/CollectionField.tsx index c3485282e..3f300fd09 100644 --- a/packages/core/client/src/data-source/collection-field/CollectionField.tsx +++ b/packages/core/client/src/data-source/collection-field/CollectionField.tsx @@ -12,12 +12,12 @@ import { connect, useField, useFieldSchema } from '@formily/react'; import { merge } from '@formily/shared'; import { concat } from 'lodash'; import React, { useCallback, useEffect, useMemo } from 'react'; +import { ErrorBoundary } from 'react-error-boundary'; import { useFormBlockContext } from '../../block-provider/FormBlockProvider'; import { useDynamicComponentProps } from '../../hoc/withDynamicSchemaProps'; import { ErrorFallback, useCompile, useComponent } from '../../schema-component'; import { useIsAllowToSetDefaultValue } from '../../schema-settings/hooks/useIsAllowToSetDefaultValue'; import { CollectionFieldProvider, useCollectionField } from './CollectionFieldProvider'; -import { ErrorBoundary } from 'react-error-boundary'; type Props = { component: any; @@ -37,7 +37,9 @@ export const CollectionFieldInternalField: React.FC = (props: Props) => { const { uiSchema: uiSchemaOrigin, defaultValue } = collectionField; const { isAllowToSetDefaultValue } = useIsAllowToSetDefaultValue(); const uiSchema = useMemo(() => compile(uiSchemaOrigin), [JSON.stringify(uiSchemaOrigin)]); - const Component = useComponent(component || uiSchema?.['x-component'] || 'Input'); + const Component = useComponent( + fieldSchema['x-component-props']?.['component'] || uiSchema?.['x-component'] || 'Input', + ); const setFieldProps = useCallback( (key, value) => { field[key] = typeof field[key] === 'undefined' ? value : field[key]; 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 4420af829..b7c8a1c1d 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 @@ -13,13 +13,13 @@ import { useTranslation } from 'react-i18next'; import { useApp } from '../../../../application'; import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; import { useCollectionManager_deprecated } from '../../../../collection-manager'; +import { useFieldComponentName } from '../../../../common/useFieldComponentName'; import { useCollection } from '../../../../data-source'; import { useDesignable } from '../../../../schema-component'; import { useAssociationFieldContext } from '../../../../schema-component/antd/association-field/hooks'; import { useColumnSchema } from '../../../../schema-component/antd/table-v2/Table.Column.Decorator'; import { SchemaSettingsDefaultValue } from '../../../../schema-settings/SchemaSettingsDefaultValue'; import { isPatternDisabled } from '../../../../schema-settings/isPatternDisabled'; -import { useFieldComponentName } from './utils'; export const tableColumnSettings = new SchemaSettings({ name: 'fieldSettings:TableColumn', diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/utils.tsx b/packages/core/client/src/modules/blocks/data-blocks/table/utils.tsx deleted file mode 100644 index 24c6b706e..000000000 --- a/packages/core/client/src/modules/blocks/data-blocks/table/utils.tsx +++ /dev/null @@ -1,31 +0,0 @@ -/** - * 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 { Field } from '@formily/core'; -import { useField, useFieldSchema } from '@formily/react'; -import { useIsFileField } from '../../../../schema-component'; -import { useColumnSchema } from '../../../../schema-component/antd/table-v2/Table.Column.Decorator'; - -export function useFieldComponentName(): string { - const { fieldSchema: tableColumnSchema, collectionField } = useColumnSchema(); - const field = useField(); - const isFileField = useIsFileField(); - const schema = useFieldSchema(); - const fieldSchema = tableColumnSchema || schema; - const map = { - // AssociationField 的 mode 默认值是 Select - AssociationField: 'Select', - }; - const fieldComponentName = - fieldSchema?.['x-component-props']?.['mode'] || - field?.componentProps?.['mode'] || - (isFileField ? 'FileManager' : '') || - collectionField?.uiSchema?.['x-component']; - return map[fieldComponentName] || fieldComponentName; -} diff --git a/packages/core/client/src/modules/fields/__e2e__/component/Input.Preview/basic.test.ts b/packages/core/client/src/modules/fields/__e2e__/component/Input.Preview/basic.test.ts new file mode 100644 index 000000000..efa3dce47 --- /dev/null +++ b/packages/core/client/src/modules/fields/__e2e__/component/Input.Preview/basic.test.ts @@ -0,0 +1,77 @@ +/** + * 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 { expect, test } from '@nocobase/test/e2e'; +import { oneFormAndOneTable } from '../../templates'; + +const img = 'https://static-docs.nocobase.com/logo-nocobase.png'; + +test.describe('Input.Preview', () => { + test('switch to Input.Preview from Input.URL', async ({ page, mockPage }) => { + await mockPage(oneFormAndOneTable).goto(); + + // 1. 在表单中的 URL 字段中输入图片地址 + await page.getByLabel('block-item-CollectionField-').getByRole('textbox').fill(img); + + // 2. 将组建切换到 Input.Preview + await page.getByLabel('block-item-CollectionField-').hover(); + await page.getByLabel('designer-schema-settings-CollectionField-fieldSettings:FormItem-general-general').hover(); + await page.getByRole('menuitem', { name: 'Field component URL' }).click(); + await page.getByRole('option', { name: 'Preview' }).click(); + + // 3. 图片正常显示 + await expect(page.getByLabel('block-item-CollectionField-').getByRole('img').first()).toHaveAttribute('src', img); + await expect(page.getByLabel('block-item-CollectionField-').getByRole('img').first()).toHaveJSProperty('width', 24); + + // 4. 切换图片大小到 Large,大小切换正常 + await page.getByLabel('block-item-CollectionField-').hover(); + await page.getByLabel('designer-schema-settings-CollectionField-fieldSettings:FormItem-general-general').hover(); + await page.getByRole('menuitem', { name: 'Size Small' }).click(); + await page.getByRole('option', { name: 'Large' }).click(); + await expect(page.getByLabel('block-item-CollectionField-').getByRole('img').first()).toHaveJSProperty('width', 72); + + // 5. 点击保存按钮,保存成功 + await page.getByLabel('action-Action-Submit-submit-').click(); + + // 6. Table 区块中显示图片链接 + await page.getByLabel('action-Action-Refresh-refresh').click(); + await expect(page.getByLabel('block-item-CardItem-general-table').getByRole('link', { name: img })).toBeVisible(); + + // 7. 将 Table 中的单元格组建切换到 Input.Preview,应该正常显示图片 + await page + .getByLabel('block-item-CardItem-general-table') + .getByRole('button', { name: 'url', exact: true }) + .hover(); + await page + .getByRole('button', { name: 'designer-schema-settings-TableV2.Column-fieldSettings:TableColumn-general' }) + .hover(); + await page.getByRole('menuitem', { name: 'Field component URL' }).click(); + await page.getByRole('option', { name: 'Preview' }).click(); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('cell').getByRole('img').first(), + ).toHaveAttribute('src', img); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('cell').getByRole('img').first(), + ).toHaveJSProperty('width', 24); + + // 8. 切换图片大小到 Large,大小切换正常 + await page + .getByLabel('block-item-CardItem-general-table') + .getByRole('button', { name: 'url', exact: true }) + .hover(); + await page + .getByRole('button', { name: 'designer-schema-settings-TableV2.Column-fieldSettings:TableColumn-general' }) + .hover(); + await page.getByRole('menuitem', { name: 'Size Small' }).click(); + await page.getByRole('option', { name: 'Large' }).click(); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('cell').getByRole('img').first(), + ).toHaveJSProperty('width', 72); + }); +}); diff --git a/packages/core/client/src/modules/fields/__e2e__/templates.ts b/packages/core/client/src/modules/fields/__e2e__/templates.ts new file mode 100644 index 000000000..21877d6b6 --- /dev/null +++ b/packages/core/client/src/modules/fields/__e2e__/templates.ts @@ -0,0 +1,380 @@ +/** + * 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. + */ + +// https://github.com/nocobase/nocobase/pull/4559 +export const oneFormAndOneTable = { + collections: [ + { + name: 'general', + fields: [ + { + interface: 'url', + name: 'url', + }, + ], + }, + ], + pageSchema: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Page', + 'x-index': 1, + properties: { + '4nbajnebmlr': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'page:addBlock', + 'x-index': 1, + properties: { + cf8uh9g697n: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + '1japwy7nj0k': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + ahp6bbaj61t: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-acl-action-props': { + skipScopeCheck: true, + }, + 'x-acl-action': 'general:create', + 'x-decorator': 'FormBlockProvider', + 'x-use-decorator-props': 'useCreateFormBlockDecoratorProps', + 'x-decorator-props': { + dataSource: 'main', + collection: 'general', + }, + 'x-toolbar': 'BlockSchemaToolbar', + 'x-settings': 'blockSettings:createForm', + 'x-component': 'CardItem', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + xgf2jpb0mwf: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'FormV2', + 'x-use-component-props': 'useCreateFormBlockProps', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'form:configureFields', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + yypv0ey12iv: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + '1qgv0svx6i0': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + url: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-toolbar': 'FormItemSchemaToolbar', + 'x-settings': 'fieldSettings:FormItem', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'general.url', + 'x-component-props': { + component: 'Input.URL', + }, + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + 'x-uid': '3d99xtkyxa7', + 'x-async': false, + }, + }, + 'x-uid': '4qa57usgxfr', + 'x-async': false, + }, + }, + 'x-uid': 'c4wm0124cvk', + 'x-async': false, + }, + }, + 'x-uid': 'heykz2e3s19', + 'x-async': false, + }, + '0tquv59oojr': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': 'createForm:configureActions', + 'x-component': 'ActionBar', + 'x-component-props': { + layout: 'one-column', + style: { + marginTop: 'var(--nb-spacing)', + }, + }, + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 2, + properties: { + f8subamq3yq: { + _isJSONSchemaObject: true, + version: '2.0', + title: '{{ t("Submit") }}', + 'x-action': 'submit', + 'x-component': 'Action', + 'x-use-component-props': 'useCreateActionProps', + 'x-toolbar': 'ActionSchemaToolbar', + 'x-settings': 'actionSettings:createSubmit', + 'x-component-props': { + type: 'primary', + htmlType: 'submit', + }, + 'x-action-settings': { + triggerWorkflows: [], + }, + type: 'void', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + 'x-uid': 'j1h5ugxq7nq', + 'x-async': false, + }, + }, + 'x-uid': '0r2mv62cvio', + 'x-async': false, + }, + }, + 'x-uid': 'em2t2fhaiw6', + 'x-async': false, + }, + }, + 'x-uid': 'tpwwr4b5p54', + 'x-async': false, + }, + }, + 'x-uid': 'aq7yxapodnw', + 'x-async': false, + }, + }, + 'x-uid': '1utnt4iy7th', + 'x-async': false, + }, + dqg82cp57e1: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 2, + properties: { + gqlczodkz2b: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + dlrpbn2z0zb: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableBlockProvider', + 'x-acl-action': 'general:list', + 'x-use-decorator-props': 'useTableBlockDecoratorProps', + 'x-decorator-props': { + collection: 'general', + dataSource: 'main', + action: 'list', + params: { + pageSize: 20, + }, + rowKey: 'id', + showIndex: true, + dragSort: false, + }, + 'x-toolbar': 'BlockSchemaToolbar', + 'x-settings': 'blockSettings:table', + 'x-component': 'CardItem', + 'x-filter-targets': [], + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': 'table:configureActions', + 'x-component': 'ActionBar', + 'x-component-props': { + style: { + marginBottom: 'var(--nb-spacing)', + }, + }, + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + h38nqwjf1zw: { + _isJSONSchemaObject: true, + version: '2.0', + title: '{{ t("Refresh") }}', + 'x-action': 'refresh', + 'x-component': 'Action', + 'x-use-component-props': 'useRefreshActionProps', + 'x-toolbar': 'ActionSchemaToolbar', + 'x-settings': 'actionSettings:refresh', + 'x-component-props': { + icon: 'ReloadOutlined', + }, + 'x-align': 'right', + type: 'void', + 'x-app-version': '1.0.0-alpha.17', + 'x-uid': '3ym5qa392m0', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'c6tw6pehj86', + 'x-async': false, + }, + tvde4dndsqj: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'array', + 'x-initializer': 'table:configureColumns', + 'x-component': 'TableV2', + 'x-use-component-props': 'useTableBlockProps', + 'x-component-props': { + rowKey: 'id', + rowSelection: { + type: 'checkbox', + }, + }, + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 2, + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("Actions") }}', + 'x-action-column': 'actions', + 'x-decorator': 'TableV2.Column.ActionBar', + 'x-component': 'TableV2.Column', + 'x-toolbar': 'TableColumnSchemaToolbar', + 'x-initializer': 'table:configureItemActions', + 'x-settings': 'fieldSettings:TableColumn', + 'x-toolbar-props': { + initializer: 'table:configureItemActions', + }, + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + properties: { + wptjn8efkdq: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'DndContext', + 'x-component': 'Space', + 'x-component-props': { + split: '|', + }, + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + 'x-uid': 'x89784q83t2', + 'x-async': false, + }, + }, + 'x-uid': '1yzn9sblzep', + 'x-async': false, + }, + raxcojsopou: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableV2.Column.Decorator', + 'x-toolbar': 'TableColumnSchemaToolbar', + 'x-settings': 'fieldSettings:TableColumn', + 'x-component': 'TableV2.Column', + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 2, + properties: { + url: { + _isJSONSchemaObject: true, + version: '2.0', + 'x-collection-field': 'general.url', + 'x-component': 'CollectionField', + 'x-component-props': {}, + 'x-read-pretty': true, + 'x-decorator': null, + 'x-decorator-props': { + labelStyle: { + display: 'none', + }, + }, + 'x-app-version': '1.0.0-alpha.17', + 'x-index': 1, + 'x-uid': 'qni0na740t1', + 'x-async': false, + }, + }, + 'x-uid': '5lq7abdz67x', + 'x-async': false, + }, + }, + 'x-uid': 'zc0cntdtdr4', + 'x-async': false, + }, + }, + 'x-uid': 'hbmp3k5e1i3', + 'x-async': false, + }, + }, + 'x-uid': 'jbxa0cnjm1w', + 'x-async': false, + }, + }, + 'x-uid': 'yqvfdsci5v8', + 'x-async': false, + }, + }, + 'x-uid': 'a1iy1sw0sus', + 'x-async': false, + }, + }, + 'x-uid': 'v3zv08v0hwn', + 'x-async': true, + }, +}; diff --git a/packages/core/client/src/modules/fields/component/Input.Preview/settings.ts b/packages/core/client/src/modules/fields/component/Input.Preview/settings.ts new file mode 100644 index 000000000..327ecfb99 --- /dev/null +++ b/packages/core/client/src/modules/fields/component/Input.Preview/settings.ts @@ -0,0 +1,56 @@ +/** + * 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 { Field } from '@formily/core'; +import { useField, useFieldSchema } from '@formily/react'; +import { useTranslation } from 'react-i18next'; +import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; +import { useColumnSchema, useDesignable } from '../../../../schema-component'; +import { fieldComponent } from '../Input.URL/settings'; + +const size = { + name: 'size', + type: 'select', + useComponentProps() { + const { t } = useTranslation(); + const field = useField(); + const schema = useFieldSchema(); + const { fieldSchema: tableColumnSchema } = useColumnSchema(); + const fieldSchema = tableColumnSchema || schema; + const { dn } = useDesignable(); + return { + title: t('Size'), + options: [ + { value: 'small', label: 'Small' }, + { value: 'middle', label: 'Middle' }, + { value: 'large', label: 'Large' }, + { value: 'auto', label: 'Auto' }, + ], + value: fieldSchema['x-component-props']?.['size'] || 'small', + onChange(size) { + const schema = { + ['x-uid']: fieldSchema['x-uid'], + }; + fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {}; + fieldSchema['x-component-props']['size'] = size; + schema['x-component-props'] = fieldSchema['x-component-props']; + field.componentProps = field.componentProps || {}; + field.componentProps.size = size; + dn.emit('patch', { + schema, + }); + }, + }; + }, +}; + +export const inputPreviewComponentFieldSettings = new SchemaSettings({ + name: 'fieldSettings:component:Input.Preview', + items: [fieldComponent, size], +}); diff --git a/packages/core/client/src/modules/fields/component/Input.URL/settings.ts b/packages/core/client/src/modules/fields/component/Input.URL/settings.ts new file mode 100644 index 000000000..c07c4eb30 --- /dev/null +++ b/packages/core/client/src/modules/fields/component/Input.URL/settings.ts @@ -0,0 +1,51 @@ +/** + * 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 { Field } from '@formily/core'; +import { useField, useFieldSchema } from '@formily/react'; +import _ from 'lodash'; +import { useTranslation } from 'react-i18next'; +import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; +import { useColumnSchema, useDesignable } from '../../../../schema-component'; + +export const fieldComponent: any = { + name: 'fieldComponent', + type: 'select', + useComponentProps() { + const { t } = useTranslation(); + const field = useField(); + const schema = useFieldSchema(); + const { fieldSchema: tableColumnSchema } = useColumnSchema(); + const fieldSchema = tableColumnSchema || schema; + const { dn } = useDesignable(); + return { + title: t('Field component'), + options: [ + { value: 'Input.URL', label: 'URL' }, + { value: 'Input.Preview', label: 'Preview' }, + ], + value: fieldSchema['x-component-props']?.['component'] || 'Input.URL', + onChange(component) { + _.set(fieldSchema, 'x-component-props.component', component); + field.componentProps.component = component; + dn.emit('patch', { + schema: { + ['x-uid']: fieldSchema['x-uid'], + 'x-component-props': fieldSchema['x-component-props'], + }, + }); + }, + }; + }, +}; + +export const inputURLComponentFieldSettings = new SchemaSettings({ + name: 'fieldSettings:component:Input.URL', + items: [fieldComponent], +}); diff --git a/packages/core/client/src/schema-component/antd/input/Input.tsx b/packages/core/client/src/schema-component/antd/input/Input.tsx index 6a6ea063e..1a7a072ca 100644 --- a/packages/core/client/src/schema-component/antd/input/Input.tsx +++ b/packages/core/client/src/schema-component/antd/input/Input.tsx @@ -13,7 +13,7 @@ import { Input as AntdInput } from 'antd'; import { InputProps, TextAreaProps } from 'antd/es/input'; import React from 'react'; import { JSONTextAreaProps, Json } from './Json'; -import { ReadPretty, InputReadPrettyComposed } from './ReadPretty'; +import { InputReadPrettyComposed, ReadPretty } from './ReadPretty'; export { ReadPretty as InputReadPretty } from './ReadPretty'; @@ -52,6 +52,7 @@ export const Input: ComposedInput = Object.assign( URL: connect(AntdInput, mapReadPretty(ReadPretty.URL)), JSON: connect(Json, mapReadPretty(ReadPretty.JSON)), ReadPretty: ReadPretty.Input, + Preview: ReadPretty.Preview, } as unknown as ComposedInput, ); diff --git a/packages/core/client/src/schema-component/antd/input/ReadPretty.tsx b/packages/core/client/src/schema-component/antd/input/ReadPretty.tsx index 30bec6bad..15956c5fe 100644 --- a/packages/core/client/src/schema-component/antd/input/ReadPretty.tsx +++ b/packages/core/client/src/schema-component/antd/input/ReadPretty.tsx @@ -9,16 +9,18 @@ import { css, cx } from '@emotion/css'; import { usePrefixCls } from '@formily/antd-v5/esm/__builtins__'; -import { Typography } from 'antd'; +import { useFieldSchema } from '@formily/react'; +import { Image, Typography } from 'antd'; import cls from 'classnames'; import React from 'react'; +import { useCompile } from '../../hooks'; import { EllipsisWithTooltip } from './EllipsisWithTooltip'; import { HTMLEncode } from './shared'; -import { useCompile } from '../../hooks'; export type InputReadPrettyComposed = { Input: React.FC; URL: React.FC; + Preview: React.FC; TextArea: React.FC; Html: React.FC; JSON: React.FC; @@ -186,6 +188,33 @@ ReadPretty.URL = (props) => { ); }; +ReadPretty.Preview = function Preview(props: any) { + const fieldSchema = useFieldSchema(); + const size = fieldSchema['x-component-props']?.['size'] || 'small'; + if (!props.value) { + return props.value; + } + const sizes = { + small: 24, + middle: 48, + large: 72, + }; + return ( + + ); +}; + export interface JSONTextAreaReadPrettyProps { value?: any; className?: string; diff --git a/packages/core/client/src/schema-settings/SchemaSettingsPlugin.ts b/packages/core/client/src/schema-settings/SchemaSettingsPlugin.ts index 738b07218..f15adb76a 100644 --- a/packages/core/client/src/schema-settings/SchemaSettingsPlugin.ts +++ b/packages/core/client/src/schema-settings/SchemaSettingsPlugin.ts @@ -16,13 +16,13 @@ import { deleteActionSettings } from '../modules/actions/delete/deleteActionSett import { disassociateActionSettings } from '../modules/actions/disassociate/disassociateActionSettings'; import { expendableActionSettings } from '../modules/actions/expand-collapse/expendableActionSettings'; import { filterActionSettings } from '../modules/actions/filter/filterActionSettings'; +import { customizeLinkActionSettings } from '../modules/actions/link/customizeLinkActionSettings'; import { refreshActionSettings } from '../modules/actions/refresh/refreshActionSettings'; import { customizeSaveRecordActionSettings } from '../modules/actions/save-record/customizeSaveRecordActionSettings'; import { createSubmitActionSettings } from '../modules/actions/submit/createSubmitActionSettings'; import { submitActionSettings, updateSubmitActionSettings } from '../modules/actions/submit/updateSubmitActionSettings'; import { customizeUpdateRecordActionSettings } from '../modules/actions/update-record/customizeUpdateRecordActionSettings'; import { customizePopupActionSettings } from '../modules/actions/view-edit-popup/customizePopupActionSettings'; -import { customizeLinkActionSettings } from '../modules/actions/link/customizeLinkActionSettings'; import { editActionSettings } from '../modules/actions/view-edit-popup/editActionSettings'; import { viewActionSettings } from '../modules/actions/view-edit-popup/viewActionSettings'; @@ -52,6 +52,8 @@ import { datePickerComponentFieldSettings } from '../modules/fields/component/Da import { fileManagerComponentFieldSettings } from '../modules/fields/component/FileManager/fileManagerComponentFieldSettings'; import { previewComponentFieldSettings } from '../modules/fields/component/FileManager/previewComponentFieldSettings'; import { uploadAttachmentComponentFieldSettings } from '../modules/fields/component/FileManager/uploadAttachmentComponentFieldSettings'; +import { inputPreviewComponentFieldSettings } from '../modules/fields/component/Input.Preview/settings'; +import { inputURLComponentFieldSettings } from '../modules/fields/component/Input.URL/settings'; import { inputNumberComponentFieldSettings } from '../modules/fields/component/InputNumber/inputNumberComponentFieldSettings'; import { subformComponentFieldSettings } from '../modules/fields/component/Nester/subformComponentFieldSettings'; import { recordPickerComponentFieldSettings } from '../modules/fields/component/Picker/recordPickerComponentFieldSettings'; @@ -117,6 +119,8 @@ export class SchemaSettingsPlugin extends Plugin { this.schemaSettingsManager.add(fileManagerComponentFieldSettings); this.schemaSettingsManager.add(tagComponentFieldSettings); this.schemaSettingsManager.add(cascadeSelectComponentFieldSettings); + this.schemaSettingsManager.add(inputPreviewComponentFieldSettings); + this.schemaSettingsManager.add(inputURLComponentFieldSettings); this.schemaSettingsManager.add(uploadAttachmentComponentFieldSettings); this.schemaSettingsManager.add(previewComponentFieldSettings); }