mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 06:29:25 +08:00
Merge branch 'next' into develop
This commit is contained in:
commit
3c7138fff9
@ -2,9 +2,7 @@
|
||||
"version": "1.6.0-alpha.2",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"npmClientArgs": [
|
||||
"--ignore-engines"
|
||||
],
|
||||
"npmClientArgs": ["--ignore-engines"],
|
||||
"command": {
|
||||
"version": {
|
||||
"forcePublish": true,
|
||||
|
@ -69,7 +69,6 @@ export function ButtonEditor(props) {
|
||||
title: t('Button title'),
|
||||
default: fieldSchema.title,
|
||||
'x-component-props': {},
|
||||
// description: `原字段标题:${collectionField?.uiSchema?.title}`,
|
||||
},
|
||||
icon: {
|
||||
'x-decorator': 'FormItem',
|
||||
@ -78,7 +77,6 @@ export function ButtonEditor(props) {
|
||||
default: fieldSchema?.['x-component-props']?.icon,
|
||||
'x-component-props': {},
|
||||
'x-visible': !isLink,
|
||||
// description: `原字段标题:${collectionField?.uiSchema?.title}`,
|
||||
},
|
||||
iconColor: {
|
||||
title: t('Color'),
|
||||
@ -730,7 +728,7 @@ export const actionSettingsItems: SchemaSettingOptions['items'] = [
|
||||
'duplicate',
|
||||
'customize:create',
|
||||
].includes(fieldSchema['x-action'] || '');
|
||||
return !isPopupAction;
|
||||
return !isPopupAction && !fieldSchema?.['x-action-settings'].disableSecondConFirm;
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -957,11 +955,12 @@ export const ActionDesigner = (props) => {
|
||||
buttonEditorProps,
|
||||
linkageRulesProps,
|
||||
schemaSettings = 'ActionSettings',
|
||||
enableDrag = true,
|
||||
...restProps
|
||||
} = props;
|
||||
const app = useApp();
|
||||
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 defaultActionSettings = schemaSettings || 'ActionSettings';
|
||||
const hasAction = app.schemaSettingsManager.has(settingsName);
|
||||
|
@ -63,5 +63,5 @@ export const useLinkageAction = () => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const isRecordAction = useIsDetailBlock();
|
||||
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 insert = useInsertSchema('SubTable');
|
||||
const insertSelector = useInsertSchema('Selector');
|
||||
const insertSelect = useInsertSchema('SubTable.SelectAction');
|
||||
const insertAddNewAction = useInsertSchema('SubTable.AddNewAction');
|
||||
|
||||
const { options } = useAssociationFieldContext();
|
||||
const { actionName } = useACLActionParamsContext();
|
||||
useEffect(() => {
|
||||
@ -34,8 +37,14 @@ export const InternalSubTable = observer(
|
||||
useEffect(() => {
|
||||
if (field.componentProps?.allowSelectExistingRecord) {
|
||||
insertSelector(schema.Selector);
|
||||
insertSelect(schema.SelectAction);
|
||||
}
|
||||
}, [field.componentProps?.allowSelectExistingRecord]);
|
||||
useEffect(() => {
|
||||
if (field.componentProps?.allowAddnew !== false) {
|
||||
insertAddNewAction(schema.AddNewAction);
|
||||
}
|
||||
}, [field.componentProps?.allowAddnew]);
|
||||
const option = useSchemaOptionsContext();
|
||||
const components = {
|
||||
...option.components,
|
||||
|
@ -13,9 +13,9 @@ import { exchangeArrayState } from '@formily/core/esm/shared/internals';
|
||||
import { observer, useFieldSchema } from '@formily/react';
|
||||
import { action } from '@formily/reactive';
|
||||
import { isArr } from '@formily/shared';
|
||||
import { Button } from 'antd';
|
||||
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Space } from 'antd';
|
||||
import {
|
||||
FormProvider,
|
||||
RecordPickerContext,
|
||||
@ -32,12 +32,13 @@ import { markRecordAsNew } from '../../../data-source/collection-record/isNewRec
|
||||
import { FlagProvider } from '../../../flag-provider';
|
||||
import { NocoBaseRecursionField } from '../../../formily/NocoBaseRecursionField';
|
||||
import { useCompile } from '../../hooks';
|
||||
import { ActionContextProvider } from '../action';
|
||||
import { ActionContextProvider, ActionDesigner, Action } from '../action';
|
||||
import { useSubTableSpecialCase } from '../form-item/hooks/useSpecialCase';
|
||||
import { SubFormProvider, useAssociationFieldContext, useFieldNames } from './hooks';
|
||||
import { useTableSelectorProps } from './InternalPicker';
|
||||
import { Table } from './Table';
|
||||
import { getLabelFormatValue, useLabelUiSchema } from './util';
|
||||
import { GeneralSchemaDesigner } from '../../../schema-settings';
|
||||
|
||||
const subTableContainer = css`
|
||||
.ant-table-footer {
|
||||
@ -80,16 +81,27 @@ const tableClassName = css`
|
||||
`;
|
||||
|
||||
const addNewButtonClassName = css`
|
||||
display: block;
|
||||
border-radius: 0px;
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.06);
|
||||
.ant-btn {
|
||||
// display: block;
|
||||
// border-radius: 0px;
|
||||
// border-right: 1px solid rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
`;
|
||||
|
||||
const selectButtonClassName = css`
|
||||
display: block;
|
||||
border-radius: 0px;
|
||||
.ant-btn {
|
||||
// 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(
|
||||
(props: any) => {
|
||||
const { openSize } = props;
|
||||
@ -196,6 +208,25 @@ export const SubTable: any = observer(
|
||||
hideOnSinglePage: false,
|
||||
};
|
||||
}, [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 (
|
||||
<div className={subTableContainer}>
|
||||
<FlagProvider isInSubTable>
|
||||
@ -224,43 +255,40 @@ export const SubTable: any = observer(
|
||||
}
|
||||
pagination={paginationConfig}
|
||||
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}
|
||||
/>
|
||||
{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>
|
||||
</FormActiveFieldsProvider>
|
||||
</CollectionRecordProvider>
|
||||
|
@ -14,7 +14,7 @@ import { FileSelector } from './FileManager';
|
||||
import { InternalPicker } from './InternalPicker';
|
||||
import { Nester } from './Nester';
|
||||
import { ReadPretty } from './ReadPretty';
|
||||
import { SubTable } from './SubTable';
|
||||
import { SubTable, AddNewAction, SelectAction } from './SubTable';
|
||||
|
||||
export {
|
||||
AssociationFieldMode,
|
||||
@ -32,5 +32,7 @@ AssociationField.Viewer = Action.Container;
|
||||
AssociationField.InternalSelect = InternalPicker;
|
||||
AssociationField.ReadPretty = ReadPretty;
|
||||
AssociationField.FileSelector = FileSelector;
|
||||
AssociationField.SubTable.AddNewAction = AddNewAction;
|
||||
AssociationField.SubTable.SelectAction = SelectAction;
|
||||
|
||||
export { useAssociationFieldContext } from './hooks';
|
||||
|
@ -140,4 +140,55 @@ export default {
|
||||
},
|
||||
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