mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 22:49:26 +08:00
Merge branch 'next' into develop
This commit is contained in:
commit
3c7138fff9
@ -2,9 +2,7 @@
|
|||||||
"version": "1.6.0-alpha.2",
|
"version": "1.6.0-alpha.2",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"useWorkspaces": true,
|
"useWorkspaces": true,
|
||||||
"npmClientArgs": [
|
"npmClientArgs": ["--ignore-engines"],
|
||||||
"--ignore-engines"
|
|
||||||
],
|
|
||||||
"command": {
|
"command": {
|
||||||
"version": {
|
"version": {
|
||||||
"forcePublish": true,
|
"forcePublish": true,
|
||||||
|
@ -69,7 +69,6 @@ export function ButtonEditor(props) {
|
|||||||
title: t('Button title'),
|
title: t('Button title'),
|
||||||
default: fieldSchema.title,
|
default: fieldSchema.title,
|
||||||
'x-component-props': {},
|
'x-component-props': {},
|
||||||
// description: `原字段标题:${collectionField?.uiSchema?.title}`,
|
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
@ -78,7 +77,6 @@ export function ButtonEditor(props) {
|
|||||||
default: fieldSchema?.['x-component-props']?.icon,
|
default: fieldSchema?.['x-component-props']?.icon,
|
||||||
'x-component-props': {},
|
'x-component-props': {},
|
||||||
'x-visible': !isLink,
|
'x-visible': !isLink,
|
||||||
// description: `原字段标题:${collectionField?.uiSchema?.title}`,
|
|
||||||
},
|
},
|
||||||
iconColor: {
|
iconColor: {
|
||||||
title: t('Color'),
|
title: t('Color'),
|
||||||
@ -730,7 +728,7 @@ export const actionSettingsItems: SchemaSettingOptions['items'] = [
|
|||||||
'duplicate',
|
'duplicate',
|
||||||
'customize:create',
|
'customize:create',
|
||||||
].includes(fieldSchema['x-action'] || '');
|
].includes(fieldSchema['x-action'] || '');
|
||||||
return !isPopupAction;
|
return !isPopupAction && !fieldSchema?.['x-action-settings'].disableSecondConFirm;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -957,11 +955,12 @@ export const ActionDesigner = (props) => {
|
|||||||
buttonEditorProps,
|
buttonEditorProps,
|
||||||
linkageRulesProps,
|
linkageRulesProps,
|
||||||
schemaSettings = 'ActionSettings',
|
schemaSettings = 'ActionSettings',
|
||||||
|
enableDrag = true,
|
||||||
...restProps
|
...restProps
|
||||||
} = props;
|
} = props;
|
||||||
const app = useApp();
|
const app = useApp();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const isDraggable = fieldSchema?.parent['x-component'] !== 'CollectionField';
|
const isDraggable = fieldSchema?.parent['x-component'] !== 'CollectionField' && enableDrag;
|
||||||
const settingsName = `ActionSettings:${fieldSchema['x-action']}`;
|
const settingsName = `ActionSettings:${fieldSchema['x-action']}`;
|
||||||
const defaultActionSettings = schemaSettings || 'ActionSettings';
|
const defaultActionSettings = schemaSettings || 'ActionSettings';
|
||||||
const hasAction = app.schemaSettingsManager.has(settingsName);
|
const hasAction = app.schemaSettingsManager.has(settingsName);
|
||||||
|
@ -63,5 +63,5 @@ export const useLinkageAction = () => {
|
|||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const isRecordAction = useIsDetailBlock();
|
const isRecordAction = useIsDetailBlock();
|
||||||
const isAction = ['Action.Link', 'Action'].includes(fieldSchema['x-component']);
|
const isAction = ['Action.Link', 'Action'].includes(fieldSchema['x-component']);
|
||||||
return isAction && isRecordAction;
|
return isAction && isRecordAction && fieldSchema['x-action'];
|
||||||
};
|
};
|
||||||
|
@ -25,6 +25,9 @@ export const InternalSubTable = observer(
|
|||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const insert = useInsertSchema('SubTable');
|
const insert = useInsertSchema('SubTable');
|
||||||
const insertSelector = useInsertSchema('Selector');
|
const insertSelector = useInsertSchema('Selector');
|
||||||
|
const insertSelect = useInsertSchema('SubTable.SelectAction');
|
||||||
|
const insertAddNewAction = useInsertSchema('SubTable.AddNewAction');
|
||||||
|
|
||||||
const { options } = useAssociationFieldContext();
|
const { options } = useAssociationFieldContext();
|
||||||
const { actionName } = useACLActionParamsContext();
|
const { actionName } = useACLActionParamsContext();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -34,8 +37,14 @@ export const InternalSubTable = observer(
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (field.componentProps?.allowSelectExistingRecord) {
|
if (field.componentProps?.allowSelectExistingRecord) {
|
||||||
insertSelector(schema.Selector);
|
insertSelector(schema.Selector);
|
||||||
|
insertSelect(schema.SelectAction);
|
||||||
}
|
}
|
||||||
}, [field.componentProps?.allowSelectExistingRecord]);
|
}, [field.componentProps?.allowSelectExistingRecord]);
|
||||||
|
useEffect(() => {
|
||||||
|
if (field.componentProps?.allowAddnew !== false) {
|
||||||
|
insertAddNewAction(schema.AddNewAction);
|
||||||
|
}
|
||||||
|
}, [field.componentProps?.allowAddnew]);
|
||||||
const option = useSchemaOptionsContext();
|
const option = useSchemaOptionsContext();
|
||||||
const components = {
|
const components = {
|
||||||
...option.components,
|
...option.components,
|
||||||
|
@ -13,9 +13,9 @@ import { exchangeArrayState } from '@formily/core/esm/shared/internals';
|
|||||||
import { observer, useFieldSchema } from '@formily/react';
|
import { observer, useFieldSchema } from '@formily/react';
|
||||||
import { action } from '@formily/reactive';
|
import { action } from '@formily/reactive';
|
||||||
import { isArr } from '@formily/shared';
|
import { isArr } from '@formily/shared';
|
||||||
import { Button } from 'antd';
|
|
||||||
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Space } from 'antd';
|
||||||
import {
|
import {
|
||||||
FormProvider,
|
FormProvider,
|
||||||
RecordPickerContext,
|
RecordPickerContext,
|
||||||
@ -32,12 +32,13 @@ import { markRecordAsNew } from '../../../data-source/collection-record/isNewRec
|
|||||||
import { FlagProvider } from '../../../flag-provider';
|
import { FlagProvider } from '../../../flag-provider';
|
||||||
import { NocoBaseRecursionField } from '../../../formily/NocoBaseRecursionField';
|
import { NocoBaseRecursionField } from '../../../formily/NocoBaseRecursionField';
|
||||||
import { useCompile } from '../../hooks';
|
import { useCompile } from '../../hooks';
|
||||||
import { ActionContextProvider } from '../action';
|
import { ActionContextProvider, ActionDesigner, Action } from '../action';
|
||||||
import { useSubTableSpecialCase } from '../form-item/hooks/useSpecialCase';
|
import { useSubTableSpecialCase } from '../form-item/hooks/useSpecialCase';
|
||||||
import { SubFormProvider, useAssociationFieldContext, useFieldNames } from './hooks';
|
import { SubFormProvider, useAssociationFieldContext, useFieldNames } from './hooks';
|
||||||
import { useTableSelectorProps } from './InternalPicker';
|
import { useTableSelectorProps } from './InternalPicker';
|
||||||
import { Table } from './Table';
|
import { Table } from './Table';
|
||||||
import { getLabelFormatValue, useLabelUiSchema } from './util';
|
import { getLabelFormatValue, useLabelUiSchema } from './util';
|
||||||
|
import { GeneralSchemaDesigner } from '../../../schema-settings';
|
||||||
|
|
||||||
const subTableContainer = css`
|
const subTableContainer = css`
|
||||||
.ant-table-footer {
|
.ant-table-footer {
|
||||||
@ -80,16 +81,27 @@ const tableClassName = css`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const addNewButtonClassName = css`
|
const addNewButtonClassName = css`
|
||||||
display: block;
|
.ant-btn {
|
||||||
border-radius: 0px;
|
// display: block;
|
||||||
border-right: 1px solid rgba(0, 0, 0, 0.06);
|
// border-radius: 0px;
|
||||||
|
// border-right: 1px solid rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const selectButtonClassName = css`
|
const selectButtonClassName = css`
|
||||||
display: block;
|
.ant-btn {
|
||||||
border-radius: 0px;
|
// display: block;
|
||||||
|
// border-radius: 0px;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const AddNewAction = (props) => {
|
||||||
|
return <div className={addNewButtonClassName}>{props.children}</div>;
|
||||||
|
};
|
||||||
|
export const SelectAction = (props) => {
|
||||||
|
return <div className={selectButtonClassName}>{props.children}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
export const SubTable: any = observer(
|
export const SubTable: any = observer(
|
||||||
(props: any) => {
|
(props: any) => {
|
||||||
const { openSize } = props;
|
const { openSize } = props;
|
||||||
@ -196,6 +208,25 @@ export const SubTable: any = observer(
|
|||||||
hideOnSinglePage: false,
|
hideOnSinglePage: false,
|
||||||
};
|
};
|
||||||
}, [field.value?.length, pageSize, currentPage]);
|
}, [field.value?.length, pageSize, currentPage]);
|
||||||
|
|
||||||
|
const useSubTableAddNewProps = () => {
|
||||||
|
const { field } = useAssociationFieldContext<ArrayField>();
|
||||||
|
return {
|
||||||
|
onClick() {
|
||||||
|
field.value = field.value || [];
|
||||||
|
field.value.push(markRecordAsNew({}));
|
||||||
|
// 计算总页数,并跳转到最后一页
|
||||||
|
const totalPages = Math.ceil(field.value.length / (field.componentProps?.pageSize || 10));
|
||||||
|
setTimeout(() => {
|
||||||
|
setCurrentPage(totalPages);
|
||||||
|
});
|
||||||
|
return field.onInput(field.value);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const handleSelect = () => {
|
||||||
|
setVisibleSelector(true);
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className={subTableContainer}>
|
<div className={subTableContainer}>
|
||||||
<FlagProvider isInSubTable>
|
<FlagProvider isInSubTable>
|
||||||
@ -224,43 +255,40 @@ export const SubTable: any = observer(
|
|||||||
}
|
}
|
||||||
pagination={paginationConfig}
|
pagination={paginationConfig}
|
||||||
rowSelection={{ type: 'none', hideSelectAll: true }}
|
rowSelection={{ type: 'none', hideSelectAll: true }}
|
||||||
footer={() =>
|
|
||||||
field.editable && (
|
|
||||||
<>
|
|
||||||
{allowAddnew !== false && (
|
|
||||||
<Button
|
|
||||||
type={'text'}
|
|
||||||
block
|
|
||||||
className={addNewButtonClassName}
|
|
||||||
onClick={() => {
|
|
||||||
field.value = field.value || [];
|
|
||||||
field.value.push(markRecordAsNew({}));
|
|
||||||
// 计算总页数,并跳转到最后一页
|
|
||||||
const totalPages = Math.ceil(field.value.length / (field.componentProps?.pageSize || 10));
|
|
||||||
setCurrentPage(totalPages);
|
|
||||||
return field.onInput(field.value);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('Add new')}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
{allowSelectExistingRecord && (
|
|
||||||
<Button
|
|
||||||
type={'text'}
|
|
||||||
block
|
|
||||||
className={selectButtonClassName}
|
|
||||||
onClick={() => {
|
|
||||||
setVisibleSelector(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('Select')}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
isSubTable={true}
|
isSubTable={true}
|
||||||
/>
|
/>
|
||||||
|
{field.editable && (
|
||||||
|
<SchemaComponentOptions scope={{ useSubTableAddNewProps, handleSelect }}>
|
||||||
|
<Space
|
||||||
|
style={{
|
||||||
|
marginTop: '10px',
|
||||||
|
position: field.value?.length ? 'absolute' : 'relative',
|
||||||
|
bottom: '0',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{allowAddnew !== false && (
|
||||||
|
<RecursionField
|
||||||
|
onlyRenderProperties
|
||||||
|
basePath={field.address}
|
||||||
|
schema={fieldSchema.parent}
|
||||||
|
filterProperties={(s) => {
|
||||||
|
return s['x-component'] === 'AssociationField.SubTable.AddNewAction';
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{allowSelectExistingRecord && (
|
||||||
|
<RecursionField
|
||||||
|
onlyRenderProperties
|
||||||
|
basePath={field.address}
|
||||||
|
schema={fieldSchema.parent}
|
||||||
|
filterProperties={(s) => {
|
||||||
|
return s['x-component'] === 'AssociationField.SubTable.SelectAction';
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
</SchemaComponentOptions>
|
||||||
|
)}
|
||||||
</SubFormProvider>
|
</SubFormProvider>
|
||||||
</FormActiveFieldsProvider>
|
</FormActiveFieldsProvider>
|
||||||
</CollectionRecordProvider>
|
</CollectionRecordProvider>
|
||||||
|
@ -14,7 +14,7 @@ import { FileSelector } from './FileManager';
|
|||||||
import { InternalPicker } from './InternalPicker';
|
import { InternalPicker } from './InternalPicker';
|
||||||
import { Nester } from './Nester';
|
import { Nester } from './Nester';
|
||||||
import { ReadPretty } from './ReadPretty';
|
import { ReadPretty } from './ReadPretty';
|
||||||
import { SubTable } from './SubTable';
|
import { SubTable, AddNewAction, SelectAction } from './SubTable';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
AssociationFieldMode,
|
AssociationFieldMode,
|
||||||
@ -32,5 +32,7 @@ AssociationField.Viewer = Action.Container;
|
|||||||
AssociationField.InternalSelect = InternalPicker;
|
AssociationField.InternalSelect = InternalPicker;
|
||||||
AssociationField.ReadPretty = ReadPretty;
|
AssociationField.ReadPretty = ReadPretty;
|
||||||
AssociationField.FileSelector = FileSelector;
|
AssociationField.FileSelector = FileSelector;
|
||||||
|
AssociationField.SubTable.AddNewAction = AddNewAction;
|
||||||
|
AssociationField.SubTable.SelectAction = SelectAction;
|
||||||
|
|
||||||
export { useAssociationFieldContext } from './hooks';
|
export { useAssociationFieldContext } from './hooks';
|
||||||
|
@ -140,4 +140,55 @@ export default {
|
|||||||
},
|
},
|
||||||
properties: {},
|
properties: {},
|
||||||
},
|
},
|
||||||
|
AddNewAction: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'AssociationField.SubTable.AddNewAction',
|
||||||
|
properties: {
|
||||||
|
'add-new': {
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Add new") }}',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
|
'x-action': null,
|
||||||
|
'x-designer-props': {
|
||||||
|
enableDrag: false,
|
||||||
|
},
|
||||||
|
'x-action-settings': {
|
||||||
|
removable: false,
|
||||||
|
disableSecondConFirm: true,
|
||||||
|
},
|
||||||
|
'x-use-component-props': 'useSubTableAddNewProps',
|
||||||
|
'x-component-props': {
|
||||||
|
type: 'default',
|
||||||
|
onClick: '{{handleAddNew}}',
|
||||||
|
size: 'small',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SelectAction: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'AssociationField.SubTable.SelectAction',
|
||||||
|
properties: {
|
||||||
|
select: {
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Select") }}',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-action': null,
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
|
'x-designer-props': {
|
||||||
|
enableDrag: false,
|
||||||
|
},
|
||||||
|
'x-action-settings': {
|
||||||
|
removable: false,
|
||||||
|
disableSecondConFirm: true,
|
||||||
|
},
|
||||||
|
'x-component-props': {
|
||||||
|
type: 'default',
|
||||||
|
onClick: '{{handleSelect}}',
|
||||||
|
size: 'small',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user