import { FormOutlined, TableOutlined } from '@ant-design/icons'; import { FormDialog, FormLayout } from '@formily/antd'; import { ISchema, SchemaOptionsContext } from '@formily/react'; import { merge } from '@formily/shared'; import React, { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { useAPIClient } from '../../api-client'; import { useBlockAssociationContext } from '../../block-provider'; import { useCollection, useCollectionManager } from '../../collection-manager'; import { SchemaComponent, SchemaComponentOptions } from '../../schema-component'; import { useSchemaTemplateManager } from '../../schema-templates'; import { SchemaInitializer } from '../SchemaInitializer'; import { createCalendarBlockSchema, createDetailsBlockSchema, createFormBlockSchema, createKanbanBlockSchema, createReadPrettyFormBlockSchema, createTableBlockSchema, createTableSelectorSchema, useCollectionDataSourceItems, useCurrentSchema, useRecordCollectionDataSourceItems } from '../utils'; // Block export const BlockInitializer = (props) => { const { item, insert } = props; return ( { insert({ ...item.schema, }); }} /> ); }; export const CustomizeActionInitializer = (props) => { return ; }; export const InitializerWithSwitch = (props) => { const { type, schema, item, insert } = props; const { exists, remove } = useCurrentSchema(schema?.[type] || item?.schema?.[type], type, item.find, item.remove); return ( { if (exists) { return remove(); } const s = merge(schema || {}, item.schema || {}); item?.schemaInitialize?.(s); insert(s); }} /> ); }; export const ActionInitializer = (props) => { return ; }; export const DataBlockInitializer = (props) => { const { templateWrap, onCreateBlockSchema, componentType, createBlockSchema, insert, ...others } = props; const { getTemplateSchemaByMode } = useSchemaTemplateManager(); return ( } {...others} onClick={async ({ item }) => { if (item.template) { const s = await getTemplateSchemaByMode(item); templateWrap ? insert(templateWrap(s, { item })) : insert(s); } else { if (onCreateBlockSchema) { onCreateBlockSchema({ item }); } else if (createBlockSchema) { insert(createBlockSchema({ collection: item.name })); } } }} items={useCollectionDataSourceItems(componentType)} /> ); }; export const TableBlockInitializer = (props) => { const { insert } = props; const { getCollection } = useCollectionManager(); return ( } componentType={'Table'} onCreateBlockSchema={async ({ item }) => { const collection = getCollection(item.name); const schema = createTableBlockSchema({ collection: item.name, rowKey: collection.filterTargetKey || 'id' }); insert(schema); }} /> ); }; export const FormBlockInitializer = (props) => { return ( } componentType={'FormItem'} templateWrap={(templateSchema, { item }) => { const s = createFormBlockSchema({ template: templateSchema, collection: item.name, }); if (item.template && item.mode === 'reference') { s['x-template-key'] = item.template.key; } return s; }} createBlockSchema={createFormBlockSchema} /> ); }; export const DetailsBlockInitializer = (props) => { const { insert } = props; const { getCollection } = useCollectionManager(); return ( } componentType={'Details'} onCreateBlockSchema={async ({ item }) => { const collection = getCollection(item.name); const schema = createDetailsBlockSchema({ collection: item.name, rowKey: collection.filterTargetKey || 'id' }); insert(schema); }} /> ); }; export const CalendarBlockInitializer = (props) => { const { insert } = props; const { t } = useTranslation(); const { getCollection } = useCollectionManager(); const options = useContext(SchemaOptionsContext); return ( } onCreateBlockSchema={async ({ item }) => { const collection = getCollection(item.name); const stringFields = collection?.fields ?.filter((field) => field.type === 'string') ?.map((field) => { return { label: field?.uiSchema?.title, value: field.name, }; }); const dateFields = collection?.fields ?.filter((field) => field.type === 'date') ?.map((field) => { return { label: field?.uiSchema?.title, value: field.name, }; }); const values = await FormDialog(t('Create calendar block'), () => { return ( ); }).open({ initialValues: {}, }); insert( createCalendarBlockSchema({ collection: item.name, fieldNames: { ...values, }, }), ); }} /> ); }; export const KanbanBlockInitializer = (props) => { const { insert } = props; const { t } = useTranslation(); const { getCollection } = useCollectionManager(); const options = useContext(SchemaOptionsContext); const api = useAPIClient(); return ( } onCreateBlockSchema={async ({ item }) => { const collection = getCollection(item.name); const fields = collection?.fields ?.filter((field) => ['select', 'radioGroup'].includes(field.interface)) ?.map((field) => { return { label: field?.uiSchema?.title, value: field.name, uiSchema: { ...field.uiSchema, name: field.name, }, }; }); const values = await FormDialog(t('Create kanban block'), () => { return ( ); }).open({ initialValues: {}, }); const sortName = `${values.groupField.value}_sort`; const exists = collection?.fields?.find((field) => field.name === sortName); if (!exists) { await api.resource('collections.fields', item.name).create({ values: { type: 'sort', name: sortName, hidden: true, scopeKey: values.groupField.value, }, }); } insert( createKanbanBlockSchema({ groupField: values.groupField.value, collection: item.name, params: { sort: [sortName], paginate: false, }, }), ); }} /> ); }; export const MarkdownBlockInitializer = (props) => { const { insert } = props; const { t } = useTranslation(); return ( } onClick={() => { insert({ type: 'void', 'x-designer': 'Markdown.Void.Designer', 'x-decorator': 'CardItem', 'x-component': 'Markdown.Void', 'x-editable': false, 'x-component-props': { content: t('This is a demo text, **supports Markdown syntax**.'), }, }); }} /> ); }; export const FilterActionInitializer = (props) => { const schema = { type: 'void', title: '{{ t("Filter") }}', 'x-action': 'filter', 'x-designer': 'Filter.Action.Designer', 'x-component': 'Filter.Action', 'x-component-props': { icon: 'FilterOutlined', useProps: '{{ useFilterActionProps }}', }, }; return ; }; export const CreateActionInitializer = (props) => { const schema = { type: 'void', title: '{{ t("Add new") }}', 'x-action': 'create', 'x-designer': 'Action.Designer', 'x-component': 'Action', 'x-component-props': { icon: 'PlusOutlined', openMode: 'drawer', type: 'primary', }, properties: { drawer: { type: 'void', title: '{{ t("Add record") }}', 'x-component': 'Action.Container', 'x-component-props': { className: 'nb-action-popup', }, properties: { grid: { type: 'void', 'x-component': 'Grid', 'x-initializer': 'CreateFormBlockInitializers', properties: {}, }, }, }, }, }; return ; }; export const ViewActionInitializer = (props) => { const schema = { type: 'void', title: '{{ t("View") }}', 'x-action': 'view', 'x-designer': 'Action.Designer', 'x-component': 'Action', 'x-component-props': { openMode: 'drawer', }, properties: { drawer: { type: 'void', title: '{{ t("View record") }}', 'x-component': 'Action.Container', 'x-component-props': { className: 'nb-action-popup', }, properties: { tabs: { type: 'void', 'x-component': 'Tabs', 'x-component-props': {}, 'x-initializer': 'TabPaneInitializers', properties: { tab1: { type: 'void', title: '{{t("Details")}}', 'x-component': 'Tabs.TabPane', 'x-designer': 'Tabs.Designer', 'x-component-props': {}, properties: { grid: { type: 'void', 'x-component': 'Grid', 'x-initializer': 'RecordBlockInitializers', properties: {}, }, }, }, }, }, }, }, }, }; return ; }; export const UpdateActionInitializer = (props) => { const schema = { type: 'void', title: '{{ t("Edit") }}', 'x-action': 'update', 'x-designer': 'Action.Designer', 'x-component': 'Action', 'x-component-props': { openMode: 'drawer', icon: 'EditOutlined', }, properties: { drawer: { type: 'void', title: '{{ t("Edit record") }}', 'x-component': 'Action.Container', 'x-component-props': { className: 'nb-action-popup', }, properties: { tabs: { type: 'void', 'x-component': 'Tabs', 'x-component-props': {}, 'x-initializer': 'TabPaneInitializers', properties: { tab1: { type: 'void', title: '{{t("Edit")}}', 'x-component': 'Tabs.TabPane', 'x-designer': 'Tabs.Designer', 'x-component-props': {}, properties: { grid: { type: 'void', 'x-component': 'Grid', 'x-initializer': 'RecordBlockInitializers', properties: {}, }, }, }, }, }, }, }, }, }; return ; }; export const DestroyActionInitializer = (props) => { const schema = { title: '{{ t("Delete") }}', 'x-action': 'destroy', 'x-component': 'Action', 'x-designer': 'Action.Designer', 'x-component-props': { icon: 'DeleteOutlined', confirm: { title: "{{t('Delete record')}}", content: "{{t('Are you sure you want to delete it?')}}", }, useProps: '{{ useDestroyActionProps }}', }, }; return ; }; export const BulkDestroyActionInitializer = (props) => { const schema = { title: '{{ t("Delete") }}', 'x-action': 'destroy', 'x-component': 'Action', 'x-designer': 'Action.Designer', 'x-component-props': { icon: 'DeleteOutlined', confirm: { title: "{{t('Delete record')}}", content: "{{t('Are you sure you want to delete it?')}}", }, useProps: '{{ useBulkDestroyActionProps }}', }, }; return ; }; export const SubmitActionInitializer = (props) => { const schema = { title: '{{ t("Submit") }}', 'x-action': 'submit', 'x-component': 'Action', 'x-designer': 'Action.Designer', 'x-component-props': { type: 'primary', htmlType: 'submit', // useProps: '{{ bp.useSubmitActionProps }}', }, }; return ; }; export const CreateSubmitActionInitializer = (props) => { const schema = { title: '{{ t("Submit") }}', 'x-action': 'submit', 'x-component': 'Action', 'x-designer': 'Action.Designer', 'x-component-props': { type: 'primary', htmlType: 'submit', useProps: '{{ useCreateActionProps }}', }, }; return ; }; export const UpdateSubmitActionInitializer = (props) => { const schema = { title: '{{ t("Submit") }}', 'x-action': 'submit', 'x-component': 'Action', 'x-designer': 'Action.Designer', 'x-component-props': { type: 'primary', htmlType: 'submit', useProps: '{{ useUpdateActionProps }}', }, }; return ; }; export const CreateFormBlockInitializer = (props) => { const { onCreateBlockSchema, componentType, createBlockSchema, insert, ...others } = props; const { getTemplateSchemaByMode } = useSchemaTemplateManager(); const association = useBlockAssociationContext(); const collection = useCollection(); return ( } {...others} onClick={async ({ item }) => { if (item.template) { const s = await getTemplateSchemaByMode(item); if (item.template.componentName === 'FormItem') { const blockSchema = createFormBlockSchema({ actionInitializers: 'CreateFormActionInitializers', association, collection: collection.name, template: s, }); if (item.mode === 'reference') { blockSchema['x-template-key'] = item.template.key; } insert(blockSchema); } else { insert(s); } } else { insert( createFormBlockSchema({ actionInitializers: 'CreateFormActionInitializers', association, collection: collection.name, }), ); } }} items={useRecordCollectionDataSourceItems('FormItem')} /> ); }; export const RecordFormBlockInitializer = (props) => { const { onCreateBlockSchema, componentType, createBlockSchema, insert, ...others } = props; const { getTemplateSchemaByMode } = useSchemaTemplateManager(); const collection = useCollection(); const association = useBlockAssociationContext(); return ( } {...others} onClick={async ({ item }) => { if (item.template) { const s = await getTemplateSchemaByMode(item); if (item.template.componentName === 'FormItem') { const blockSchema = createFormBlockSchema({ association, collection: collection.name, action: 'get', useSourceId: '{{ useSourceIdFromParentRecord }}', useParams: '{{ useParamsFromRecord }}', actionInitializers: 'UpdateFormActionInitializers', template: s, }); if (item.mode === 'reference') { blockSchema['x-template-key'] = item.template.key; } insert(blockSchema); } else { insert(s); } } else { insert( createFormBlockSchema({ association, collection: collection.name, action: 'get', useSourceId: '{{ useSourceIdFromParentRecord }}', useParams: '{{ useParamsFromRecord }}', actionInitializers: 'UpdateFormActionInitializers', }), ); } }} items={useRecordCollectionDataSourceItems('FormItem')} /> ); }; export const RecordReadPrettyFormBlockInitializer = (props) => { const { onCreateBlockSchema, componentType, createBlockSchema, insert, ...others } = props; const { getTemplateSchemaByMode } = useSchemaTemplateManager(); const collection = useCollection(); const association = useBlockAssociationContext(); return ( } {...others} onClick={async ({ item }) => { if (item.template) { const s = await getTemplateSchemaByMode(item); if (item.template.componentName === 'ReadPrettyFormItem') { const blockSchema = createReadPrettyFormBlockSchema({ association, collection: collection.name, action: 'get', useSourceId: '{{ useSourceIdFromParentRecord }}', useParams: '{{ useParamsFromRecord }}', template: s, }); if (item.mode === 'reference') { blockSchema['x-template-key'] = item.template.key; } insert(blockSchema); } else { insert(s); } } else { insert( createReadPrettyFormBlockSchema({ association, collection: collection.name, action: 'get', useSourceId: '{{ useSourceIdFromParentRecord }}', useParams: '{{ useParamsFromRecord }}', }), ); } }} items={useRecordCollectionDataSourceItems('ReadPrettyFormItem')} /> ); }; export const RecordAssociationBlockInitializer = (props) => { const { item, onCreateBlockSchema, componentType, createBlockSchema, insert, ...others } = props; const { getTemplateSchemaByMode } = useSchemaTemplateManager(); const { getCollection } = useCollectionManager(); return ( } {...others} onClick={async ({ item }) => { console.log('RecordAssociationBlockInitializer', item); const field = item.field; const collection = getCollection(field.target); insert( createTableBlockSchema({ rowKey: collection.filterTargetKey, collection: field.target, resource: `${field.collectionName}.${field.name}`, association: `${field.collectionName}.${field.name}`, }), ); // if (item.template) { // const s = await getTemplateSchemaByMode(item); // insert(s); // } else { // insert(createTableBlockSchema({ collection: item.name })); // } }} // items={useRecordCollectionDataSourceItems('Table')} /> ); }; export const TableActionColumnInitializer = (props) => { const schema = { type: 'void', title: '{{ t("Actions") }}', 'x-decorator': 'TableV2.Column.ActionBar', 'x-component': 'TableV2.Column', 'x-designer': 'TableV2.ActionColumnDesigner', 'x-initializer': 'TableActionColumnInitializers', 'x-action-column': 'actions', properties: { actions: { type: 'void', 'x-decorator': 'DndContext', 'x-component': 'Space', 'x-component-props': { split: '|', }, properties: {}, }, }, }; return ; }; export const TableCollectionFieldInitializer = (props) => { const schema: ISchema = {}; return ; }; export const CollectionFieldInitializer = (props) => { const schema: ISchema = {}; return ; }; export const TableSelectorInitializer = (props) => { const { onCreateBlockSchema, componentType, createBlockSchema, insert, ...others } = props; const { getTemplateSchemaByMode } = useSchemaTemplateManager(); const collection = useCollection(); return ( } {...others} onClick={async ({ item }) => { const field = item.field; insert( createTableSelectorSchema({ rowKey: collection.filterTargetKey, collection: collection.name, resource: collection.name, }), ); }} /> ); };