feat: duplicate action (#1973)

* feat: depulicate action

* feat: depulicate action

* refactor: duplicate action

* refactor: duplicate action

* refactor: duplicate action

* refactor:  support quick duplicate

* refactor: local improve

* refactor: local improve

* fix: duplicate intialValue

* refactor: detail action support duplicate

* refactor: action role check

* fix: duplicate support linkage rule

* fix: duplicate action support openMode and openSize

* fix: duplicate action support linkage rule

* refactor: locale

* refactor: detail block support duplicate action

* refactor: code improve

* refactor: code improve

* refactor: duplicate action improve

* refactor:  wait time after click is too long, a Duplicating is required

---------

Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
katherinehhh 2023-06-07 11:25:32 +08:00 committed by GitHub
parent 8809df3f51
commit c3c02d8925
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 379 additions and 73 deletions

View File

@ -689,4 +689,9 @@ export default {
"Feedback": "Feedback", "Feedback": "Feedback",
"Try again": "Try again", "Try again": "Try again",
"Data template": "Data template", "Data template": "Data template",
"Duplicate":"Duplicate",
"Duplicate mode":"Duplicate mode",
"Quick duplicate":"Quick duplicate",
"Duplicate and continue":"Duplicate and continue",
"Please configure the duplicate fields":"Please configure the duplicate fields"
}; };

View File

@ -600,4 +600,9 @@ export default {
'Display data template selector': 'データテンプレートセレクターを表示', 'Display data template selector': 'データテンプレートセレクターを表示',
'Form data templates': 'フォームデータテンプレート', 'Form data templates': 'フォームデータテンプレート',
"Data template": "データテンプレート", "Data template": "データテンプレート",
"Duplicate":"レプリケーション",
"Duplicate mode":"コピーモード",
"Quick duplicate":"今すぐコピー",
"Duplicate and continue":"コピーして続行",
"Please configure the duplicate fields":"コピーするフィールドを設定してください"
} }

View File

@ -765,4 +765,9 @@ export default {
'The will interrupt service, it may take a few seconds to restart. Are you sure to continue?': '重启将会中断当前服务,这个过程可能需要一点时间,确定要继续吗?', 'The will interrupt service, it may take a few seconds to restart. Are you sure to continue?': '重启将会中断当前服务,这个过程可能需要一点时间,确定要继续吗?',
'Reboot': '重启', 'Reboot': '重启',
'Clear cache': '清除缓存', 'Clear cache': '清除缓存',
"Duplicate":"复制",
"Duplicate mode":"复制方式",
"Quick duplicate":"快速复制",
"Duplicate and continue":"复制并继续",
"Please configure the duplicate fields":"请配置要复制的字段"
} }

View File

@ -1,6 +1,7 @@
import { ISchema, useField, useFieldSchema } from '@formily/react'; import { ISchema, useField, useFieldSchema, connect, mapProps } from '@formily/react';
import { isValid, uid } from '@formily/shared'; import { isValid, uid } from '@formily/shared';
import { Menu } from 'antd'; import { Menu, Tree as AntdTree } from 'antd';
import { cloneDeep } from 'lodash';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useDesignable } from '../..'; import { useDesignable } from '../..';
@ -8,9 +9,20 @@ import { useCollection, useCollectionManager } from '../../../collection-manager
import { OpenModeSchemaItems } from '../../../schema-items'; import { OpenModeSchemaItems } from '../../../schema-items';
import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings'; import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings';
import { useLinkageAction } from './hooks'; import { useLinkageAction } from './hooks';
import { useCollectionState } from '../../../schema-settings/DataTemplates/hooks/useCollectionState';
import { requestSettingsSchema } from './utils'; import { requestSettingsSchema } from './utils';
const Tree = connect(
AntdTree,
mapProps((props, field: any) => {
return {
...props,
onCheck: (checkedKeys) => {
field.value = checkedKeys;
},
};
}),
);
const MenuGroup = (props) => { const MenuGroup = (props) => {
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const actionType = fieldSchema['x-action'] || ''; const actionType = fieldSchema['x-action'] || '';
@ -41,19 +53,22 @@ export const ActionDesigner = (props) => {
const field = useField(); const field = useField();
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const { name } = useCollection(); const { name } = useCollection();
const { getChildrenCollections } = useCollectionManager(); const { getChildrenCollections, getCollection, getCollectionField } = useCollectionManager();
const { dn } = useDesignable(); const { dn } = useDesignable();
const { t } = useTranslation(); const { t } = useTranslation();
const isAction = useLinkageAction(); const isAction = useLinkageAction();
const isPopupAction = ['create', 'update', 'view', 'customize:popup'].includes(fieldSchema['x-action'] || ''); const isPopupAction = ['create', 'update', 'view', 'customize:popup','duplicate'].includes(fieldSchema['x-action'] || '');
const isUpdateModePopupAction = ['customize:bulkUpdate', 'customize:bulkEdit'].includes(fieldSchema['x-action']); const isUpdateModePopupAction = ['customize:bulkUpdate', 'customize:bulkEdit'].includes(fieldSchema['x-action']);
const [initialSchema, setInitialSchema] = useState<ISchema>(); const [initialSchema, setInitialSchema] = useState<ISchema>();
const actionType = fieldSchema['x-action'] ?? ''; const actionType = fieldSchema['x-action'] ?? '';
const isLinkageAction = linkageAction || isAction; const isLinkageAction = linkageAction || isAction;
const isChildCollectionAction = getChildrenCollections(name).length > 0 && fieldSchema['x-action'] === 'create'; const isChildCollectionAction = getChildrenCollections(name).length > 0 && fieldSchema['x-action'] === 'create';
const isLink = fieldSchema['x-component'] === 'Action.Link'; const isLink = fieldSchema['x-component'] === 'Action.Link';
const isDelete = fieldSchema?.parent['x-component'] === 'CollectionField'; const isDelete = fieldSchema?.parent?.['x-component'] === 'CollectionField';
const isDraggable=fieldSchema?.parent['x-component'] !== 'CollectionField'; const isDraggable = fieldSchema?.parent?.['x-component'] !== 'CollectionField';
const isDuplicateAction = fieldSchema['x-action'] === 'duplicate';
const { collectionList, getEnableFieldTree, onLoadData, onCheck } = useCollectionState(name);
const duplicateValues = cloneDeep(fieldSchema['x-component-props'].duplicateFields || []);
useEffect(() => { useEffect(() => {
const schemaUid = uid(); const schemaUid = uid();
const schema: ISchema = { const schema: ISchema = {
@ -73,6 +88,7 @@ export const ActionDesigner = (props) => {
'After clicking the custom button, the following fields of the current record will be saved according to the following form.', 'After clicking the custom button, the following fields of the current record will be saved according to the following form.',
), ),
}; };
return ( return (
<GeneralSchemaDesigner {...restProps} disableInitializer draggable={isDraggable}> <GeneralSchemaDesigner {...restProps} disableInitializer draggable={isDraggable}>
<MenuGroup> <MenuGroup>
@ -142,6 +158,100 @@ export const ActionDesigner = (props) => {
}} }}
/> />
{isLinkageAction && <SchemaSettings.LinkageRules collectionName={name} />} {isLinkageAction && <SchemaSettings.LinkageRules collectionName={name} />}
{isDuplicateAction && [
<SchemaSettings.ModalItem
title={t('Duplicate mode')}
components={{ Tree }}
scope={{ getEnableFieldTree, collectionName: name }}
schema={
{
type: 'object',
title: t('Duplicate mode'),
properties: {
duplicateMode: {
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
title: t('Duplicate mode'),
default: fieldSchema['x-component-props']?.duplicateMode || 'quickDulicate',
enum: [
{ value: 'quickDulicate', label: '{{t("Quick duplicate")}}' },
{ value: 'continueduplicate', label: '{{t("Duplicate and continue")}}' },
],
},
collection: {
type: 'string',
title: '{{ t("Collection") }}',
required: true,
description: t('If collection inherits, choose inherited collections as templates'),
default: '{{ collectionName }}',
'x-display': collectionList.length > 1 ? 'visible' : 'hidden',
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
options: collectionList,
},
},
duplicateFields: {
type: 'array',
title: '{{ t("Data fields") }}',
required: true,
default: duplicateValues,
description: t('Only the selected fields will be used as the initialization data for the form'),
'x-decorator': 'FormItem',
'x-component': Tree,
'x-component-props': {
defaultCheckedKeys: duplicateValues,
treeData: [],
checkable: true,
checkStrictly: true,
selectable: false,
loadData: onLoadData,
onCheck,
rootStyle: {
padding: '8px 0',
border: '1px solid #d9d9d9',
borderRadius: '2px',
maxHeight: '30vh',
overflow: 'auto',
margin: '2px 0',
},
},
'x-reactions': [
{
dependencies: ['.collection'],
fulfill: {
state: {
disabled: '{{ !$deps[0] }}',
componentProps: {
treeData: '{{ getEnableFieldTree($deps[0], $self) }}',
},
},
},
},
],
},
},
} as ISchema
}
onSubmit={({ duplicateMode, duplicateFields }) => {
const fields = Array.isArray(duplicateFields) ? duplicateFields : duplicateFields.checked || [];
field.componentProps.duplicateMode = duplicateMode;
field.componentProps.duplicateFields = fields;
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
fieldSchema['x-component-props'].duplicateMode = duplicateMode;
fieldSchema['x-component-props'].duplicateFields = fields;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-component-props': {
...fieldSchema['x-component-props'],
},
},
});
dn.refresh();
}}
/>,
]}
<OpenModeSchemaItems openMode={isPopupAction} openSize={isPopupAction}></OpenModeSchemaItems> <OpenModeSchemaItems openMode={isPopupAction} openSize={isPopupAction}></OpenModeSchemaItems>
{isUpdateModePopupAction && ( {isUpdateModePopupAction && (
<SchemaSettings.SelectItem <SchemaSettings.SelectItem
@ -217,39 +327,6 @@ export const ActionDesigner = (props) => {
}} }}
/> />
)} )}
{/* {isValid(fieldSchema?.['x-action-settings']?.overwriteValues) && (
<SchemaSettings.ModalItem
title={t('Form values')}
schema={
{
type: 'object',
properties: {
overwriteValues: {
title: t('When submitting the following fields, the saved values are'),
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
default: JSON.stringify(fieldSchema?.['x-action-settings']?.overwriteValues),
},
},
} as ISchema
}
onSubmit={({ overwriteValues }) => {
try {
const values = JSON.parse(overwriteValues);
fieldSchema['x-action-settings'].overwriteValues = values;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-action-settings': {
...fieldSchema['x-action-settings'],
},
},
});
dn.refresh();
} catch (e) {}
}}
/>
)} */}
{isValid(fieldSchema?.['x-action-settings']?.['onSuccess']) && ( {isValid(fieldSchema?.['x-action-settings']?.['onSuccess']) && (
<SchemaSettings.ModalItem <SchemaSettings.ModalItem
title={ title={

View File

@ -5,7 +5,7 @@ import { ComposedAction } from './types';
export const ActionLink: ComposedAction = observer( export const ActionLink: ComposedAction = observer(
(props: any) => { (props: any) => {
return <Action {...props} component={'a'} className={'nb-action-link'} />; return <Action {...props} component={props.component || 'a'} className={'nb-action-link'} />;
}, },
{ displayName: 'ActionLink' }, { displayName: 'ActionLink' },
); );

View File

@ -7,6 +7,7 @@ import { useTranslation } from 'react-i18next';
import { useAPIClient } from '../../../api-client'; import { useAPIClient } from '../../../api-client';
import { findFormBlock } from '../../../block-provider'; import { findFormBlock } from '../../../block-provider';
import { useCollectionManager } from '../../../collection-manager'; import { useCollectionManager } from '../../../collection-manager';
import { useDuplicatefieldsContext } from '../../../schema-initializer/components';
export interface ITemplate { export interface ITemplate {
config?: { config?: {
@ -32,9 +33,12 @@ export interface ITemplate {
const useDataTemplates = () => { const useDataTemplates = () => {
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const { t } = useTranslation(); const { t } = useTranslation();
const { items = [], display = true } = findDataTemplates(fieldSchema); const data = useDuplicatefieldsContext();
const { getCollectionJoinField } = useCollectionManager(); const { getCollectionJoinField } = useCollectionManager();
if (data) {
return data;
}
const { items = [], display = true } = findDataTemplates(fieldSchema);
// 过滤掉已经被删除的字段 // 过滤掉已经被删除的字段
items.forEach((item) => { items.forEach((item) => {
try { try {
@ -147,7 +151,7 @@ function findDataTemplates(fieldSchema): ITemplate {
return {} as ITemplate; return {} as ITemplate;
} }
async function fetchTemplateData(api, template: { collection: string; dataId: number; fields: string[] }, t) { export async function fetchTemplateData(api, template: { collection: string; dataId: number; fields: string[] }, t) {
if (template.fields.length === 0) { if (template.fields.length === 0) {
return; return;
} }

View File

@ -31,6 +31,19 @@ export const DetailsActionInitializers = {
'x-decorator': 'ACLActionProvider', 'x-decorator': 'ACLActionProvider',
}, },
}, },
{
type: 'item',
title: '{{t("Duplicate")}}',
component: 'DuplicateActionInitializer',
schema: {
'x-component': 'Action',
'x-action': 'duplicate',
'x-decorator': 'ACLActionProvider',
'x-component-props': {
type: 'primary',
},
},
},
], ],
}, },
], ],

View File

@ -1,5 +1,9 @@
import { useCollection } from '../..'; import { useCollection } from '../..';
const useVisibleCollection = () => {
const collection = useCollection();
return collection.template !== 'view';
};
// 表单的操作配置 // 表单的操作配置
export const ReadPrettyFormActionInitializers = { export const ReadPrettyFormActionInitializers = {
title: '{{t("Configure actions")}}', title: '{{t("Configure actions")}}',
@ -23,10 +27,7 @@ export const ReadPrettyFormActionInitializers = {
type: 'primary', type: 'primary',
}, },
}, },
visible: () => { visible: useVisibleCollection,
const collection = useCollection();
return (collection as any).template !== 'view';
},
}, },
{ {
type: 'item', type: 'item',
@ -36,10 +37,21 @@ export const ReadPrettyFormActionInitializers = {
'x-component': 'Action', 'x-component': 'Action',
'x-decorator': 'ACLActionProvider', 'x-decorator': 'ACLActionProvider',
}, },
visible: () => { visible: useVisibleCollection,
const collection = useCollection(); },
return (collection as any).template !== 'view'; {
type: 'item',
title: '{{t("Duplicate")}}',
component: 'DuplicateActionInitializer',
schema: {
'x-component': 'Action',
'x-action': 'duplicate',
'x-decorator': 'ACLActionProvider',
'x-component-props': {
type: 'primary',
},
}, },
visible: useVisibleCollection,
}, },
{ {
type: 'item', type: 'item',
@ -132,10 +144,7 @@ export const ReadPrettyFormActionInitializers = {
useProps: '{{ useCustomizeUpdateActionProps }}', useProps: '{{ useCustomizeUpdateActionProps }}',
}, },
}, },
visible: () => { visible: useVisibleCollection,
const collection = useCollection();
return (collection as any).template !== 'view';
},
}, },
{ {
type: 'item', type: 'item',
@ -159,10 +168,7 @@ export const ReadPrettyFormActionInitializers = {
useProps: '{{ useCustomizeRequestActionProps }}', useProps: '{{ useCustomizeRequestActionProps }}',
}, },
}, },
visible: () => { visible: useVisibleCollection,
const collection = useCollection();
return (collection as any).template !== 'view';
},
}, },
], ],
}, },

View File

@ -102,10 +102,10 @@ export const TableActionColumnInitializers = (props: any) => {
'x-decorator': 'ACLActionProvider', 'x-decorator': 'ACLActionProvider',
}, },
visible: () => { visible: () => {
const collection = useCollection();
return (collection as any).template !== 'view'; return (collection as any).template !== 'view';
}, },
}, },
modifyFlag && { modifyFlag && {
type: 'item', type: 'item',
title: t('Delete'), title: t('Delete'),
@ -127,6 +127,19 @@ export const TableActionColumnInitializers = (props: any) => {
'x-decorator': 'ACLActionProvider', 'x-decorator': 'ACLActionProvider',
}, },
}, },
{
type: 'item',
title: t('Duplicate'),
component: 'DuplicateActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'duplicate',
'x-decorator': 'ACLActionProvider',
},
visible: () => {
return (collection as any).template !== 'view';
},
},
], ],
}, },
{ {
@ -210,7 +223,6 @@ export const TableActionColumnInitializers = (props: any) => {
}, },
}, },
visible: () => { visible: () => {
const collection = useCollection();
return (collection as any).template !== 'view'; return (collection as any).template !== 'view';
}, },
}, },
@ -236,7 +248,6 @@ export const TableActionColumnInitializers = (props: any) => {
}, },
}, },
visible: () => { visible: () => {
const collection = useCollection();
return (collection as any).template !== 'view'; return (collection as any).template !== 'view';
}, },
}, },

View File

@ -0,0 +1,121 @@
import React, { createContext, useContext, useState } from 'react';
import { observer, RecursionField, useField, useFieldSchema } from '@formily/react';
import { RecordProvider, ActionContext, useActionContext, useRecord, useCollection } from '../../';
import { useTranslation } from 'react-i18next';
import { css, cx } from '@emotion/css';
import { useAPIClient, useBlockRequestContext, useDesignable } from '../../';
import { actionDesignerCss } from './CreateRecordAction';
import { fetchTemplateData } from '../../schema-component/antd/form-v2/Templates';
import { Button, message } from 'antd';
const DuplicatefieldsContext = createContext(null);
export const useDuplicatefieldsContext = () => {
return useContext(DuplicatefieldsContext);
};
export const DuplicateAction = observer((props: any) => {
const { children } = props;
const field = useField();
const fieldSchema = useFieldSchema();
const api = useAPIClient();
const disabled: boolean = field.disabled || props.disabled;
const { designable } = useDesignable();
const [visible, setVisible] = useState(false);
const [loading, setLoading] = useState(false);
const { resource, service, __parent, block } = useBlockRequestContext();
const { duplicateFields, duplicateMode = 'quickDulicate' } = fieldSchema['x-component-props'];
const { id } = useRecord();
const ctx = useActionContext();
const { name } = useCollection();
const { t } = useTranslation();
const template = { key: 'duplicate', dataId: id, default: true, fields: duplicateFields || [], collection: name };
const isLinkBtn = fieldSchema['x-component'] === 'Action.Link';
const handelQuickDuplicate = async () => {
setLoading(true);
try {
const data = await fetchTemplateData(api, template, t);
await resource.create({
values: {
...data,
},
});
message.success(t('Saved successfully'));
if (block === 'form') {
__parent?.service?.refresh?.();
} else {
await service?.refresh?.();
}
setLoading(false);
} catch (error) {
setLoading(false);
console.error(error); // Handle or log the error appropriately
}
};
const handelDuplicate = () => {
if (!disabled && !loading) {
if (duplicateFields?.length > 0) {
if (duplicateMode === 'quickDulicate') {
handelQuickDuplicate();
} else {
setVisible(true);
}
} else {
message.error(t('Please configure the duplicate fields'));
}
}
};
return (
<div
className={cx(actionDesignerCss, {
[css`
.general-schema-designer {
top: -10px;
bottom: -10px;
left: -10px;
right: -10px;
}
`]: isLinkBtn,
})}
>
<DuplicatefieldsContext.Provider
value={{
display: false,
enabled: true,
defaultTemplate: template,
}}
>
<div>
{isLinkBtn ? (
<a
//@ts-ignore
disabled={disabled}
style={{
opacity: designable && field?.data?.hidden && 0.1,
cursor: loading ? 'not-allowed' : 'pointer',
}}
onClick={handelDuplicate}
>
{loading ? t('Duplicating') : children || t('Duplicate')}
</a>
) : (
<Button
disabled={disabled}
style={{
opacity: designable && field?.data?.hidden && 0.1,
}}
{...props}
onClick={handelDuplicate}
>
{loading ? t('Duplicating') : children || t('Duplicate')}
</Button>
)}
<ActionContext.Provider value={{ ...ctx, visible, setVisible }}>
<RecursionField schema={fieldSchema} basePath={field.address} onlyRenderProperties />
</ActionContext.Provider>
</div>
</DuplicatefieldsContext.Provider>
</div>
);
});

View File

@ -1,3 +1,4 @@
export * from './assigned-field'; export * from './assigned-field';
export * from './BulkEditField'; export * from './BulkEditField';
export * from './CreateRecordAction'; export * from './CreateRecordAction';
export * from './DuplicateAction'

View File

@ -0,0 +1,54 @@
import React from 'react';
import { ActionInitializer } from './ActionInitializer';
export const DuplicateActionInitializer = (props) => {
const schema = {
type: 'void',
'x-action': 'duplicate',
'x-acl-action':'create',
title: '{{ t("Duplicate") }}',
'x-designer': 'Action.Designer',
'x-component': 'Action.Link',
'x-decorator': 'ACLActionProvider',
'x-component-props': {
openMode: 'drawer',
component: 'DuplicateAction',
},
properties: {
drawer: {
type: 'void',
title: '{{ t("Duplicate") }}',
'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("Duplicate")}}',
'x-component': 'Tabs.TabPane',
'x-designer': 'Tabs.Designer',
'x-component-props': {},
properties: {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'CreateFormBlockInitializers',
properties: {},
},
},
},
},
},
},
},
},
};
return <ActionInitializer {...props} schema={schema} />;
};

View File

@ -51,4 +51,5 @@ export * from './TableCollectionFieldInitializer';
export * from './TableSelectorInitializer'; export * from './TableSelectorInitializer';
export * from './UpdateActionInitializer'; export * from './UpdateActionInitializer';
export * from './UpdateSubmitActionInitializer'; export * from './UpdateSubmitActionInitializer';
export * from './DuplicateActionInitializer';
export * from './ViewActionInitializer'; export * from './ViewActionInitializer';

View File

@ -29,15 +29,16 @@ export const OpenModeSchemaItems: React.FC<Options> = (options) => {
value={openModeValue} value={openModeValue}
onChange={(value) => { onChange={(value) => {
field.componentProps.openMode = value; field.componentProps.openMode = value;
fieldSchema['x-component-props'] = field.componentProps; const schema = {
'x-uid': fieldSchema['x-uid'],
};
schema['x-component-props'] = fieldSchema['x-component-props'] || {};
schema['x-component-props'].openMode = value;
fieldSchema['x-component-props'].openMode = value;
// when openMode change, set openSize value to default // when openMode change, set openSize value to default
Reflect.deleteProperty(fieldSchema['x-component-props'], 'openSize'); Reflect.deleteProperty(fieldSchema['x-component-props'], 'openSize');
dn.emit('patch', { dn.emit('patch', {
schema: { schema: schema,
'x-uid': fieldSchema['x-uid'],
'x-component-props': fieldSchema['x-component-props'],
},
}); });
dn.refresh(); dn.refresh();
}} }}
@ -60,12 +61,14 @@ export const OpenModeSchemaItems: React.FC<Options> = (options) => {
} }
onChange={(value) => { onChange={(value) => {
field.componentProps.openSize = value; field.componentProps.openSize = value;
fieldSchema['x-component-props'] = field.componentProps; const schema = {
'x-uid': fieldSchema['x-uid'],
};
schema['x-component-props'] = fieldSchema['x-component-props'] || {};
schema['x-component-props'].openSize = value;
fieldSchema['x-component-props'].openSize = value;
dn.emit('patch', { dn.emit('patch', {
schema: { schema: schema,
'x-uid': fieldSchema['x-uid'],
'x-component-props': fieldSchema['x-component-props'],
},
}); });
dn.refresh(); dn.refresh();
}} }}