From 0480b57db5e5e153dded895667f7c44165abc2dd Mon Sep 17 00:00:00 2001 From: chenos Date: Fri, 9 Dec 2022 23:29:54 +0800 Subject: [PATCH] feat: iframe block (#1225) --- packages/core/client/package.json | 1 + packages/core/client/src/locale/en_US.ts | 1 + packages/core/client/src/locale/zh_CN.ts | 1 + .../common/iframe/Iframe.Designer.tsx | 66 +++++++++++++++++++ .../schema-component/common/iframe/index.tsx | 39 +++++++++++ .../src/schema-component/common/index.ts | 1 + .../buttons/BlockInitializers.tsx | 6 ++ .../items/IframeBlockInitializer.tsx | 25 +++++++ .../src/schema-initializer/items/index.tsx | 4 +- 9 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 packages/core/client/src/schema-component/common/iframe/Iframe.Designer.tsx create mode 100644 packages/core/client/src/schema-component/common/iframe/index.tsx create mode 100644 packages/core/client/src/schema-initializer/items/IframeBlockInitializer.tsx diff --git a/packages/core/client/package.json b/packages/core/client/package.json index fb7a6ee25..c35d91df9 100644 --- a/packages/core/client/package.json +++ b/packages/core/client/package.json @@ -34,6 +34,7 @@ "mathjs": "^10.6.0", "react-beautiful-dnd": "^13.1.0", "react-big-calendar": "^0.38.7", + "react-iframe": "~1.8.5", "react-contenteditable": "^3.3.6", "react-drag-listview": "^0.1.9", "react-helmet": "^6.1.0", diff --git a/packages/core/client/src/locale/en_US.ts b/packages/core/client/src/locale/en_US.ts index 7c3454bd8..528c6bcd9 100644 --- a/packages/core/client/src/locale/en_US.ts +++ b/packages/core/client/src/locale/en_US.ts @@ -510,4 +510,5 @@ export default { "Selector": "Selector", "Inner": "Inner", "Search and select collection": "Search and select collection", + 'Please fill in the iframe URL': 'Please fill in the iframe URL', } diff --git a/packages/core/client/src/locale/zh_CN.ts b/packages/core/client/src/locale/zh_CN.ts index d42d84565..7a5169cad 100644 --- a/packages/core/client/src/locale/zh_CN.ts +++ b/packages/core/client/src/locale/zh_CN.ts @@ -626,4 +626,5 @@ export default { "Selector": "选择器", "Inner": "里面", "Search and select collection": "搜索并选择数据表", + 'Please fill in the iframe URL': '请填写嵌入的地址', } diff --git a/packages/core/client/src/schema-component/common/iframe/Iframe.Designer.tsx b/packages/core/client/src/schema-component/common/iframe/Iframe.Designer.tsx new file mode 100644 index 000000000..0b4505cea --- /dev/null +++ b/packages/core/client/src/schema-component/common/iframe/Iframe.Designer.tsx @@ -0,0 +1,66 @@ +import { ISchema, useField, useFieldSchema } from '@formily/react'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings'; +import { useDesignable } from '../../hooks'; + +export const IframeDesigner = () => { + const field = useField(); + const fieldSchema = useFieldSchema(); + const { t } = useTranslation(); + const { dn } = useDesignable(); + + return ( + + { + field.componentProps.url = url; + field.componentProps.height = height; + const componentProps = fieldSchema['x-component-props'] || {}; + componentProps['url'] = url; + componentProps['height'] = height; + fieldSchema['x-component-props'] = componentProps; + dn.emit('patch', { + schema: { + 'x-uid': fieldSchema['x-uid'], + 'x-component-props': componentProps, + }, + }); + }} + /> + + + + ); +}; diff --git a/packages/core/client/src/schema-component/common/iframe/index.tsx b/packages/core/client/src/schema-component/common/iframe/index.tsx new file mode 100644 index 000000000..b434d123f --- /dev/null +++ b/packages/core/client/src/schema-component/common/iframe/index.tsx @@ -0,0 +1,39 @@ +import { observer } from '@formily/react'; +import { Card } from 'antd'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import RIframe from 'react-iframe'; +import type { IIframe } from 'react-iframe/types'; +import { IframeDesigner } from './Iframe.Designer'; + +function isNumeric(str: string) { + if (typeof str !== 'string') return false; // we only process strings! + return ( + !isNaN(str as any) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)... + !isNaN(parseFloat(str)) + ); // ...and ensure strings of whitespace fail +} + +export const Iframe: any = observer((props: IIframe) => { + const { url, height, ...others } = props; + const { t } = useTranslation(); + if (!url) { + return {t('Please fill in the iframe URL')}; + } + return ( + + ); +}); + +Iframe.Designer = IframeDesigner; diff --git a/packages/core/client/src/schema-component/common/index.ts b/packages/core/client/src/schema-component/common/index.ts index e1b472059..ba61b9f1c 100644 --- a/packages/core/client/src/schema-component/common/index.ts +++ b/packages/core/client/src/schema-component/common/index.ts @@ -1,3 +1,4 @@ export * from './dnd-context'; +export * from './iframe'; export * from './sortable-item'; diff --git a/packages/core/client/src/schema-initializer/buttons/BlockInitializers.tsx b/packages/core/client/src/schema-initializer/buttons/BlockInitializers.tsx index c7f3b0b46..d00f42fea 100644 --- a/packages/core/client/src/schema-initializer/buttons/BlockInitializers.tsx +++ b/packages/core/client/src/schema-initializer/buttons/BlockInitializers.tsx @@ -164,6 +164,12 @@ export const BlockInitializers = { title: '{{t("Markdown")}}', component: 'MarkdownBlockInitializer', }, + { + key: 'iframe', + type: 'item', + title: '{{t("Iframe")}}', + component: 'IframeBlockInitializer', + }, { key: 'auditLogs', type: 'item', diff --git a/packages/core/client/src/schema-initializer/items/IframeBlockInitializer.tsx b/packages/core/client/src/schema-initializer/items/IframeBlockInitializer.tsx new file mode 100644 index 000000000..7994a3c9f --- /dev/null +++ b/packages/core/client/src/schema-initializer/items/IframeBlockInitializer.tsx @@ -0,0 +1,25 @@ +import { FormOutlined } from '@ant-design/icons'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { SchemaInitializer } from '../SchemaInitializer'; + +export const IframeBlockInitializer = (props) => { + const { insert } = props; + const { t } = useTranslation(); + return ( + } + onClick={() => { + insert({ + type: 'void', + 'x-designer': 'Iframe.Designer', + 'x-decorator': 'BlockItem', + 'x-component': 'Iframe', + 'x-component-props': {}, + }); + }} + /> + ); +}; diff --git a/packages/core/client/src/schema-initializer/items/index.tsx b/packages/core/client/src/schema-initializer/items/index.tsx index 64d99cef7..ecef69bc1 100644 --- a/packages/core/client/src/schema-initializer/items/index.tsx +++ b/packages/core/client/src/schema-initializer/items/index.tsx @@ -11,12 +11,13 @@ export * from './CreateSubmitActionInitializer'; export * from './CustomizeActionInitializer'; export * from './CustomizeBulkEditActionInitializer'; export * from './DataBlockInitializer'; -export * from './DestroyActionInitializer'; export * from './DeleteEventActionInitializer'; +export * from './DestroyActionInitializer'; export * from './DetailsBlockInitializer'; export * from './FilterActionInitializer'; export * from './FormBlockInitializer'; export * from './G2PlotInitializer'; +export * from './IframeBlockInitializer'; export * from './InitializerWithSwitch'; export * from './KanbanBlockInitializer'; export * from './MarkdownBlockInitializer'; @@ -37,3 +38,4 @@ export * from './TableSelectorInitializer'; export * from './UpdateActionInitializer'; export * from './UpdateSubmitActionInitializer'; export * from './ViewActionInitializer'; +