refactor(add-new):association field add new support button edit (#1854)
* feat: assoociation add new supoort button edit * feat: assoociation add new supoort button edit * fix: add new button type * refactor: add new support button edit
This commit is contained in:
parent
3a77e4376a
commit
d58174011c
@ -44,7 +44,7 @@ export const ActionDesigner = (props) => {
|
||||
const { getChildrenCollections } = useCollectionManager();
|
||||
const { dn } = useDesignable();
|
||||
const { t } = useTranslation();
|
||||
const isAction = useLinkageAction()
|
||||
const isAction = useLinkageAction();
|
||||
const isPopupAction = ['create', 'update', 'view', 'customize:popup'].includes(fieldSchema['x-action'] || '');
|
||||
const isUpdateModePopupAction = ['customize:bulkUpdate', 'customize:bulkEdit'].includes(fieldSchema['x-action']);
|
||||
const [initialSchema, setInitialSchema] = useState<ISchema>();
|
||||
@ -52,6 +52,7 @@ export const ActionDesigner = (props) => {
|
||||
const isLinkageAction = linkageAction || isAction;
|
||||
const isChildCollectionAction = getChildrenCollections(name).length > 0 && fieldSchema['x-action'] === 'create';
|
||||
const isLink = fieldSchema['x-component'] === 'Action.Link';
|
||||
const isDelete = fieldSchema?.parent['x-component'] === 'CollectionField';
|
||||
useEffect(() => {
|
||||
const schemaUid = uid();
|
||||
const schema: ISchema = {
|
||||
@ -329,16 +330,19 @@ export const ActionDesigner = (props) => {
|
||||
)}
|
||||
|
||||
{isChildCollectionAction && <SchemaSettings.EnableChildCollections collectionName={name} />}
|
||||
<SchemaSettings.Divider />
|
||||
<SchemaSettings.Remove
|
||||
removeParentsIfNoChildren
|
||||
breakRemoveOn={(s) => {
|
||||
return s['x-component'] === 'Space' || s['x-component'].endsWith('ActionBar');
|
||||
}}
|
||||
confirm={{
|
||||
title: t('Delete action'),
|
||||
}}
|
||||
/>
|
||||
|
||||
{!isDelete && [
|
||||
<SchemaSettings.Divider />,
|
||||
<SchemaSettings.Remove
|
||||
removeParentsIfNoChildren
|
||||
breakRemoveOn={(s) => {
|
||||
return s['x-component'] === 'Space' || s['x-component'].endsWith('ActionBar');
|
||||
}}
|
||||
confirm={{
|
||||
title: t('Delete action'),
|
||||
}}
|
||||
/>,
|
||||
]}
|
||||
</MenuGroup>
|
||||
</GeneralSchemaDesigner>
|
||||
);
|
||||
|
@ -1,15 +1,10 @@
|
||||
import { LoadingOutlined } from '@ant-design/icons';
|
||||
import { RecursionField, connect, mapProps, observer, useField, useFieldSchema } from '@formily/react';
|
||||
import { Button, Input } from 'antd';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { CollectionProvider } from '../../../collection-manager';
|
||||
import { Input } from 'antd';
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useFieldTitle } from '../../hooks';
|
||||
import { ActionContext } from '../action';
|
||||
import { useAssociationFieldContext } from './hooks';
|
||||
import { RemoteSelect, RemoteSelectProps } from '../remote-select';
|
||||
import useServiceOptions, { useInsertSchema } from './hooks';
|
||||
import schema from './schema';
|
||||
import useServiceOptions from './hooks';
|
||||
|
||||
export type AssociationSelectProps<P = any> = RemoteSelectProps<P> & {
|
||||
action?: string;
|
||||
@ -20,13 +15,8 @@ const InternalAssociationSelect = observer((props: AssociationSelectProps) => {
|
||||
const { fieldNames, objectValue = true } = props;
|
||||
const field: any = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const [visibleAddNewer, setVisibleAddNewer] = useState(false);
|
||||
const service = useServiceOptions(props);
|
||||
const { options: collectionField } = useAssociationFieldContext();
|
||||
const isFilterForm = fieldSchema['x-designer'] === 'FormItem.FilterFormDesigner';
|
||||
const isAllowAddNew = fieldSchema['x-add-new'];
|
||||
const insertAddNewer = useInsertSchema('AddNewer');
|
||||
const { t } = useTranslation();
|
||||
const normalizeValues = useCallback(
|
||||
(obj) => {
|
||||
if (!objectValue && typeof obj === 'object') {
|
||||
@ -36,7 +26,6 @@ const InternalAssociationSelect = observer((props: AssociationSelectProps) => {
|
||||
},
|
||||
[objectValue, fieldNames?.value],
|
||||
);
|
||||
|
||||
const value = useMemo(() => {
|
||||
if (props.value === undefined || props.value === null || !Object.keys(props.value).length) {
|
||||
return;
|
||||
@ -60,31 +49,18 @@ const InternalAssociationSelect = observer((props: AssociationSelectProps) => {
|
||||
value={value}
|
||||
service={service}
|
||||
></RemoteSelect>
|
||||
{isAllowAddNew && !field.readPretty && !isFilterForm && (
|
||||
<Button
|
||||
type={'default'}
|
||||
onClick={() => {
|
||||
insertAddNewer(schema.AddNewer);
|
||||
setVisibleAddNewer(true);
|
||||
}}
|
||||
>
|
||||
{t('Add new')}
|
||||
</Button>
|
||||
)}
|
||||
</Input.Group>
|
||||
|
||||
<ActionContext.Provider value={{ openMode: 'drawer', visible: visibleAddNewer, setVisible: setVisibleAddNewer }}>
|
||||
<CollectionProvider name={collectionField.target}>
|
||||
{isAllowAddNew && (
|
||||
<RecursionField
|
||||
onlyRenderProperties
|
||||
basePath={field.address}
|
||||
schema={fieldSchema}
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] === 'AssociationField.AddNewer';
|
||||
return s['x-component'] === 'Action';
|
||||
}}
|
||||
/>
|
||||
</CollectionProvider>
|
||||
</ActionContext.Provider>
|
||||
)}
|
||||
</Input.Group>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
@ -9,6 +9,7 @@ import { SchemaComponentOptions } from '../../';
|
||||
import { InternalSubTable } from './InternalSubTable';
|
||||
import { InternalFileManager } from './FileManager';
|
||||
import { useAssociationFieldContext } from './hooks';
|
||||
import {CreateRecordAction} from './components/CreateRecordAction'
|
||||
|
||||
const EditableAssociationField = observer((props: any) => {
|
||||
const { multiple } = props;
|
||||
@ -44,7 +45,7 @@ const EditableAssociationField = observer((props: any) => {
|
||||
};
|
||||
};
|
||||
return (
|
||||
<SchemaComponentOptions scope={{ useCreateActionProps }}>
|
||||
<SchemaComponentOptions scope={{ useCreateActionProps }} components={{CreateRecordAction}}>
|
||||
{currentMode === 'Picker' && <InternalPicker {...props} />}
|
||||
{currentMode === 'Nester' && <InternalNester {...props} />}
|
||||
{currentMode === 'Select' && <AssociationSelect {...props} />}
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
TableSelectorParamsProvider,
|
||||
useTableSelectorProps as useTsp,
|
||||
} from '../../../block-provider/TableSelectorProvider';
|
||||
import { CollectionProvider, useCollection, useCollectionManager } from '../../../collection-manager';
|
||||
import { CollectionProvider } from '../../../collection-manager';
|
||||
import { useCompile } from '../../hooks';
|
||||
import { ActionContext } from '../action';
|
||||
import { useFieldNames, useInsertSchema } from './hooks';
|
||||
@ -65,17 +65,10 @@ export const InternalPicker = observer((props: any) => {
|
||||
const { value, multiple, onChange, quickUpload, selectFile, ...others } = props;
|
||||
const field: any = useField();
|
||||
const fieldNames = useFieldNames(props);
|
||||
const [visibleAddNewer, setVisibleAddNewer] = useState(false);
|
||||
const [visibleSelector, setVisibleSelector] = useState(false);
|
||||
const fieldSchema = useFieldSchema();
|
||||
const insertAddNewer = useInsertSchema('AddNewer');
|
||||
const insertSelector = useInsertSchema('Selector');
|
||||
const { t } = useTranslation();
|
||||
const { options: collectionField } = useAssociationFieldContext();
|
||||
const addbuttonClick = () => {
|
||||
insertAddNewer(schema.AddNewer);
|
||||
setVisibleAddNewer(true);
|
||||
};
|
||||
const compile = useCompile();
|
||||
const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
|
||||
const isAllowAddNew = fieldSchema['x-add-new'];
|
||||
@ -168,29 +161,16 @@ export const InternalPicker = observer((props: any) => {
|
||||
/>
|
||||
</div>
|
||||
{isAllowAddNew && (
|
||||
<Button
|
||||
style={{ width: 'auto' }}
|
||||
type={'default'}
|
||||
onClick={() => {
|
||||
addbuttonClick();
|
||||
}}
|
||||
>
|
||||
{t('Add new')}
|
||||
</Button>
|
||||
)}
|
||||
</Input.Group>
|
||||
<ActionContext.Provider value={{ openMode: 'drawer', visible: visibleAddNewer, setVisible: setVisibleAddNewer }}>
|
||||
<CollectionProvider name={collectionField.target}>
|
||||
<RecursionField
|
||||
onlyRenderProperties
|
||||
basePath={field.address}
|
||||
schema={fieldSchema}
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] === 'AssociationField.AddNewer';
|
||||
return s['x-component'] === 'Action';
|
||||
}}
|
||||
/>
|
||||
</CollectionProvider>
|
||||
</ActionContext.Provider>
|
||||
)}
|
||||
</Input.Group>
|
||||
<ActionContext.Provider value={{ openMode: 'drawer', visible: visibleSelector, setVisible: setVisibleSelector }}>
|
||||
<RecordPickerProvider {...pickerProps}>
|
||||
<CollectionProvider name={collectionField.target}>
|
||||
|
@ -0,0 +1,40 @@
|
||||
import { RecursionField, observer, useField, useFieldSchema } from '@formily/react';
|
||||
import React, { useState } from 'react';
|
||||
import { CollectionProvider } from '../../../../collection-manager';
|
||||
import { ActionContext, useActionContext } from '../../action';
|
||||
import { useAssociationFieldContext } from '../hooks';
|
||||
import { useInsertSchema } from '../hooks';
|
||||
import { CreateAction } from '../../../../schema-initializer/components';
|
||||
import schema from '../schema';
|
||||
|
||||
export const CreateRecordAction = observer((props) => {
|
||||
const field: any = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const ctx = useActionContext();
|
||||
const insertAddNewer = useInsertSchema('AddNewer');
|
||||
const { options: collectionField } = useAssociationFieldContext();
|
||||
const [visibleAddNewer, setVisibleAddNewer] = useState(false);
|
||||
const [currentCollection, setCurrentCollection] = useState(collectionField.target);
|
||||
const addbuttonClick = (name) => {
|
||||
insertAddNewer(schema.AddNewer);
|
||||
setVisibleAddNewer(true);
|
||||
setCurrentCollection(name);
|
||||
};
|
||||
return (
|
||||
<CollectionProvider name={collectionField.target}>
|
||||
<CreateAction {...props} onClick={(arg) => addbuttonClick(arg)} />
|
||||
<ActionContext.Provider value={{ ...ctx, visible: visibleAddNewer, setVisible: setVisibleAddNewer }}>
|
||||
<CollectionProvider name={currentCollection}>
|
||||
<RecursionField
|
||||
onlyRenderProperties
|
||||
basePath={field.address}
|
||||
schema={fieldSchema}
|
||||
filterProperties={(s) => {
|
||||
return s['x-component'] === 'AssociationField.AddNewer';
|
||||
}}
|
||||
/>
|
||||
</CollectionProvider>
|
||||
</ActionContext.Provider>
|
||||
</CollectionProvider>
|
||||
);
|
||||
});
|
@ -146,6 +146,7 @@ FormItem.Designer = function Designer() {
|
||||
value: field?.name,
|
||||
label: compile(field?.uiSchema?.title) || field?.name,
|
||||
}));
|
||||
|
||||
let readOnlyMode = 'editable';
|
||||
if (fieldSchema['x-disabled'] === true) {
|
||||
readOnlyMode = 'readonly';
|
||||
@ -588,6 +589,28 @@ FormItem.Designer = function Designer() {
|
||||
title={t('Allow add new data')}
|
||||
checked={fieldSchema['x-add-new'] as boolean}
|
||||
onChange={(allowAddNew) => {
|
||||
const hasAddNew = fieldSchema.reduceProperties((buf, schema) => {
|
||||
if (schema['x-component'] === 'Action') {
|
||||
return schema;
|
||||
}
|
||||
return buf;
|
||||
}, null);
|
||||
|
||||
if (!hasAddNew) {
|
||||
const addNewActionschema = {
|
||||
'x-action': 'create',
|
||||
title: "{{t('Add new')}}",
|
||||
'x-designer': 'Action.Designer',
|
||||
'x-component': 'Action',
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
'x-component-props': {
|
||||
openMode: 'drawer',
|
||||
type: 'default',
|
||||
component: 'CreateRecordAction',
|
||||
},
|
||||
};
|
||||
insertAdjacent('afterBegin', addNewActionschema);
|
||||
}
|
||||
const schema = {
|
||||
['x-uid']: fieldSchema['x-uid'],
|
||||
};
|
||||
|
@ -3,7 +3,6 @@ import { css } from '@emotion/css';
|
||||
import { RecursionField, observer, useField, useFieldSchema } from '@formily/react';
|
||||
import { Button, Dropdown, Menu } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDesignable } from '../../';
|
||||
import { useACLRolesCheck, useRecordPkValue } from '../../acl/ACLProvider';
|
||||
import { CollectionProvider, useCollection, useCollectionManager } from '../../collection-manager';
|
||||
@ -85,11 +84,48 @@ export const CreateRecordAction = observer((props: any) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const collection = useCollection();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const field: any = useField();
|
||||
const [currentCollection, setCurrentCollection] = useState(collection.name);
|
||||
const linkageRules = fieldSchema?.['x-linkage-rules'] || [];
|
||||
const values = useRecord();
|
||||
const ctx = useActionContext();
|
||||
useEffect(() => {
|
||||
field.linkageProperty = {};
|
||||
linkageRules
|
||||
.filter((k) => !k.disabled)
|
||||
.map((v) => {
|
||||
return v.actions?.map((h) => {
|
||||
linkageAction(h.operator, field, v.condition, values);
|
||||
});
|
||||
});
|
||||
}, [linkageRules, values]);
|
||||
return (
|
||||
<div className={actionDesignerCss}>
|
||||
<ActionContext.Provider value={{ ...ctx, visible, setVisible }}>
|
||||
<CreateAction
|
||||
{...props}
|
||||
onClick={(name) => {
|
||||
setVisible(true);
|
||||
setCurrentCollection(name);
|
||||
}}
|
||||
/>
|
||||
<CollectionProvider name={currentCollection}>
|
||||
<RecursionField schema={fieldSchema} basePath={field.address} onlyRenderProperties />
|
||||
</CollectionProvider>
|
||||
</ActionContext.Provider>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export const CreateAction = observer((props: any) => {
|
||||
const { onClick } = props;
|
||||
const collection = useCollection();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const enableChildren = fieldSchema['x-enable-children'] || [];
|
||||
const allowAddToCurrent = fieldSchema?.['x-allow-add-to-current'];
|
||||
const field: any = useField();
|
||||
const { t } = useTranslation();
|
||||
const componentType = field.componentProps.type || 'primary';
|
||||
console.log(componentType)
|
||||
const { getChildrenCollections } = useCollectionManager();
|
||||
const totalChildCollections = getChildrenCollections(collection.name);
|
||||
const inheritsCollections = enableChildren
|
||||
@ -109,10 +145,8 @@ export const CreateRecordAction = observer((props: any) => {
|
||||
.filter((v) => {
|
||||
return v && actionAclCheck(`${v.name}:create`);
|
||||
});
|
||||
const [currentCollection, setCurrentCollection] = useState(collection.name);
|
||||
const linkageRules = fieldSchema?.['x-linkage-rules'] || [];
|
||||
const values = useRecord();
|
||||
const ctx = useActionContext();
|
||||
const compile = useCompile();
|
||||
const { designable } = useDesignable();
|
||||
const icon = props.icon || <PlusOutlined />;
|
||||
@ -123,8 +157,7 @@ export const CreateRecordAction = observer((props: any) => {
|
||||
<Menu.Item
|
||||
key={option.name}
|
||||
onClick={(info) => {
|
||||
setVisible(true);
|
||||
setCurrentCollection(option.name);
|
||||
onClick?.(option.name);
|
||||
}}
|
||||
>
|
||||
{compile(option.title)}
|
||||
@ -145,56 +178,49 @@ export const CreateRecordAction = observer((props: any) => {
|
||||
}, [linkageRules, values]);
|
||||
return (
|
||||
<div className={actionDesignerCss}>
|
||||
<ActionContext.Provider value={{ ...ctx, visible, setVisible }}>
|
||||
{inheritsCollections?.length > 0 ? (
|
||||
allowAddToCurrent === undefined || allowAddToCurrent ? (
|
||||
<Dropdown.Button
|
||||
type={componentType}
|
||||
icon={<DownOutlined />}
|
||||
buttonsRender={([leftButton, rightButton]) => [
|
||||
leftButton,
|
||||
React.cloneElement(rightButton as React.ReactElement<any, string>, { loading: false }),
|
||||
]}
|
||||
overlay={menu}
|
||||
onClick={(info) => {
|
||||
setVisible(true);
|
||||
setCurrentCollection(collection.name);
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
{props.children}
|
||||
</Dropdown.Button>
|
||||
) : (
|
||||
<Dropdown overlay={menu}>
|
||||
{
|
||||
<Button icon={icon} type={'primary'}>
|
||||
{props.children} <DownOutlined />
|
||||
</Button>
|
||||
}
|
||||
</Dropdown>
|
||||
)
|
||||
) : (
|
||||
<Button
|
||||
{inheritsCollections?.length > 0 ? (
|
||||
allowAddToCurrent === undefined || allowAddToCurrent ? (
|
||||
<Dropdown.Button
|
||||
type={componentType}
|
||||
disabled={field.disabled}
|
||||
danger={componentType === 'danger'}
|
||||
icon={icon}
|
||||
icon={<DownOutlined />}
|
||||
buttonsRender={([leftButton, rightButton]) => [
|
||||
leftButton,
|
||||
React.cloneElement(rightButton as React.ReactElement<any, string>, { loading: false }),
|
||||
]}
|
||||
overlay={menu}
|
||||
onClick={(info) => {
|
||||
setVisible(true);
|
||||
setCurrentCollection(collection.name);
|
||||
}}
|
||||
style={{
|
||||
display: !designable && field?.data?.hidden && 'none',
|
||||
opacity: designable && field?.data?.hidden && 0.1,
|
||||
onClick?.(collection.name);
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
{props.children}
|
||||
</Button>
|
||||
)}
|
||||
<CollectionProvider name={currentCollection}>
|
||||
<RecursionField schema={fieldSchema} basePath={field.address} onlyRenderProperties />
|
||||
</CollectionProvider>
|
||||
</ActionContext.Provider>
|
||||
</Dropdown.Button>
|
||||
) : (
|
||||
<Dropdown overlay={menu}>
|
||||
{
|
||||
<Button icon={icon} type={componentType}>
|
||||
{props.children} <DownOutlined />
|
||||
</Button>
|
||||
}
|
||||
</Dropdown>
|
||||
)
|
||||
) : (
|
||||
<Button
|
||||
type={componentType}
|
||||
disabled={field.disabled}
|
||||
danger={componentType === 'danger'}
|
||||
icon={icon}
|
||||
onClick={(info) => {
|
||||
onClick?.(collection.name);
|
||||
}}
|
||||
style={{
|
||||
display: !designable && field?.data?.hidden && 'none',
|
||||
opacity: designable && field?.data?.hidden && 0.1,
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
@ -1111,13 +1111,13 @@ SchemaSettings.EnableChildCollections = function EnableChildCollectionsItem(prop
|
||||
fieldSchema['x-enable-children'] = enableChildren;
|
||||
fieldSchema['x-allow-add-to-current'] = v.allowAddToCurrent;
|
||||
fieldSchema['x-component-props'] = {
|
||||
openMode: 'drawer',
|
||||
...fieldSchema['x-component-props'],
|
||||
component: 'CreateRecordAction',
|
||||
};
|
||||
schema['x-enable-children'] = enableChildren;
|
||||
schema['x-allow-add-to-current'] = v.allowAddToCurrent;
|
||||
schema['x-component-props'] = {
|
||||
openMode: 'drawer',
|
||||
...fieldSchema['x-component-props'],
|
||||
component: 'CreateRecordAction',
|
||||
};
|
||||
dn.emit('patch', {
|
||||
|
Loading…
Reference in New Issue
Block a user