Merge remote-tracking branch 'origin/main' into merge_from_upstream

This commit is contained in:
sealday 2024-03-14 22:19:15 +08:00
commit abec9982fb
365 changed files with 6937 additions and 2146 deletions

View File

@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
## [v0.20.0-alpha.10](https://github.com/nocobase/nocobase/compare/v0.20.0-alpha.9...v0.20.0-alpha.10) - 2024-03-13
### Merged
- fix(client): size undefined in nanoid [`#3708`](https://github.com/nocobase/nocobase/pull/3708)
- refactor(radio): radio support multiple field types [`#3706`](https://github.com/nocobase/nocobase/pull/3706)
- fix: get async json schema [`#3705`](https://github.com/nocobase/nocobase/pull/3705)
- fix: select fieldnames [`#3704`](https://github.com/nocobase/nocobase/pull/3704)
- fix: field configuration of Kanban interacts with other block [`#3689`](https://github.com/nocobase/nocobase/pull/3689)
- fix: radio [`#3701`](https://github.com/nocobase/nocobase/pull/3701)
- feat: add uuid & nanoid & unitTimestamp interface [`#3684`](https://github.com/nocobase/nocobase/pull/3684)
- fix(plugin-workflow): fix duplicated triggering schedule event [`#3692`](https://github.com/nocobase/nocobase/pull/3692)
- refactor(client): add component to support data source select [`#3691`](https://github.com/nocobase/nocobase/pull/3691)
- fix(Form): should be created instead of updated when clicking submit [`#3687`](https://github.com/nocobase/nocobase/pull/3687)
- fix: incorrect pagination query parameters when batch deleting last page [`#3670`](https://github.com/nocobase/nocobase/pull/3670)
### Commits
- chore(versions): 😊 publish v0.20.0-alpha.10 [`40a2294`](https://github.com/nocobase/nocobase/commit/40a22943b91455734a255b6598178391d7887999)
- chore: update changelog [`a8e37f6`](https://github.com/nocobase/nocobase/commit/a8e37f6224a5a03f90164a2848ad2e9a250bebae)
- fix: add external deps [`24b52c9`](https://github.com/nocobase/nocobase/commit/24b52c98d18f11083e97f584b8e23749846052f0)
## [v0.20.0-alpha.9](https://github.com/nocobase/nocobase/compare/v0.20.0-alpha.8...v0.20.0-alpha.9) - 2024-03-12
### Merged
@ -144,11 +166,21 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- chore: update changelog [`eda9a37`](https://github.com/nocobase/nocobase/commit/eda9a37e997c08744e9f648466412b620ccc98cd)
- fix: import [`e5a380f`](https://github.com/nocobase/nocobase/commit/e5a380ff394b6f1c2b8b77ad7505e78321c3f471)
## [v0.20.0-alpha.1](https://github.com/nocobase/nocobase/compare/v0.19.0-alpha.9...v0.20.0-alpha.1) - 2024-03-03
## [v0.20.0-alpha.1](https://github.com/nocobase/nocobase/compare/v0.19.0-alpha.10...v0.20.0-alpha.1) - 2024-03-03
### Merged
- feat: support for multiple data sources [`#3418`](https://github.com/nocobase/nocobase/pull/3418)
### Commits
- chore(versions): 😊 publish v0.20.0-alpha.1 [`29e10f3`](https://github.com/nocobase/nocobase/commit/29e10f365fc51e2f9838320cbc1d672dd390a1ef)
## [v0.19.0-alpha.10](https://github.com/nocobase/nocobase/compare/v0.19.0-alpha.9...v0.19.0-alpha.10) - 2024-03-13
### Merged
- fix: get async json schema [`#3705`](https://github.com/nocobase/nocobase/pull/3705)
- fix(plugin-workflow): fix off static schedule trigger [`#3595`](https://github.com/nocobase/nocobase/pull/3595)
- fix(plugin-workflow): fix interval number greater then 32-bits integer [`#3592`](https://github.com/nocobase/nocobase/pull/3592)
- fix: plugin settings auth bug [`#3585`](https://github.com/nocobase/nocobase/pull/3585)
@ -157,7 +189,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
### Commits
- chore(versions): 😊 publish v0.20.0-alpha.1 [`29e10f3`](https://github.com/nocobase/nocobase/commit/29e10f365fc51e2f9838320cbc1d672dd390a1ef)
- chore(versions): 😊 publish v0.19.0-alpha.10 [`7a74b10`](https://github.com/nocobase/nocobase/commit/7a74b101f42acdb3d0833214e70cea132b1156e2)
- chore: update changelog [`866eccc`](https://github.com/nocobase/nocobase/commit/866eccc60770fa2d2b42138e7083d78730d82de8)
## [v0.19.0-alpha.9](https://github.com/nocobase/nocobase/compare/v0.19.0-alpha.8...v0.19.0-alpha.9) - 2024-02-28

View File

@ -1,5 +1,5 @@
{
"version": "0.20.0-alpha.9",
"version": "0.20.0-alpha.10",
"npmClient": "yarn",
"useWorkspaces": true,
"npmClientArgs": ["--ignore-engines"],

View File

@ -1,13 +1,13 @@
{
"name": "@nocobase/acl",
"version": "0.20.0-alpha.9",
"version": "0.20.0-alpha.10",
"description": "",
"license": "Apache-2.0",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"dependencies": {
"@nocobase/resourcer": "0.20.0-alpha.9",
"@nocobase/utils": "0.20.0-alpha.9",
"@nocobase/resourcer": "0.20.0-alpha.10",
"@nocobase/utils": "0.20.0-alpha.10",
"minimatch": "^5.1.1"
},
"repository": {

View File

@ -1,14 +1,14 @@
{
"name": "@nocobase/actions",
"version": "0.20.0-alpha.9",
"version": "0.20.0-alpha.10",
"description": "",
"license": "Apache-2.0",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"dependencies": {
"@nocobase/cache": "0.20.0-alpha.9",
"@nocobase/database": "0.20.0-alpha.9",
"@nocobase/resourcer": "0.20.0-alpha.9"
"@nocobase/cache": "0.20.0-alpha.10",
"@nocobase/database": "0.20.0-alpha.10",
"@nocobase/resourcer": "0.20.0-alpha.10"
},
"repository": {
"type": "git",

View File

@ -1,17 +1,17 @@
{
"name": "@nocobase/app",
"version": "0.20.0-alpha.9",
"version": "0.20.0-alpha.10",
"description": "",
"license": "AGPL-3.0",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"dependencies": {
"@nocobase/database": "0.20.0-alpha.9",
"@nocobase/preset-nocobase": "0.20.0-alpha.9",
"@nocobase/server": "0.20.0-alpha.9"
"@nocobase/database": "0.20.0-alpha.10",
"@nocobase/preset-nocobase": "0.20.0-alpha.10",
"@nocobase/server": "0.20.0-alpha.10"
},
"devDependencies": {
"@nocobase/client": "0.20.0-alpha.9"
"@nocobase/client": "0.20.0-alpha.10"
},
"repository": {
"type": "git",

View File

@ -1,16 +1,16 @@
{
"name": "@nocobase/auth",
"version": "0.20.0-alpha.9",
"version": "0.20.0-alpha.10",
"description": "",
"license": "Apache-2.0",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"dependencies": {
"@nocobase/actions": "0.20.0-alpha.9",
"@nocobase/cache": "0.20.0-alpha.9",
"@nocobase/database": "0.20.0-alpha.9",
"@nocobase/resourcer": "0.20.0-alpha.9",
"@nocobase/utils": "0.20.0-alpha.9",
"@nocobase/actions": "0.20.0-alpha.10",
"@nocobase/cache": "0.20.0-alpha.10",
"@nocobase/database": "0.20.0-alpha.10",
"@nocobase/resourcer": "0.20.0-alpha.10",
"@nocobase/utils": "0.20.0-alpha.10",
"@types/jsonwebtoken": "^8.5.8",
"jsonwebtoken": "^8.5.1"
},

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/build",
"version": "0.20.0-alpha.9",
"version": "0.20.0-alpha.10",
"description": "Library build tool based on rollup.",
"main": "lib/index.js",
"types": "./lib/index.d.ts",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/cache",
"version": "0.20.0-alpha.9",
"version": "0.20.0-alpha.10",
"description": "",
"license": "Apache-2.0",
"main": "./lib/index.js",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/cli",
"version": "0.20.0-alpha.9",
"version": "0.20.0-alpha.10",
"description": "",
"license": "Apache-2.0",
"main": "./src/index.js",
@ -8,7 +8,7 @@
"nocobase": "./bin/index.js"
},
"dependencies": {
"@nocobase/app": "0.20.0-alpha.9",
"@nocobase/app": "0.20.0-alpha.10",
"@types/fs-extra": "^11.0.1",
"@umijs/utils": "3.5.20",
"chalk": "^4.1.1",
@ -25,7 +25,7 @@
"tsx": "^4.6.2"
},
"devDependencies": {
"@nocobase/devtools": "0.20.0-alpha.9"
"@nocobase/devtools": "0.20.0-alpha.10"
},
"repository": {
"type": "git",

View File

@ -1,6 +1,6 @@
{
"name": "@nocobase/client",
"version": "0.20.0-alpha.9",
"version": "0.20.0-alpha.10",
"license": "Apache-2.0",
"main": "lib/index.js",
"module": "es/index.mjs",
@ -26,9 +26,9 @@
"@formily/reactive-react": "^2.2.27",
"@formily/shared": "^2.2.27",
"@formily/validator": "^2.2.27",
"@nocobase/evaluators": "0.20.0-alpha.9",
"@nocobase/sdk": "0.20.0-alpha.9",
"@nocobase/utils": "0.20.0-alpha.9",
"@nocobase/evaluators": "0.20.0-alpha.10",
"@nocobase/sdk": "0.20.0-alpha.10",
"@nocobase/utils": "0.20.0-alpha.10",
"ahooks": "^3.7.2",
"antd": "^5.12.8",
"antd-style": "3.4.5",

View File

@ -0,0 +1,66 @@
import { CompatibleSchemaInitializer, isInitializersSame } from '../schema-initializer/CompatibleSchemaInitializer';
describe('CompatibleSchemaInitializer', () => {
it('should synchronize add operations between instances', () => {
const first = new CompatibleSchemaInitializer({ type: 'item', items: [], name: 'firstSchema' });
const second = new CompatibleSchemaInitializer({ type: 'item', items: [], name: 'secondSchema' }, first);
first.add('item1', { type: 'item', test: true });
expect(second.items).toContainEqual({ type: 'item', name: 'item1', test: true });
expect(first.items).toContainEqual({ type: 'item', name: 'item1', test: true });
});
it('should synchronize remove operations between instances', () => {
const first = new CompatibleSchemaInitializer({
type: 'item',
items: [{ type: 'item', name: 'toRemove', test: true }],
name: 'firstSchema',
});
const second = new CompatibleSchemaInitializer(
{ type: 'item', items: [{ type: 'item', name: 'toRemove', test: true }], name: 'secondSchema' },
first,
);
first.remove('toRemove');
expect(first.items).not.toContainEqual({ type: 'item', name: 'toRemove', test: true });
expect(second.items).not.toContainEqual({ type: 'item', name: 'toRemove', test: true });
});
});
describe('isInitializersSame', () => {
test('should return true for matching old and new names directly', () => {
expect(isInitializersSame('page:addBlock', 'page:addBlock')).toBeTruthy();
});
test('should return true for an old name matching a new name via the mapping', () => {
expect(isInitializersSame('BlockInitializers', 'page:addBlock')).toBeTruthy();
});
test('should return false when old name does not match and is not found in mapping', () => {
expect(isInitializersSame('NonExistentInitializer', 'page:addBlock')).toBeFalsy();
});
test('should handle case where old name is in the map but does not match the new name', () => {
expect(isInitializersSame('BlockInitializers', 'mobilePage:addBlock')).toBeFalsy();
});
test('should return true for complex name structures that match through the mapping', () => {
expect(isInitializersSame('CreateFormBlockInitializers', 'popup:addNew:addBlock')).toBeTruthy();
});
test('should return false for complex name structures that do not match any new name', () => {
expect(isInitializersSame('CreateFormBlockInitializers', 'nonExistentAction')).toBeFalsy();
});
test('should return true for new names that match directly and are not in the mapping', () => {
expect(isInitializersSame('unmappedNewInitializer:action', 'unmappedNewInitializer:action')).toBeTruthy();
});
test('should return false for old names trying to match to unrelated new names', () => {
expect(isInitializersSame('BlockInitializers', 'unrelatedNewInitializer:action')).toBeFalsy();
});
test('should handle empty strings', () => {
expect(isInitializersSame('', '')).toBeTruthy();
expect(isInitializersSame('', 'page:addBlock')).toBeFalsy();
expect(isInitializersSame('BlockInitializers', '')).toBeFalsy();
});
});

View File

@ -0,0 +1,74 @@
import { SchemaInitializer } from '../schema-initializer/SchemaInitializer';
describe('SchemaInitializer', () => {
it('should initialize with default items when no options provided', () => {
const schema = new SchemaInitializer({ name: 'schema0' });
expect(schema.items).toEqual([]);
});
it('should initialize with provided items', () => {
const schema = new SchemaInitializer({ type: 'item', items: [{ name: 'test', type: 'item' }], name: 'schema1' });
expect(schema.items).toEqual([{ type: 'item', name: 'test' }]);
});
it('should add item with unique name', () => {
const schema = new SchemaInitializer({ items: [], name: 'schema2' });
schema.add('item1', { type: 'item', test: true });
expect(schema.items).toContainEqual({ type: 'item', name: 'item1', test: true });
});
it('should replace item with same name', () => {
const schema = new SchemaInitializer({
type: 'item',
items: [{ type: 'item', name: 'item1', test: false }],
name: 'schema3',
});
schema.add('item1', { type: 'item', test: true });
expect(schema.items).toContainEqual({ type: 'item', name: 'item1', test: true });
expect(schema.items.length).toBe(1);
});
it('should add children to the specified parent item', () => {
const schema = new SchemaInitializer({
type: 'item',
items: [{ type: 'item', name: 'parent', children: [] }],
name: 'schema4',
});
schema.add('parent.child', { type: 'item', test: true });
expect(schema.get('parent').children).toContainEqual({ type: 'item', name: 'child', test: true });
});
it('should get the item by nested name', () => {
const schema = new SchemaInitializer({
type: 'item',
items: [{ type: 'item', name: 'parent', children: [{ type: 'item', name: 'child', test: true }] }],
name: 'schema5',
});
expect(schema.get('parent.child')).toEqual({ type: 'item', name: 'child', test: true });
});
it('should return undefined for non-existent item', () => {
const schema = new SchemaInitializer({ type: 'item', items: [], name: 'schema6' });
expect(schema.get('nonexistent')).toBeUndefined();
});
it('should remove the specified item', () => {
const schema = new SchemaInitializer({
type: 'item',
items: [{ type: 'item', name: 'toRemove', test: true }],
name: 'schema7',
});
schema.remove('toRemove');
expect(schema.items).not.toContainEqual({ type: 'item', name: 'toRemove', test: true });
});
it('should remove the specified nested item', () => {
const schema = new SchemaInitializer({
type: 'item',
items: [{ type: 'item', name: 'parent', children: [{ type: 'item', name: 'toRemove', test: true }] }],
name: 'schema8',
});
schema.remove('parent.toRemove');
expect(schema.get('parent').children).not.toContainEqual({ type: 'item', name: 'toRemove', test: true });
});
});

View File

@ -0,0 +1,99 @@
import { SchemaInitializer } from './SchemaInitializer';
/**
* @internal
*
* SchemaInitializer name Schema
* 使 Schema 使
* name Schema name
*
* 1. name
* 2. name 使
*/
export class CompatibleSchemaInitializer extends SchemaInitializer {
/**
*
*/
otherInstance: CompatibleSchemaInitializer = null;
constructor(options: any, otherInstance?: CompatibleSchemaInitializer) {
super(options);
if (otherInstance) {
this.otherInstance = otherInstance;
otherInstance.otherInstance = this;
}
}
add(name: string, item: any) {
if (super.get(name)) return;
super.add(name, item);
if (this.otherInstance) {
this.otherInstance.add(name, item);
}
}
remove(nestedName: string): void {
if (!super.get(nestedName)) return;
super.remove(nestedName);
if (this.otherInstance) {
this.otherInstance.remove(nestedName);
}
}
}
const oldToNewNameMap = {
BlockInitializers: 'page:addBlock',
MBlockInitializers: 'mobilePage:addBlock',
CreateFormBlockInitializers: 'popup:addNew:addBlock',
CusomeizeCreateFormBlockInitializers: 'popup:addRecord:addBlock',
RecordBlockInitializers: 'popup:common:addBlock',
BulkEditBlockInitializers: 'popup:bulkEdit:addBlock',
TableColumnInitializers: 'table:configureColumns',
TableActionColumnInitializers: 'table:configureItemActions',
TableActionInitializers: 'table:configureActions',
SubTableActionInitializers: 'subTable:configureActions',
FormItemInitializers: 'form:configureFields',
CreateFormActionInitializers: 'createForm:configureActions',
UpdateFormActionInitializers: 'editForm:configureActions',
ReadPrettyFormItemInitializers: 'details:configureFields',
DetailsActionInitializers: 'detailsWithPaging:configureActions',
ReadPrettyFormActionInitializers: 'details:configureActions',
KanbanCardInitializers: 'kanban:configureItemFields',
KanbanActionInitializers: 'kanban:configureActions',
GridCardActionInitializers: 'gridCard:configureActions',
GridCardItemActionInitializers: 'gridCard:configureItemActions',
ListActionInitializers: 'list:configureActions',
ListItemActionInitializers: 'list:configureItemActions',
CalendarActionInitializers: 'calendar:configureActions',
GanttActionInitializers: 'gantt:configureActions',
MapActionInitializers: 'map:configureActions',
TableSelectorInitializers: 'popup:tableSelector:addBlock',
ChartInitializers: 'charts:addBlock',
ChartFilterItemInitializers: 'chartFilterForm:configureFields',
ChartFilterActionInitializers: 'chartFilterForm:configureActions',
AssociationFilterInitializers: 'filterCollapse:configureFields',
FilterFormItemInitializers: 'filterForm:configureFields',
FilterFormActionInitializers: 'filterForm:configureActions',
CustomFormItemInitializers: 'assignFieldValuesForm:configureFields',
BulkEditFormItemInitializers: 'bulkEditForm:configureFields',
BulkEditFormActionInitializers: 'bulkEditForm:configureActions',
AuditLogsTableColumnInitializers: 'auditLogsTable:configureColumns',
AuditLogsTableActionColumnInitializers: 'auditLogsTable:configureItemActions',
AuditLogsTableActionInitializers: 'auditLogsTable:configureActions',
SnapshotBlockInitializers: 'popup:snapshot:addBlock',
AddBlockButton: 'workflowManual:popup:configureUserInterface:addBlock',
AddCustomFormField: 'workflowManual:customForm:configureFields',
AddActionButton: 'workflowManual:form:configureActions',
};
/**
* schema x-initializer
*
* @param oldOrNewName x-initializer
* @param newName
*/
export function isInitializersSame(oldOrNewName: string, newName: string) {
return oldOrNewName === newName || oldToNewNameMap[oldOrNewName] === newName;
}

View File

@ -49,7 +49,10 @@ export const SchemaInitializerChild: FC<SchemaInitializerItemType> = memo((props
const componentVal = Component || component;
const isBuiltType = !componentVal && type && typeComponentMap[type];
const componentChildren = useChildrenRes || children;
const componentChildren = useMemo(() => {
const res = [...(useChildrenRes || []), ...(children || [])];
return res.length === 0 ? undefined : res;
}, [useChildrenRes, children]);
const contextValue = useMemo(() => {
return {
...others,

View File

@ -50,6 +50,9 @@ export const SchemaInitializerMenu: FC<MenuProps> = (props) => {
.ant-menu-sub {
max-height: 50vh !important;
}
.ant-menu-item {
margin-block: 0;
}
.ant-menu-root {
margin: 0 -${token.margin}px;
.ant-menu-submenu-title {

View File

@ -41,6 +41,7 @@ export function useGetSchemaInitializerMenuItems(onClick?: (args: any) => void)
return {
key: item.key,
label: element,
associationField: item.associationField,
};
}
if (item.type === 'itemGroup') {
@ -73,6 +74,7 @@ export function useGetSchemaInitializerMenuItems(onClick?: (args: any) => void)
return {
key,
label,
associationField: item.associationField,
onClick: (info) => {
if (info.key !== key) return;
if (item.onClick) {

View File

@ -4,4 +4,5 @@ export * from './types';
export * from './context';
export * from './components';
export * from './SchemaInitializer';
export * from './CompatibleSchemaInitializer';
export * from './SchemaInitializerManager';

View File

@ -84,7 +84,10 @@ export const SchemaSettingsChild: FC<SchemaSettingsItemType> = memo((props) => {
const useChildrenRes = useChildren();
const useComponentPropsRes = useComponentProps();
const findComponent = useFindComponent();
const componentChildren = useChildrenRes || children;
const componentChildren = useMemo(() => {
const res = [...(useChildrenRes || []), ...(children || [])];
return res.length === 0 ? undefined : res;
}, [useChildrenRes, children]);
const visibleResult = useVisible();
const ComponentValue = useMemo(() => {
return !Component && type && typeComponentMap[type] ? typeComponentMap[type] : Component;

View File

@ -346,7 +346,7 @@ export const useParamsFromRecord = () => {
const obj = {
filterByTk: filterByTk,
};
if (record.__collection && !['oho', 'm2o', 'obo'].includes(collectionField?.interface)) {
if (record.__collection && collectionField && !['oho', 'm2o', 'obo'].includes(collectionField.interface)) {
obj['targetCollection'] = record.__collection;
}
if (!filterByTk) {

View File

@ -19,11 +19,11 @@ const InternalDetailsBlockProvider = (props) => {
createForm({
readPretty,
}),
[],
[readPretty],
);
const { resource, service } = useBlockRequestContext();
const parentRecord = useCollectionParentRecord();
const currentRecord = service?.data?.data?.[0] || {};
const currentRecord = (action === 'list' ? service?.data?.data?.[0] : service?.data?.data) || {};
const detailsBLockValue = useMemo(() => {
return {
action,
@ -38,7 +38,7 @@ const InternalDetailsBlockProvider = (props) => {
filterOption: service?.params?.[0]?.filter,
});
useEffect(() => {
if (!_.isEmpty(filter)) {
if (!_.isEmpty(filter) && !service.loading) {
service?.run({ ...service?.params?.[0], filter });
}
}, [JSON.stringify(filter)]);
@ -65,6 +65,9 @@ export const DetailsBlockProvider = (props) => {
);
};
/**
* @deprecated
*/
export const useDetailsBlockContext = () => {
return useContext(DetailsBlockContext);
};
@ -73,14 +76,15 @@ export const useDetailsBlockProps = () => {
const ctx = useDetailsBlockContext();
useEffect(() => {
if (!ctx.service.loading) {
const data = ctx.action === 'list' ? ctx.service?.data?.data?.[0] : ctx.service?.data?.data;
ctx.form
.reset()
.then(() => {
ctx.form.setValues(ctx.service?.data?.data?.[0] || {});
ctx.form.setValues(data || {});
})
.catch(console.error);
}
}, [ctx.service.loading]);
}, [ctx.action, ctx.form, ctx.service?.data?.data, ctx.service.loading]);
return {
form: ctx.form,
};

View File

@ -145,7 +145,15 @@ export const useTableBlockProps = () => {
field.componentProps.pagination.total = ctx?.service?.data?.meta?.count;
field.componentProps.pagination.current = ctx?.service?.data?.meta?.page;
}
}, [ctx?.service?.loading]);
}, [
ctx?.field?.data?.selectedRowKeys,
ctx?.service?.data?.data,
ctx?.service?.data?.meta?.count,
ctx?.service?.data?.meta?.page,
ctx?.service?.data?.meta?.pageSize,
ctx?.service?.loading,
field,
]);
return {
childrenColumnName: ctx.childrenColumnName,
loading: ctx?.service?.loading,
@ -199,6 +207,9 @@ export const useTableBlockProps = () => {
const storedFilter = block.service.params?.[1]?.filters || {};
if (selectedRow.includes(record[ctx.rowKey])) {
if (block.dataLoadingMode === 'manual') {
return block.clearData();
}
delete storedFilter[uid];
} else {
storedFilter[uid] = {

View File

@ -148,7 +148,7 @@ export const useTableFieldProps = () => {
field.data = field.data || {};
field.data.selectedRowKeys = ctx?.field?.data?.selectedRowKeys;
}
}, [ctx?.service?.loading]);
}, [ctx?.field?.data?.selectedRowKeys, ctx?.service?.data?.data, ctx?.service?.loading, field]);
return {
size: 'middle',
loading: ctx?.service?.loading,

View File

@ -290,7 +290,16 @@ export const useTableSelectorProps = () => {
field.componentProps.pagination.total = ctx?.service?.data?.meta?.count;
field.componentProps.pagination.current = ctx?.service?.data?.meta?.page;
}
}, [ctx?.service?.loading]);
}, [
collectionField?.foreignKey,
ctx?.field?.data?.selectedRowKeys,
ctx?.service?.data?.data,
ctx?.service?.data?.meta?.count,
ctx?.service?.data?.meta?.page,
ctx?.service?.data?.meta?.pageSize,
ctx?.service?.loading,
field,
]);
return {
loading: ctx?.service?.loading,
showIndex: false,

View File

@ -11,6 +11,7 @@ import { useReactToPrint } from 'react-to-print';
import {
AssociationFilter,
useCollectionRecord,
useDataLoadingMode,
useDataSourceHeaders,
useFormActiveFields,
useFormBlockContext,
@ -198,6 +199,10 @@ export const useCreateActionProps = () => {
const collectValues = useCollectValuesToSubmit();
const action = record.isNew ? actionField.componentProps.saveMode || 'create' : 'update';
const filterKeys = actionField.componentProps.filterKeys?.checked || [];
const dataLoadingMode = useDataLoadingMode();
console.log('dataLoadingMode', dataLoadingMode);
return {
async onClick() {
const { onSuccess, skipValidator, triggerWorkflows } = actionSchema?.['x-action-settings'] ?? {};
@ -426,6 +431,10 @@ export const useFilterBlockActionProps = () => {
block.defaultFilter,
]);
if (block.dataLoadingMode === 'manual' && _.isEmpty(mergedFilter)) {
return block.clearData();
}
return block.doFilter(
{
...param,
@ -436,11 +445,10 @@ export const useFilterBlockActionProps = () => {
);
}),
);
actionField.data.loading = false;
} catch (error) {
console.error(error);
actionField.data.loading = false;
}
actionField.data.loading = false;
},
};
};
@ -466,6 +474,10 @@ export const useResetBlockActionProps = () => {
const target = targets.find((target) => target.uid === block.uid);
if (!target) return;
if (block.dataLoadingMode === 'manual') {
return block.clearData();
}
const param = block.service.params?.[0] || {};
// 保留原有的 filter
const storedFilter = block.service.params?.[1]?.filters || {};
@ -1208,6 +1220,9 @@ export const useAssociationFilterBlockProps = () => {
[filterKey]: value,
};
} else {
if (block.dataLoadingMode === 'manual') {
return block.clearData();
}
delete storedFilter[key];
}

View File

@ -40,7 +40,7 @@ const schema: ISchema = {
type: 'void',
'x-component': Grid,
'x-read-pretty': true,
'x-initializer': 'AddFieldButton',
'x-initializer': 'addFieldButton',
'x-uid': uid(),
properties: {},
},
@ -124,7 +124,7 @@ const FormItemInitializer = () => {
};
const addFieldButton = new SchemaInitializer({
name: 'AddFieldButton',
name: 'addFieldButton',
// 正常情况下这个值为 false通过点击页面左上角的设计按钮切换这里为了显示设置为 true
designable: true,
// 按钮标题标题

View File

@ -398,7 +398,7 @@ export const recordPickerViewer = {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {},
},
},

View File

@ -42,13 +42,13 @@ export class SubTableFieldInterface extends CollectionFieldInterface {
properties: {
actions: {
type: 'void',
'x-initializer': 'SubTableActionInitializers',
'x-initializer': 'subTable:configureActions',
'x-component': 'TableField.ActionBar',
'x-component-props': {},
},
[field.name]: {
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowSelection: {

View File

@ -84,10 +84,16 @@ const PreviewCom = (props) => {
const fieldsData = Object.values(data?.data?.fields)?.map((v: any) => {
if (v.source) {
const option = fields?.data.find((h) => h.name === v.name) || v;
return { ...v, uiSchema: omit(option.uiSchema, 'rawTitle') };
return {
...v,
uiSchema: { ...omit(option.uiSchema, 'rawTitle'), title: option.uiSchema?.title || option.name },
};
} else {
const option = fields?.data.find((h) => h.name === v.name) || v;
return { ...option, uiSchema: omit(option.uiSchema, 'rawTitle') };
return {
...option,
uiSchema: { ...omit(option.uiSchema, 'rawTitle'), title: option.uiSchema?.title || option.name },
};
}
});
field.value = fieldsData;

View File

@ -31,47 +31,15 @@ describe('CollectionDeletedPlaceholder', () => {
});
describe('name exist', () => {
test("designable: true & process.env.NODE_ENV === 'development', render `Result` component", () => {
const NODE_ENV = process.env.NODE_ENV;
process.env.NODE_ENV = 'development';
test('designable: true, render `Result` component', () => {
renderApp('test', true);
process.env.NODE_ENV = NODE_ENV;
expect(document.body.innerHTML).toContain('ant-result');
});
test("designable: false & process.env.NODE_ENV === 'development', render `Result` component", () => {
const NODE_ENV = process.env.NODE_ENV;
process.env.NODE_ENV = 'development';
test('designable: false, render nothing', () => {
renderApp('test', false);
process.env.NODE_ENV = NODE_ENV;
expect(document.body.innerHTML).toContain('ant-result');
});
test("designable: true & process.env.NODE_ENV !== 'development', render `Result` component", () => {
const NODE_ENV = process.env.NODE_ENV;
process.env.NODE_ENV = 'production';
renderApp('test', true);
process.env.NODE_ENV = NODE_ENV;
expect(document.body.innerHTML).toContain('ant-result');
});
test("designable: false & process.env.NODE_ENV !== 'development', render nothing", () => {
const NODE_ENV = process.env.NODE_ENV;
process.env.NODE_ENV = 'production';
renderApp('test', false);
process.env.NODE_ENV = NODE_ENV;
expect(screen.getByTestId('app').innerHTML.length).toBe(0);
});
});

View File

@ -61,7 +61,7 @@ export const CollectionDeletedPlaceholder: FC<CollectionDeletedPlaceholderProps>
}).replaceAll('&gt;', '>');
}, [message, nameValue, type, t, blockType]);
if (designable || process.env.NODE_ENV === 'development') {
if (designable) {
if (type === 'Field') {
return <Text type="secondary">{messageValue}</Text>;
}

View File

@ -24,6 +24,7 @@ export interface AllDataBlockProps {
parentRecord?: CollectionRecord;
requestService?: UseRequestService<any>;
requestOptions?: UseRequestOptions;
dataLoadingMode?: 'auto' | 'manual';
[index: string]: any;
}

View File

@ -6,11 +6,13 @@ import { CollectionRecordProvider, CollectionRecord } from '../collection-record
import { AllDataBlockProps, useDataBlockProps } from './DataBlockProvider';
import { useDataBlockResource } from './DataBlockResourceProvider';
import { useDataSourceHeaders } from '../utils';
import { useDataLoadingMode } from '../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem';
export const BlockRequestContext = createContext<UseRequestResult<any>>(null);
BlockRequestContext.displayName = 'BlockRequestContext';
function useCurrentRequest<T>(options: Omit<AllDataBlockProps, 'type'>) {
const dataLoadingMode = useDataLoadingMode();
const resource = useDataBlockResource();
const { action, params = {}, record, requestService, requestOptions } = options;
if (params.filterByTk === undefined) {
@ -36,13 +38,13 @@ function useCurrentRequest<T>(options: Omit<AllDataBlockProps, 'type'>) {
// 因为修改 Schema 会导致 params 对象发生变化,所以这里使用 `DeepCompare`
useDeepCompareEffect(() => {
if (action) {
if (action && dataLoadingMode === 'auto') {
request.run();
}
}, [params, action, record]);
useUpdateEffect(() => {
if (action) {
if (action && dataLoadingMode === 'auto') {
request.run();
}
}, [resource]);
@ -131,9 +133,5 @@ export const BlockRequestProvider: FC = ({ children }) => {
export const useDataBlockRequest = <T extends {}>(): UseRequestResult<{ data: T }> => {
const context = useContext(BlockRequestContext);
if (!context) {
throw new Error('useDataBlockRequest() must be used within a DataBlockRequestProvider');
}
return context;
};

View File

@ -1,10 +1,12 @@
import { useField, useFieldSchema } from '@formily/react';
import { uniqBy } from 'lodash';
import React, { createContext, useEffect, useRef } from 'react';
import React, { createContext, useCallback, useEffect, useRef } from 'react';
import { useBlockRequestContext } from '../block-provider/BlockProvider';
import { CollectionFieldOptions_deprecated, useCollection_deprecated } from '../collection-manager';
import { removeNullCondition } from '../schema-component';
import { mergeFilter, useAssociatedFields } from './utils';
import { useDataLoadingMode } from '../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem';
import { GeneralField } from '@formily/core';
enum FILTER_OPERATOR {
AND = '$and',
@ -40,6 +42,8 @@ export interface DataBlock {
doFilter: (params: any, params2?: any) => Promise<void>;
/** 清除筛选区块设置的筛选参数 */
clearFilter: (uid: string) => void;
/** 将数据区块的数据置为空 */
clearData: () => void;
/** 数据区块表中所有的关系字段 */
associatedFields?: CollectionFieldOptions_deprecated[];
/** 数据区块表中所有的外键字段 */
@ -50,6 +54,11 @@ export interface DataBlock {
service?: any;
/** 数据区块所的 DOM 容器 */
dom: HTMLElement;
/**
* auto: 数据区块会在初始渲染时请求数据
* manual: 只有当点击了筛选按钮
*/
dataLoadingMode?: 'auto' | 'manual';
}
interface FilterContextValue {
@ -89,13 +98,14 @@ export const DataBlockCollector = ({
const fieldSchema = useFieldSchema();
const associatedFields = useAssociatedFields();
const container = useRef(null);
const dataLoadingMode = useDataLoadingMode();
const shouldApplyFilter =
field.decoratorType !== 'FilterFormBlockProvider' &&
field.decoratorType !== 'FormBlockProvider' &&
field.decoratorProps.blockType !== 'filter';
const addBlockToDataBlocks = () => {
const addBlockToDataBlocks = useCallback(() => {
recordDataBlocks({
uid: fieldSchema['x-uid'],
title: field.componentProps.title,
@ -106,6 +116,7 @@ export const DataBlockCollector = ({
defaultFilter: params?.filter || {},
service,
dom: container.current,
dataLoadingMode,
clearFilter(uid: string) {
const param = this.service.params?.[0] || {};
const storedFilter = this.service.params?.[1]?.filters || {};
@ -124,12 +135,15 @@ export const DataBlockCollector = ({
{ filters: storedFilter },
);
},
clearData() {
this.service.mutate(undefined);
},
});
};
}, [associatedFields, collection, dataLoadingMode, field, fieldSchema, params?.filter, recordDataBlocks, service]);
useEffect(() => {
if (shouldApplyFilter) addBlockToDataBlocks();
}, [params?.filter, service]);
}, [params.filter, service, dataLoadingMode, shouldApplyFilter, addBlockToDataBlocks]);
useEffect(() => {
return () => {
@ -163,6 +177,7 @@ export const useFilterBlock = () => {
// 这里的值有可能会变化,所以需要更新
existingBlock.service = block.service;
existingBlock.defaultFilter = block.defaultFilter;
existingBlock.dataLoadingMode = block.dataLoadingMode;
return;
}
// 由于 setDataBlocks 是异步操作,所以上面的 existingBlock 在判断时有可能用的是旧的 dataBlocks,所以下面还需要根据 uid 进行去重操作

View File

@ -58,6 +58,8 @@ export * from './modules/blocks/BlockSchemaToolbar';
export * from './modules/blocks/data-blocks/table';
export * from './modules/blocks/data-blocks/form';
export * from './modules/blocks/data-blocks/table-selector';
export * from './modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem';
export * as __UNSAFE__ from './unsafe';
export type {
DynamicComponentProps as __UNSAFE__DynamicComponentProps,

View File

@ -104,6 +104,10 @@
"Submit": "Submit",
"Close": "Close",
"Set the data scope": "Set the data scope",
"Set data loading mode": "Set data loading mode",
"Automatically load data": "Automatically load data",
"Load data after filtering": "Load data after filtering",
"Data loading mode": "Data loading mode",
"Data blocks": "Data blocks",
"Filter blocks": "Filter blocks",
"Table": "Table",
@ -354,6 +358,10 @@
"Add tab": "Add tab",
"Disable tabs": "Disable tabs",
"Details": "Details",
"Edit form": "Edit form",
"Create form": "Create form",
"Form (Edit)": "Form (Edit)",
"Form (Add new)": "Form (Add new)",
"Edit tab": "Edit tab",
"Relationship blocks": "Relationship blocks",
"Select record": "Select record",

View File

@ -99,6 +99,10 @@
"Submit": "Enviar",
"Close": "Cerrar",
"Set the data scope": "Establecer el ámbito de los datos",
"Data loading mode": "Modo de carga de datos",
"Set data loading mode": "Establecer el modo de carga de datos",
"Automatically load data": "Cargar datos",
"Load data after filtering": "Cargar datos después de filtrar",
"Data blocks": "Bloques de datos",
"Filter blocks": "Bloques de filtro",
"Table": "Tabla",
@ -327,6 +331,10 @@
"Add tab": "Añadir pestaña",
"Disable tabs": "Desactivar pestañas",
"Details": "Detalles",
"Edit form": "Editar formulario",
"Create form": "Crear formulario",
"Form (Edit)": "Formulario (Editar)",
"Form (Add new)": "Formulario (Añadir nuevo)",
"Edit tab": "Editar pestaña",
"Relationship blocks": "Bloques de relación",
"Select record": "Seleccionar registro",

View File

@ -99,6 +99,10 @@
"Submit": "Envoyer",
"Close": "Fermer",
"Set the data scope": "Définir la portée des données",
"Data loading mode": "Mode de chargement des données",
"Set data loading mode": "Définir le mode de chargement des données",
"Automatically load data": "Charger automatiquement les données",
"Load data after filtering": "Charger les données après filtrage",
"Data blocks": "Blocs de données",
"Filter blocks": "Blocs de filtre",
"Table": "Tableau",
@ -342,6 +346,10 @@
"Add tab": "Ajouter un onglet",
"Disable tabs": "Désactiver les onglets",
"Details": "Détails",
"Edit form": "Modifier le formulaire",
"Create form": "Créer un formulaire",
"Form (Edit)": "Formulaire (Modifier)",
"Form (Add new)": "Formulaire (Ajouter nouveau)",
"Edit tab": "Modifier l'onglet",
"Relationship blocks": "Blocs de relations",
"Select record": "Sélectionner un enregistrement",

View File

@ -102,6 +102,10 @@
"Submit": "送信",
"Close": "閉じる",
"Set the data scope": "データ範囲の設定",
"Data loading mode": "データ読み込みモード",
"Set data loading mode": "データ読み込みモードの設定",
"Automatically load data": "データを自動的に読み込む",
"Load data after filtering": "フィルタリング後にデータを読み込む",
"Data blocks": "データブロック",
"Filter blocks": "フィルターブロック",
"Table OID(Inheritance)": "データテーブルOID(継承)",
@ -289,6 +293,10 @@
"Add tab": "タブを追加",
"Disable tabs": "タブを無効にする",
"Details": "詳細",
"Edit form": "フォームを編集",
"Create form": "フォームを作成",
"Form (Edit)": "フォーム (編集)",
"Form (Add new)": "フォーム (新規追加)",
"Edit tab": "タブを編集",
"Relationship blocks": "関連付けされたブロック",
"Select record": "レコードを選択",

View File

@ -122,6 +122,10 @@
"Submit": "제출",
"Close": "닫기",
"Set the data scope": "데이터 범위 설정",
"Data loading mode": "데이터 로드 모드",
"Set data loading mode": "데이터 로드 모드 설정",
"Automatically load data": "데이터 자동 로드",
"Load data after filtering": "필터링 후 데이터 로드",
"Block": "블록",
"Data blocks": "데이터 블록",
"Filter blocks": "필터 블록",
@ -374,6 +378,10 @@
"Add tab": "탭 추가",
"Disable tabs": "탭 비활성화",
"Details": "세부 정보",
"Edit form": "폼 편집",
"Create form": "폼 생성",
"Form (Edit)": "폼 (편집)",
"Form (Add new)": "폼 (새로 추가)",
"Edit tab": "탭 편집",
"Relationship blocks": "관계 데이터 블록",
"Select record": "레코드 선택",

View File

@ -73,6 +73,10 @@
"Submit": "Enviar",
"Close": "Fechar",
"Set the data scope": "Definir o escopo de dados",
"Data loading mode": "Modo de carregamento de dados",
"Set data loading mode": "Definir modo de carregamento de dados",
"Automatically load data": "Carregar dados automaticamente",
"Load data after filtering": "Carregar dados após filtragem",
"Data blocks": "Blocos de dados",
"Filter blocks": "Blocos de filtro",
"Table": "Tabela",
@ -291,6 +295,10 @@
"Add tab": "Adicionar guia",
"Disable tabs": "Desativar guias",
"Details": "Detalhes",
"Edit form": "Editar formulário",
"Create form": "Criar formulário",
"Form (Edit)": "Formulário (Editar)",
"Form (Add new)": "Formulário (Adicionar novo)",
"Edit tab": "Editar guia",
"Relationship blocks": "Blocos de relacionamento",
"Select record": "Selecionar registro",

View File

@ -69,6 +69,10 @@
"Submit": "Отправить",
"Close": "Закрыть",
"Set the data scope": "Установить область данных",
"Data loading mode": "Режим загрузки данных",
"Set data loading mode": "Установить режим загрузки данных",
"Automatically load data": "Автоматически загружать данные",
"Load data after filtering": "Загружать данные после фильтрации",
"Data blocks": "Блоки данных",
"Filter blocks": "Просеивающие блоки",
"Table": "Таблица",
@ -229,6 +233,10 @@
"Add tab": "Добавить вкладку",
"Disable tabs": "Запретить вкладки",
"Details": "Подробности",
"Edit form": "Изменить форму",
"Create form": "Создать форму",
"Form (Edit)": "Форма (Изменить)",
"Form (Add new)": "Форма (Добавить новый)",
"Edit tab": "Изменить вкладку",
"Relationship blocks": "Блоки отношений",
"Select record": "Выбрать запись",

View File

@ -69,6 +69,10 @@
"Submit": "Gönder",
"Close": "Kapat",
"Set the data scope": "Veri kapsamını ayarla",
"Data loading mode": "Veri yükleme modu",
"Set data loading mode": "Veri yükleme modunu ayarla",
"Automatically load data": "Veriyi otomatik yükle",
"Load data after filtering": "Filtrelemeden sonra veriyi yükle",
"Data blocks": "Veri Blokları",
"Filter blocks": "Filtre blokları",
"Table": "Tablo",
@ -229,6 +233,10 @@
"Add tab": "Sekme ekle",
"Disable tabs": "Sekmeleri pasifleştir",
"Details": "Detaylar",
"Edit form": "Formu düzenle",
"Create form": "Form oluştur",
"Form (Edit)": "Form (Düzenle)",
"Form (Add new)": "Form (Yeni ekle)",
"Edit tab": "Sekme düzenle",
"Relationship blocks": "İlişki blokları",
"Select record": "Kayıt seç",

View File

@ -99,6 +99,10 @@
"Submit": "Відправити",
"Close": "Закрити",
"Set the data scope": "Встановити обсяг даних",
"Data loading mode": "Режим завантаження даних",
"Set data loading mode": "Встановити режим завантаження даних",
"Automatically load data": "Автоматично завантажувати дані",
"Load data after filtering": "Завантажувати дані після фільтрації",
"Data blocks": "Блоки даних",
"Filter blocks": "Блоки фільтрів",
"Table": "Таблиця",
@ -344,6 +348,10 @@
"Add tab": "Додати вкладку",
"Disable tabs": "Вимкнути вкладки",
"Details": "Деталі",
"Edit form": "Редагувати форму",
"Create form": "Створити форму",
"Form (Edit)": "Форма (Редагувати)",
"Form (Add new)": "Форма (Додати новий)",
"Edit tab": "Редагувати вкладку",
"Relationship blocks": "Блоки відношень",
"Select record": "Вибрати запис",

View File

@ -122,6 +122,10 @@
"Submit": "提交",
"Close": "关闭",
"Set the data scope": "设置数据范围",
"Data loading mode": "数据加载方式",
"Set data loading mode": "设置数据加载方式",
"Automatically load data": "自动加载数据",
"Load data after filtering": "筛选后才加载数据",
"Block": "区块",
"Data blocks": "数据区块",
"Filter blocks": "筛选区块",
@ -375,6 +379,10 @@
"Add tab": "添加标签页",
"Disable tabs": "禁用标签页",
"Details": "详情",
"Edit form": "编辑表单",
"Create form": "创建表单",
"Form (Edit)": "表单(编辑)",
"Form (Add new)": "表单(添加)",
"Edit tab": "编辑标签页",
"Relationship blocks": "关系数据区块",
"Select record": "选择数据",

View File

@ -122,6 +122,10 @@
"Submit": "提交",
"Close": "關閉",
"Set the data scope": "設定資料範圍",
"Data loading mode": "資料加載方式",
"Set data loading mode": "設定資料加載方式",
"Automatically load data": "自動加載資料",
"Load data after filtering": "篩選後才加載資料",
"Block": "區塊",
"Data blocks": "資料區塊",
"Filter blocks": "篩選區塊",
@ -374,6 +378,10 @@
"Add tab": "新增標籤頁",
"Disable tabs": "停用標籤頁",
"Details": "詳情",
"Edit form": "編輯表單",
"Create form": "建立表單",
"Form (Edit)": "表單(編輯)",
"Form (Add new)": "表單(添加)",
"Edit tab": "編輯標籤頁",
"Relationship blocks": "關聯資料區塊",
"Select record": "選擇資料",

View File

@ -41,7 +41,7 @@ export const CreateChildInitializer = (props) => {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'CreateFormBlockInitializers',
'x-initializer': 'popup:addNew:addBlock',
properties: {},
},
},

View File

@ -43,7 +43,7 @@ export const CreateActionInitializer = () => {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'CreateFormBlockInitializers',
'x-initializer': 'popup:addNew:addBlock',
properties: {},
},
},

View File

@ -1,7 +1,10 @@
import { SchemaInitializer } from '../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../application/schema-initializer/CompatibleSchemaInitializer';
import { gridRowColWrap } from '../../../schema-initializer/utils';
export const createFormBlockInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const createFormBlockInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'CreateFormBlockInitializers',
wrap: gridRowColWrap,
title: '{{t("Add block")}}',
@ -33,3 +36,39 @@ export const createFormBlockInitializers = new SchemaInitializer({
},
],
});
export const createFormBlockInitializers = new CompatibleSchemaInitializer(
{
name: 'popup:addNew:addBlock',
wrap: gridRowColWrap,
title: '{{t("Add block")}}',
icon: 'PlusOutlined',
items: [
{
type: 'itemGroup',
title: '{{t("Data blocks")}}',
name: 'dataBlocks',
children: [
{
name: 'form',
title: '{{t("Form")}}',
Component: 'CreateFormBlockInitializer',
},
],
},
{
type: 'itemGroup',
title: '{{t("Other blocks")}}',
name: 'otherBlocks',
children: [
{
name: 'markdown',
title: '{{t("Markdown")}}',
Component: 'MarkdownBlockInitializer',
},
],
},
],
},
createFormBlockInitializers_deprecated,
);

View File

@ -29,7 +29,7 @@ export const CustomizeAddRecordActionInitializer = () => {
'x-component-props': {},
'x-initializer': 'TabPaneInitializersForCreateFormBlock',
'x-initializer-props': {
gridInitializer: 'CusomeizeCreateFormBlockInitializers',
gridInitializer: 'popup:addRecord:addBlock',
},
properties: {
tab1: {
@ -42,7 +42,7 @@ export const CustomizeAddRecordActionInitializer = () => {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'CusomeizeCreateFormBlockInitializers',
'x-initializer': 'popup:addRecord:addBlock',
properties: {},
},
},

View File

@ -1,7 +1,10 @@
import { SchemaInitializer } from '../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../application/schema-initializer/CompatibleSchemaInitializer';
import { gridRowColWrap } from '../../../schema-initializer/utils';
export const customizeCreateFormBlockInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const customizeCreateFormBlockInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'CusomeizeCreateFormBlockInitializers',
wrap: gridRowColWrap,
title: '{{t("Add block")}}',
@ -34,3 +37,40 @@ export const customizeCreateFormBlockInitializers = new SchemaInitializer({
},
],
});
export const customizeCreateFormBlockInitializers = new CompatibleSchemaInitializer(
{
name: 'popup:addRecord:addBlock',
wrap: gridRowColWrap,
title: '{{t("Add block")}}',
icon: 'PlusOutlined',
items: [
{
type: 'itemGroup',
title: '{{t("Data blocks")}}',
name: 'dataBlocks',
children: [
{
name: 'form',
title: '{{t("Form")}}',
Component: 'FormBlockInitializer',
isCusomeizeCreate: true,
},
],
},
{
type: 'itemGroup',
title: '{{t("Other blocks")}}',
name: 'otherBlocks',
children: [
{
name: 'markdown',
title: '{{t("Markdown")}}',
Component: 'MarkdownBlockInitializer',
},
],
},
],
},
customizeCreateFormBlockInitializers_deprecated,
);

View File

@ -1,6 +1,6 @@
import { useFieldSchema } from '@formily/react';
import { isValid } from '@formily/shared';
import { useSchemaToolbar } from '../../../application';
import { isInitializersSame, useSchemaToolbar } from '../../../application';
import { SchemaSettings } from '../../../application/schema-settings/SchemaSettings';
import {
ButtonEditor,
@ -45,7 +45,6 @@ export const updateSubmitActionSettings = new SchemaSettings({
],
});
// TODO: 0.20 发版之前后移除
export const submitActionSettings = new SchemaSettings({
name: 'actionSettings:submit',
items: [
@ -76,7 +75,7 @@ export const submitActionSettings = new SchemaSettings({
const fieldSchema = useFieldSchema();
return (
fieldSchema['x-action'] === 'submit' &&
fieldSchema.parent?.['x-initializer'] === 'CreateFormActionInitializers'
isInitializersSame(fieldSchema.parent?.['x-initializer'], 'createForm:configureActions')
);
},
},

View File

@ -1,6 +1,6 @@
import React from 'react';
import { BlockInitializer } from '../../../schema-initializer/items';
import { useSchemaInitializerItem } from '../../../application';
import { BlockInitializer } from '../../../schema-initializer/items';
export const PopupActionInitializer = (props) => {
const schema = {
@ -38,7 +38,7 @@ export const PopupActionInitializer = (props) => {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {},
},
},

View File

@ -1,6 +1,9 @@
import { SchemaInitializer } from '../../../application/schema-initializer/SchemaInitializer';
import { gridRowColWrap } from '../../../schema-initializer/utils';
/**
* @deprecated
*/
export const recordFormBlockInitializers = new SchemaInitializer({
name: 'RecordFormBlockInitializers',
title: '{{ t("Add block") }}',

View File

@ -39,7 +39,7 @@ export const UpdateActionInitializer = (props) => {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {},
},
},

View File

@ -38,7 +38,7 @@ export const ViewActionInitializer = (props) => {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {},
},
},

View File

@ -1,7 +1,10 @@
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
// 表单的操作配置
export const detailsActionInitializers = new SchemaInitializer({
/**
* @deprecated
*
*/
export const detailsActionInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'DetailsActionInitializers',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
@ -49,3 +52,45 @@ export const detailsActionInitializers = new SchemaInitializer({
},
],
});
export const detailsActionInitializers = new CompatibleSchemaInitializer(
{
name: 'detailsWithPaging:configureActions',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
style: {
marginLeft: 8,
},
items: [
{
type: 'itemGroup',
title: '{{t("Enable actions")}}',
name: 'enableActions',
children: [
{
name: 'edit',
title: '{{t("Edit")}}',
Component: 'UpdateActionInitializer',
schema: {
'x-component': 'Action',
'x-decorator': 'ACLActionProvider',
'x-component-props': {
type: 'primary',
},
},
},
{
name: 'delete',
title: '{{t("Delete")}}',
Component: 'DestroyActionInitializer',
schema: {
'x-component': 'Action',
'x-decorator': 'ACLActionProvider',
},
},
],
},
],
},
detailsActionInitializers_deprecated,
);

View File

@ -4,8 +4,36 @@ import { useSchemaInitializer, useSchemaInitializerItem } from '../../../../appl
import { useCollectionManager_deprecated } from '../../../../collection-manager';
import { createDetailsBlockSchema } from '../../../../schema-initializer/utils';
import { DataBlockInitializer } from '../../../../schema-initializer/items/DataBlockInitializer';
import { Collection, CollectionFieldOptions } from '../../../../data-source/collection/Collection';
export const DetailsBlockInitializer = () => {
export const DetailsBlockInitializer = ({
filterCollections,
onlyCurrentDataSource,
hideSearch,
componentType = 'Details',
createBlockSchema,
templateWrap,
showAssociationFields,
}: {
filterCollections: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean;
onlyCurrentDataSource: boolean;
hideSearch?: boolean;
/**
* Details ReadPrettyFormItem
* template
*/
componentType?: 'Details' | 'ReadPrettyFormItem';
createBlockSchema?: (options: any) => any;
templateWrap?: (
templateSchema: any,
{
item,
}: {
item: any;
},
) => any;
showAssociationFields?: boolean;
}) => {
const { insert } = useSchemaInitializer();
const { getCollection } = useCollectionManager_deprecated();
const itemConfig = useSchemaInitializerItem();
@ -13,8 +41,13 @@ export const DetailsBlockInitializer = () => {
<DataBlockInitializer
{...itemConfig}
icon={<TableOutlined />}
componentType={'Details'}
onCreateBlockSchema={async ({ item }) => {
componentType={componentType}
onCreateBlockSchema={async (options) => {
if (createBlockSchema) {
return createBlockSchema(options);
}
const { item } = options;
const collection = getCollection(item.name, item.dataSource);
const schema = createDetailsBlockSchema({
collection: item.name,
@ -23,11 +56,16 @@ export const DetailsBlockInitializer = () => {
actionInitializers:
(collection.template !== 'view' || collection?.writableView) &&
collection.template !== 'sql' &&
'DetailsActionInitializers',
'detailsWithPaging:configureActions',
settings: 'blockSettings:multiDataDetails',
});
insert(schema);
}}
onlyCurrentDataSource={!!onlyCurrentDataSource}
hideSearch={hideSearch}
filter={filterCollections}
templateWrap={templateWrap}
showAssociationFields={showAssociationFields}
/>
);
};

View File

@ -3,17 +3,18 @@ import { createBlockInPage, expect, oneEmptyDetailsBlock, test } from '@nocobase
test.describe('where multi data details block can be added', () => {
test('page', async ({ page, mockPage }) => {
await mockPage().goto();
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
await createBlockInPage(page, 'Details');
await expect(page.getByLabel('block-item-CardItem-users-details')).toBeVisible();
});
});
test.describe('configure fields', () => {
test('display collection fields & display association fields & add text', async ({ page, mockPage }) => {
test('display collection fields & display association fields & add text', async ({ page, mockPage, mockRecord }) => {
await mockPage(oneEmptyDetailsBlock).goto();
await mockRecord('general');
const formItemInitializer = page.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general');
const formItemInitializer = page.getByLabel('schema-initializer-Grid-details:configureFields-general');
// add fields
await formItemInitializer.hover();
@ -60,10 +61,11 @@ test.describe('configure fields', () => {
});
test.describe('configure actions', () => {
test('edit & delete & duplicate', async ({ page, mockPage }) => {
test('edit & delete & duplicate', async ({ page, mockPage, mockRecord }) => {
await mockPage(oneEmptyDetailsBlock).goto();
await mockRecord('general');
await page.getByLabel('schema-initializer-ActionBar-DetailsActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-detailsWithPaging:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
@ -75,7 +77,7 @@ test.describe('configure actions', () => {
await expect(page.getByRole('button', { name: 'Delete' })).toBeVisible();
// delete buttons
await page.getByLabel('schema-initializer-ActionBar-DetailsActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-detailsWithPaging:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();

View File

@ -29,11 +29,12 @@ test.describe('multi data details block schema settings', () => {
});
test.describe('actions schema settings', () => {
test('edit & delete & duplicate', async ({ page, mockPage }) => {
test('edit & delete & duplicate', async ({ page, mockPage, mockRecord }) => {
await mockPage(oneEmptyDetailsBlock).goto();
await mockRecord('general');
// 创建 Edit & Delete 两个按钮
await page.getByLabel('schema-initializer-ActionBar-DetailsActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-detailsWithPaging:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.mouse.move(0, 300);

View File

@ -8,6 +8,7 @@ import { useCollection_deprecated, useSortFields } from '../../../../collection-
import { removeNullCondition, useDesignable } from '../../../../schema-component';
import { SchemaSettingsBlockTitleItem, SchemaSettingsTemplate } from '../../../../schema-settings';
import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope';
import { setDataLoadingModeSettingsItem, useDataLoadingMode } from './setDataLoadingModeSettingsItem';
export const multiDataDetailsBlockSettings = new SchemaSettings({
name: 'blockSettings:multiDataDetails',
@ -26,6 +27,7 @@ export const multiDataDetailsBlockSettings = new SchemaSettings({
const field = useField();
const { service } = useDetailsBlockContext();
const { dn } = useDesignable();
const dataLoadingMode = useDataLoadingMode();
return {
collectionName: name,
defaultFilter: fieldSchema?.['x-decorator-props']?.params?.filter || {},
@ -36,7 +38,11 @@ export const multiDataDetailsBlockSettings = new SchemaSettings({
params.filter = filter;
field.decoratorProps.params = params;
fieldSchema['x-decorator-props']['params'] = params;
service.run({ ...service.params?.[0], filter });
if (dataLoadingMode === 'auto') {
service.run({ ...service.params?.[0], filter });
}
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
@ -164,6 +170,7 @@ export const multiDataDetailsBlockSettings = new SchemaSettings({
};
},
},
setDataLoadingModeSettingsItem,
{
name: 'template',
Component: SchemaSettingsTemplate,

View File

@ -0,0 +1,71 @@
import { ISchema, useField, useFieldSchema } from '@formily/react';
import _ from 'lodash';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useDesignable } from '../../../../schema-component';
import { SchemaSettingsModalItem, useCollectionState } from '../../../../schema-settings';
import { useCollection_deprecated } from '../../../../collection-manager/hooks/useCollection_deprecated';
import { useDataBlockProps, useDataBlockRequest } from '../../../../data-source';
export const setDataLoadingModeSettingsItem = {
name: 'setDataLoadingMode',
Component: SetDataLoadingMode,
};
export function useDataLoadingMode() {
const { dataLoadingMode } = useDataBlockProps() || {};
return dataLoadingMode || 'auto';
}
export function SetDataLoadingMode() {
const { dn } = useDesignable();
const { t } = useTranslation();
const field = useField();
const fieldSchema = useFieldSchema();
const { name } = useCollection_deprecated();
const { getEnableFieldTree, getOnLoadData } = useCollectionState(name);
const request = useDataBlockRequest();
return (
<SchemaSettingsModalItem
title={t('Set data loading mode')}
scope={{ getEnableFieldTree, name, getOnLoadData }}
schema={
{
type: 'object',
title: t('Data loading mode'),
properties: {
dataLoadingMode: {
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
default: fieldSchema['x-decorator-props']?.dataLoadingMode || 'auto',
enum: [
{ value: 'auto', label: t('Automatically load data') },
{ value: 'manual', label: t('Load data after filtering') },
],
},
},
} as ISchema
}
onSubmit={({ dataLoadingMode }) => {
_.set(fieldSchema, 'x-decorator-props.dataLoadingMode', dataLoadingMode);
field.decoratorProps.dataLoadingMode = dataLoadingMode;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-decorator-props': {
...fieldSchema['x-decorator-props'],
},
},
});
dn.refresh();
if (dataLoadingMode === 'auto') {
request.run();
} else {
request.mutate(undefined);
}
}}
/>
);
}

View File

@ -1,12 +1,16 @@
import { useCollection_deprecated } from '../../../..';
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { useCollection_deprecated } from '../../../../collection-manager/hooks/useCollection_deprecated';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
const useVisibleCollection = () => {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
};
// 表单的操作配置
export const readPrettyFormActionInitializers = new SchemaInitializer({
/**
* @deprecated
*
*/
export const readPrettyFormActionInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'ReadPrettyFormActionInitializers',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
@ -84,3 +88,85 @@ export const readPrettyFormActionInitializers = new SchemaInitializer({
},
],
});
export const readPrettyFormActionInitializers = new CompatibleSchemaInitializer(
{
name: 'details:configureActions',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
style: {
marginLeft: 8,
},
items: [
{
type: 'itemGroup',
name: 'enableActions',
title: '{{t("Enable actions")}}',
children: [
{
title: '{{t("Edit")}}',
name: 'edit',
Component: 'UpdateActionInitializer',
schema: {
'x-component': 'Action',
'x-decorator': 'ACLActionProvider',
'x-component-props': {
type: 'primary',
},
},
useVisible: useVisibleCollection,
},
{
title: '{{t("Delete")}}',
name: 'delete',
Component: 'DestroyActionInitializer',
schema: {
'x-component': 'Action',
'x-decorator': 'ACLActionProvider',
},
useVisible: useVisibleCollection,
},
],
},
{
name: 'divider',
type: 'divider',
},
{
type: 'subMenu',
name: 'customize',
title: '{{t("Customize")}}',
children: [
{
name: 'popup',
title: '{{t("Popup")}}',
Component: 'PopupActionInitializer',
useComponentProps() {
return {
'x-component': 'Action',
};
},
},
{
name: 'updateRecord',
title: '{{t("Update record")}}',
Component: 'UpdateRecordActionInitializer',
useComponentProps() {
return {
'x-component': 'Action',
};
},
visible: useVisibleCollection,
},
{
name: 'customRequest',
title: '{{t("Custom request")}}',
Component: 'CustomRequestInitializer',
useVisible: useVisibleCollection,
},
],
},
],
},
readPrettyFormActionInitializers_deprecated,
);

View File

@ -1,7 +1,6 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { SchemaInitializerChildren } from '../../../../application';
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
import { useCompile } from '../../../../schema-component';
import {
gridRowColWrap,
@ -9,6 +8,7 @@ import {
useFormItemInitializerFields,
useInheritsFormItemInitializerFields,
} from '../../../../schema-initializer/utils';
import { SchemaInitializerChildren } from '../../../../application/schema-initializer/components/SchemaInitializerChildren';
const ParentCollectionFields = () => {
const inheritFields = useInheritsFormItemInitializerFields();
@ -45,7 +45,10 @@ const AssociatedFields = () => {
return <SchemaInitializerChildren>{schema}</SchemaInitializerChildren>;
};
export const readPrettyFormItemInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const readPrettyFormItemInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'ReadPrettyFormItemInitializers',
wrap: gridRowColWrap,
icon: 'SettingOutlined',
@ -88,3 +91,50 @@ export const readPrettyFormItemInitializers = new SchemaInitializer({
},
],
});
export const readPrettyFormItemInitializers = new CompatibleSchemaInitializer(
{
name: 'details:configureFields',
wrap: gridRowColWrap,
icon: 'SettingOutlined',
title: '{{t("Configure fields")}}',
items: [
{
type: 'itemGroup',
name: 'displayFields',
title: '{{t("Display fields")}}',
useChildren: useFormItemInitializerFields,
},
{
name: 'parentCollectionFields',
Component: ParentCollectionFields,
},
{
name: 'associationFields',
Component: AssociatedFields,
},
{
name: 'divider',
type: 'divider',
},
{
name: 'addText',
title: '{{t("Add text")}}',
Component: 'BlockItemInitializer',
schema: {
type: 'void',
'x-editable': false,
'x-decorator': 'FormItem',
// 'x-designer': 'Markdown.Void.Designer',
'x-toolbar': 'BlockSchemaToolbar',
'x-settings': 'blockSettings:markdown',
'x-component': 'Markdown.Void',
'x-component-props': {
content: '{{t("This is a demo text, **supports Markdown syntax**.")}}',
},
},
},
],
},
readPrettyFormItemInitializers_deprecated,
);

View File

@ -1,75 +1,85 @@
import { FormOutlined } from '@ant-design/icons';
import React from 'react';
import React, { useCallback } from 'react';
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
import { useBlockAssociationContext, useBlockRequestContext } from '../../../../block-provider';
import { useCollection_deprecated } from '../../../../collection-manager';
import { useSchemaTemplateManager } from '../../../../schema-templates';
import {
createReadPrettyFormBlockSchema,
useRecordCollectionDataSourceItems,
} from '../../../../schema-initializer/utils';
import { createDetailsBlockSchema, useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils';
export const RecordReadPrettyFormBlockInitializer = () => {
const itemConfig = useSchemaInitializerItem();
const {
onCreateBlockSchema,
componentType,
createBlockSchema,
icon = true,
targetCollection,
...others
} = itemConfig;
const { insert } = useSchemaInitializer();
const { getTemplateSchemaByMode } = useSchemaTemplateManager();
const { icon = true, targetCollection, ...others } = itemConfig;
const currentCollection = useCollection_deprecated();
const collection = targetCollection || currentCollection;
const association = useBlockAssociationContext();
const { block } = useBlockRequestContext();
const actionInitializers =
block !== 'TableField' ? itemConfig.actionInitializers || 'ReadPrettyFormActionInitializers' : null;
const { createSingleDetailsSchema } = useCreateSingleDetailsSchema();
return (
<SchemaInitializerItem
icon={icon && <FormOutlined />}
{...others}
onClick={async ({ item }) => {
if (item.template) {
const s = await getTemplateSchemaByMode(item);
if (item.template.componentName === 'ReadPrettyFormItem') {
const blockSchema = createReadPrettyFormBlockSchema({
actionInitializers,
association,
collection: collection.name,
dataSource: collection.dataSource,
action: 'get',
useSourceId: '{{ useSourceIdFromParentRecord }}',
useParams: '{{ useParamsFromRecord }}',
template: s,
settings: 'blockSettings:singleDataDetails',
});
if (item.mode === 'reference') {
blockSchema['x-template-key'] = item.template.key;
}
insert(blockSchema);
} else {
insert(s);
}
} else {
insert(
createReadPrettyFormBlockSchema({
actionInitializers,
association,
collection: collection.name,
dataSource: collection.dataSource,
action: 'get',
useSourceId: '{{ useSourceIdFromParentRecord }}',
useParams: '{{ useParamsFromRecord }}',
settings: 'blockSettings:singleDataDetails',
}),
);
}
}}
onClick={(options) => createSingleDetailsSchema(options)}
items={useRecordCollectionDataSourceItems('ReadPrettyFormItem', null, collection?.name)}
/>
);
};
export function useCreateSingleDetailsSchema() {
const itemConfig = useSchemaInitializerItem();
const { insert } = useSchemaInitializer();
const { getTemplateSchemaByMode } = useSchemaTemplateManager();
const association = useBlockAssociationContext();
const { block } = useBlockRequestContext();
const actionInitializers =
block !== 'TableField' ? itemConfig.actionInitializers || 'details:configureActions' : null;
const templateWrap = useCallback(
(templateSchema, options) => {
const { item } = options;
if (item.template.componentName === 'ReadPrettyFormItem') {
const blockSchema = createDetailsBlockSchema({
actionInitializers,
association,
collection: item.collectionName || item.name,
dataSource: item.dataSource,
action: 'get',
useSourceId: '{{ useSourceIdFromParentRecord }}',
useParams: '{{ useParamsFromRecord }}',
template: templateSchema,
settings: 'blockSettings:singleDataDetails',
});
if (item.mode === 'reference') {
blockSchema['x-template-key'] = item.template.key;
}
return blockSchema;
} else {
return templateSchema;
}
},
[actionInitializers, association],
);
const createSingleDetailsSchema = useCallback(
async ({ item }) => {
if (item.template) {
const template = await getTemplateSchemaByMode(item);
insert(templateWrap(template, { item }));
} else {
insert(
createDetailsBlockSchema({
actionInitializers,
association,
collection: item.collectionName || item.name,
dataSource: item.dataSource,
action: 'get',
useSourceId: '{{ useSourceIdFromParentRecord }}',
useParams: '{{ useParamsFromRecord }}',
settings: 'blockSettings:singleDataDetails',
}),
);
}
},
[actionInitializers, association, getTemplateSchemaByMode, insert, templateWrap],
);
return { createSingleDetailsSchema, templateWrap };
}

View File

@ -7,11 +7,12 @@ test.describe('where single data details block can be added', () => {
await nocoPage.goto();
await page.getByLabel('action-Action.Link-View-view-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-RecordBlockInitializers-general').hover();
await page.getByRole('menuitem', { name: 'Details' }).click();
await page.getByLabel('schema-initializer-Grid-popup:common:addBlock-general').hover();
await page.getByRole('menuitem', { name: 'Details' }).hover();
await page.getByRole('menuitem', { name: 'General' }).click();
await page.mouse.move(300, 0);
await expect(page.getByLabel('block-item-CardItem-general-form')).toBeVisible();
await expect(page.getByLabel('block-item-CardItem-general-details')).toBeVisible();
});
});
@ -22,53 +23,54 @@ test.describe('configure actions', () => {
await nocoPage.goto();
await page.getByLabel('action-Action.Link-View-view-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-RecordBlockInitializers-general').hover();
await page.getByRole('menuitem', { name: 'Details' }).click();
await page.getByLabel('schema-initializer-Grid-popup:common:addBlock-general').hover();
await page.getByRole('menuitem', { name: 'Details' }).hover();
await page.getByRole('menuitem', { name: 'General' }).click();
await page.mouse.move(300, 0);
// create edit ------------------------------------------------------------------------------------
await createAction(page, 'Edit');
await expect(page.getByLabel('action-Action-Edit-update-general-form-0')).toBeVisible();
await expect(page.getByLabel('action-Action-Edit-update-')).toBeVisible();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action-Edit-update-general-form-0').hover();
await page.getByLabel('action-Action-Edit-update-').hover();
await page.getByRole('button', { name: 'designer-schema-settings-Action-actionSettings:edit-general' }).hover();
},
supportedOptions: ['Edit button', 'Linkage rules', 'Open mode', 'Popup size', 'Delete'],
});
await deleteAction(page, 'action-Action-Edit-update-general-form-0');
await deleteAction(page, 'action-Action-Edit-update-');
// create delete ------------------------------------------------------------------------------------
await createAction(page, 'Delete');
await expect(page.getByLabel('action-Action-Delete-destroy-general-form-0')).toBeVisible();
await expect(page.getByLabel('action-Action-Delete-destroy-general-details-')).toBeVisible();
// create print
await createAction(page, 'Print');
await expect(page.getByLabel('action-Action-Print-print-general-form-0')).toBeVisible();
await expect(page.getByLabel('action-Action-Print-print-')).toBeVisible();
// create customize actions ----------------------------------------------------------------------------
// Popup
await createCustomAction(page, 'Popup');
await expect(page.getByLabel('action-Action-Popup-customize:popup-general-form-0')).toBeVisible();
await expect(page.getByLabel('action-Action-Popup-customize')).toBeVisible();
// Update record
await createCustomAction(page, 'Update record');
await expect(page.getByLabel('action-Action-Update record-customize:update-general-form-0')).toBeVisible();
await expect(page.getByLabel('action-Action-Update record-')).toBeVisible();
});
});
test.describe('configure fields', () => {});
async function createAction(page: Page, name: string) {
await page.getByLabel('schema-initializer-ActionBar-ReadPrettyFormActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-details:configureActions-general').hover();
await page.getByRole('menuitem', { name: name }).click();
await expect(page.getByRole('menuitem', { name: name }).getByRole('switch')).toBeChecked();
await page.mouse.move(300, 0);
}
async function createCustomAction(page: Page, name: string) {
await page.getByLabel('schema-initializer-ActionBar-ReadPrettyFormActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-details:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Customize' }).hover();
await page.getByRole('menuitem', { name: name }).click();
await page.mouse.move(0, 400);

View File

@ -24,7 +24,7 @@ export const CreateFormBlockInitializer = () => {
const s = await getTemplateSchemaByMode(item);
if (item.template.componentName === 'FormItem') {
const blockSchema = createFormBlockSchema({
actionInitializers: 'CreateFormActionInitializers',
actionInitializers: 'createForm:configureActions',
association,
dataSource: collection.dataSource,
collection: collection.name,
@ -41,7 +41,7 @@ export const CreateFormBlockInitializer = () => {
} else {
insert(
createFormBlockSchema({
actionInitializers: 'CreateFormActionInitializers',
actionInitializers: 'createForm:configureActions',
association,
dataSource: collection.dataSource,
collection: collection.name,

View File

@ -1,19 +1,69 @@
import { FormOutlined } from '@ant-design/icons';
import React from 'react';
import { useSchemaInitializerItem } from '../../../../application';
import React, { useCallback } from 'react';
import { useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
import { createFormBlockSchema } from '../../../../schema-initializer/utils';
import { DataBlockInitializer } from '../../../../schema-initializer/items/DataBlockInitializer';
import { Collection, CollectionFieldOptions } from '../../../../data-source/collection/Collection';
export const FormBlockInitializer = () => {
export const FormBlockInitializer = ({
filterCollections,
onlyCurrentDataSource,
hideSearch,
createBlockSchema,
componentType = 'FormItem',
templateWrap,
showAssociationFields,
}: {
filterCollections: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean;
onlyCurrentDataSource: boolean;
hideSearch?: boolean;
createBlockSchema?: (options: any) => any;
/**
* template
*/
componentType?: 'FormItem';
templateWrap?: (
templateSchema: any,
{
item,
}: {
item: any;
},
) => any;
showAssociationFields?: boolean;
}) => {
const { insert } = useSchemaInitializer();
const itemConfig = useSchemaInitializerItem();
const { isCusomeizeCreate } = itemConfig;
const onCreateFormBlockSchema = useCallback(
({ item }) => {
if (createBlockSchema) {
return createBlockSchema({ item });
}
insert(
createFormBlockSchema({
collection: item.collectionName || item.name,
dataSource: item.dataSource,
isCusomeizeCreate,
settings: 'blockSettings:createForm',
}),
);
},
[createBlockSchema, insert, isCusomeizeCreate],
);
return (
<DataBlockInitializer
{...itemConfig}
icon={<FormOutlined />}
componentType={'FormItem'}
componentType={componentType}
templateWrap={(templateSchema, { item }) => {
const s = createFormBlockSchema({
if (templateWrap) {
return templateWrap(templateSchema, { item });
}
const schema = createFormBlockSchema({
isCusomeizeCreate,
dataSource: item.dataSource,
template: templateSchema,
@ -21,11 +71,15 @@ export const FormBlockInitializer = () => {
settings: 'blockSettings:createForm',
});
if (item.template && item.mode === 'reference') {
s['x-template-key'] = item.template.key;
schema['x-template-key'] = item.template.key;
}
return s;
return schema;
}}
createBlockSchema={createFormBlockSchema}
onCreateBlockSchema={onCreateFormBlockSchema}
filter={filterCollections}
onlyCurrentDataSource={onlyCurrentDataSource}
hideSearch={hideSearch}
showAssociationFields={showAssociationFields}
/>
);
};

View File

@ -1,61 +1,87 @@
import { FormOutlined } from '@ant-design/icons';
import React from 'react';
import React, { useCallback } from 'react';
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
import { useBlockAssociationContext } from '../../../../block-provider';
import { useCollection_deprecated } from '../../../../collection-manager';
import { useSchemaTemplateManager } from '../../../../schema-templates';
import { createFormBlockSchema, useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils';
/**
* @deprecated
*/
export const RecordFormBlockInitializer = () => {
const itemConfig = useSchemaInitializerItem();
const { onCreateBlockSchema, componentType, createBlockSchema, targetCollection, ...others } = itemConfig;
const { targetCollection, ...others } = itemConfig;
const { insert } = useSchemaInitializer();
const { getTemplateSchemaByMode } = useSchemaTemplateManager();
const currentCollection = useCollection_deprecated();
const collection = targetCollection || currentCollection;
const association = useBlockAssociationContext();
const { createEditFormBlock, templateWrap } = useCreateEditFormBlock();
return (
<SchemaInitializerItem
icon={<FormOutlined />}
{...others}
onClick={async ({ item }) => {
if (item.template) {
const s = await getTemplateSchemaByMode(item);
if (item.template.componentName === 'FormItem') {
const blockSchema = createFormBlockSchema({
association,
collection: collection.name,
dataSource: collection.dataSource,
action: 'get',
useSourceId: '{{ useSourceIdFromParentRecord }}',
useParams: '{{ useParamsFromRecord }}',
actionInitializers: 'UpdateFormActionInitializers',
template: s,
settings: 'blockSettings:editForm',
});
if (item.mode === 'reference') {
blockSchema['x-template-key'] = item.template.key;
}
insert(blockSchema);
} else {
insert(s);
}
const template = await getTemplateSchemaByMode(item);
insert(templateWrap(template, { item }));
} else {
insert(
createFormBlockSchema({
association,
collection: collection.name,
dataSource: collection.dataSource,
action: 'get',
useSourceId: '{{ useSourceIdFromParentRecord }}',
useParams: '{{ useParamsFromRecord }}',
actionInitializers: 'UpdateFormActionInitializers',
settings: 'blockSettings:editForm',
}),
);
createEditFormBlock({ item });
}
}}
items={useRecordCollectionDataSourceItems('FormItem', null, collection?.name)}
/>
);
};
export function useCreateEditFormBlock() {
const { insert } = useSchemaInitializer();
const association = useBlockAssociationContext();
const createEditFormBlock = useCallback(
({ item }) => {
insert(
createFormBlockSchema({
association,
collection: item.collectionName || item.name,
dataSource: item.dataSource,
action: 'get',
useSourceId: '{{ useSourceIdFromParentRecord }}',
useParams: '{{ useParamsFromRecord }}',
actionInitializers: 'editForm:configureActions',
settings: 'blockSettings:editForm',
}),
);
},
[association, insert],
);
const templateWrap = useCallback(
(templateSchema, { item }) => {
if (item.template.componentName === 'FormItem') {
const blockSchema = createFormBlockSchema({
association,
collection: item.collectionName || item.name,
dataSource: item.dataSource,
action: 'get',
useSourceId: '{{ useSourceIdFromParentRecord }}',
useParams: '{{ useParamsFromRecord }}',
actionInitializers: 'editForm:configureActions',
template: templateSchema,
settings: 'blockSettings:editForm',
});
if (item.mode === 'reference') {
blockSchema['x-template-key'] = item.template.key;
}
return blockSchema;
} else {
return templateSchema;
}
},
[association],
);
return { createEditFormBlock, templateWrap };
}

View File

@ -2,7 +2,7 @@ import { expect, oneFormBlockBasedOnUsers, test } from '@nocobase/test/e2e';
test('fields', async ({ page, mockPage }) => {
await mockPage(oneFormBlockBasedOnUsers).goto();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-users').hover();
await page.getByLabel('schema-initializer-Grid-form:configureFields-users').hover();
await page.getByRole('menuitem', { name: 'Nickname' }).click();
await page.getByRole('menuitem', { name: 'Username' }).click();
await page.getByRole('menuitem', { name: 'Email' }).click();

View File

@ -282,7 +282,7 @@ test.describe('association fields', () => {
await expect(page.getByLabel('Member')).toBeHidden();
await expect(page.getByLabel('Root')).toBeVisible();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-users').hover();
await page.getByLabel('schema-initializer-Grid-form:configureFields-users').hover();
await page.getByRole('menuitem', { name: 'Nickname' }).click();
await page.mouse.move(200, 0);

View File

@ -6,7 +6,7 @@ test.describe('where creation form block can be added', () => {
test('page', async ({ page, mockPage }) => {
await mockPage().goto();
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
await createBlockInPage(page, 'Form');
await expect(page.getByLabel('block-item-CardItem-users-form')).toBeVisible();
});
@ -17,7 +17,7 @@ test.describe('configure fields', () => {
await mockPage(oneEmptyForm).goto();
// collection fields
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
await page.getByLabel('schema-initializer-Grid-form:configureFields-general').hover();
await page.getByRole('menuitem', { name: 'ID', exact: true }).click();
await expect(page.getByRole('menuitem', { name: 'ID', exact: true }).getByRole('switch')).toBeChecked();
@ -33,7 +33,7 @@ test.describe('configure fields', () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.manyToOne.nickname')).toBeVisible();
// delete fields
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
await page.getByLabel('schema-initializer-Grid-form:configureFields-general').hover();
await page.getByRole('menuitem', { name: 'ID', exact: true }).click();
await expect(page.getByRole('menuitem', { name: 'ID', exact: true }).getByRole('switch')).not.toBeChecked();
@ -50,7 +50,7 @@ test.describe('configure fields', () => {
).not.toBeVisible();
// add text
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
await page.getByLabel('schema-initializer-Grid-form:configureFields-general').hover();
await page.getByRole('menuitem', { name: 'Text' }).click();
await expect(page.getByLabel('block-item-Markdown.Void-general-form')).toBeVisible();
});
@ -62,7 +62,7 @@ test.describe('configure actions', () => {
test('submit', async ({ page, mockPage }) => {
await mockPage(oneEmptyForm).goto();
await page.getByLabel('schema-initializer-ActionBar-FormActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-general').hover();
// add button
await page.getByRole('menuitem', { name: 'Submit' }).click();
@ -72,7 +72,7 @@ test.describe('configure actions', () => {
await expect(page.getByRole('button', { name: 'Submit' })).toBeVisible();
// delete button
await page.getByLabel('schema-initializer-ActionBar-FormActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Submit' }).click();
await expect(page.getByRole('menuitem', { name: 'Submit' }).getByRole('switch')).not.toBeChecked();
@ -137,7 +137,7 @@ test.describe('configure actions', () => {
test('customize: save record', async ({ page, mockPage }) => {
await mockPage(oneEmptyForm).goto();
await page.getByLabel('schema-initializer-ActionBar-FormActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Customize' }).hover();
await page.getByRole('menuitem', { name: 'Save record' }).click();

View File

@ -350,7 +350,7 @@ test.describe('creation form block schema settings', () => {
await expect(page.getByRole('menuitem', { name: 'Convert reference to duplicate' })).toBeVisible();
// 创建区块的时候,可以选择刚才保存的模板 --------------------------------------------------
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
await page.getByRole('menuitem', { name: 'form Form right' }).first().hover();
await page.getByRole('menuitem', { name: 'General right' }).hover();
@ -359,7 +359,7 @@ test.describe('creation form block schema settings', () => {
await page.getByRole('menuitem', { name: 'new_form_template (Fields only)' }).click();
// Reference template
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
await page.getByRole('menuitem', { name: 'form Form right' }).first().hover();
await page.getByRole('menuitem', { name: 'General right' }).hover();
await page.getByRole('menuitem', { name: 'General right' }).click();
@ -549,7 +549,7 @@ test.describe('creation form block schema settings', () => {
.hover();
await page.mouse.move(100, 0);
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-users').hover();
await page.getByLabel('schema-initializer-Grid-form:configureFields-users').hover();
await page.getByRole('menuitem', { name: 'Nickname' }).click();
await page.getByRole('menuitem', { name: 'Username' }).click();
@ -622,7 +622,7 @@ test.describe('creation form block schema settings', () => {
.hover();
await page.mouse.move(100, 0);
await page.getByLabel('schema-initializer-AssociationField.SubTable-TableColumnInitializers-users').hover();
await page.getByLabel('schema-initializer-AssociationField.SubTable-table:configureColumns-users').hover();
await page.getByRole('menuitem', { name: 'Nickname' }).click();
await page.getByRole('menuitem', { name: 'Username' }).click();
@ -719,7 +719,7 @@ test.describe('creation form block schema settings', () => {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
gdj0ceke8ac: {
_isJSONSchemaObject: true,
@ -764,7 +764,7 @@ test.describe('creation form block schema settings', () => {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
properties: {
gnw25oyqe56: {
_isJSONSchemaObject: true,
@ -810,7 +810,7 @@ test.describe('creation form block schema settings', () => {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'FormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -879,7 +879,7 @@ test.describe('creation form block schema settings', () => {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
ibb0kjq3kyl: {
_isJSONSchemaObject: true,
@ -919,7 +919,7 @@ test.describe('creation form block schema settings', () => {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -980,7 +980,7 @@ test.describe('creation form block schema settings', () => {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'CreateFormBlockInitializers',
'x-initializer': 'popup:addNew:addBlock',
'x-uid': 'w224zhqyair',
'x-async': false,
'x-index': 1,
@ -1014,7 +1014,7 @@ test.describe('creation form block schema settings', () => {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -1033,7 +1033,7 @@ test.describe('creation form block schema settings', () => {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
properties: {
actions: {
_isJSONSchemaObject: true,
@ -1094,7 +1094,7 @@ test.describe('creation form block schema settings', () => {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
'x-uid': 's49vs6v3qs0',
'x-async': false,
'x-index': 1,
@ -1160,7 +1160,7 @@ test.describe('creation form block schema settings', () => {
'x-index': 1,
},
}).goto();
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
//使用复制模板
await page.getByRole('menuitem', { name: 'form Form' }).first().hover();
await page.getByRole('menuitem', { name: 'Users' }).hover();
@ -1171,25 +1171,25 @@ test.describe('creation form block schema settings', () => {
//在新建操作中使用引用模板
await page.getByLabel('action-Action-Add new-create-users-table').click();
await page.getByLabel('schema-initializer-Grid-CreateFormBlockInitializers-users').hover();
await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-users').hover();
await page.getByRole('menuitem', { name: 'form Form' }).first().hover();
await page.getByRole('menuitem', { name: 'Reference template' }).hover();
await page.getByRole('menuitem', { name: 'Users_Form (Fields only)' }).first().click();
await page.mouse.move(300, 0);
await page.getByLabel('schema-initializer-Grid-CreateFormBlockInitializers-users').hover();
await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-users').hover();
await expect(page.locator('.ant-drawer').getByLabel('block-item-CardItem-users-form')).toBeVisible();
await page.locator('.ant-drawer-mask').click();
//在编辑操作中使用引用模板
await page.getByLabel('action-Action.Link-Edit-update-users-table-0').click();
await page.getByLabel('schema-initializer-Grid-RecordBlockInitializers-users').click();
await page.getByRole('menuitem', { name: 'form Form' }).first().hover();
await page.getByLabel('schema-initializer-Grid-popup:common:addBlock-users').click();
await page.getByRole('menuitem', { name: 'form Form (Edit)' }).first().hover();
await page.getByRole('menuitem', { name: 'Reference template' }).hover();
await page.getByRole('menuitem', { name: 'Users_Form (Fields only)' }).first().click();
await page.mouse.move(300, 0);
//修改引用模板
await page.locator('.ant-drawer').getByLabel('schema-initializer-Grid-FormItemInitializers-users').hover();
await page.locator('.ant-drawer').getByLabel('schema-initializer-Grid-form:configureFields-users').hover();
await page.getByRole('menuitem', { name: 'Phone' }).click();
await page.locator('.ant-drawer-mask').click();
//复制模板不同步,引用模板同步

View File

@ -12,7 +12,7 @@ export const T2165 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
psn8ekavlq6: {
_isJSONSchemaObject: true,
@ -58,7 +58,7 @@ export const T2165 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
'x-linkage-rules': [
{
condition: {
@ -235,7 +235,7 @@ export const T2165 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'FormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -291,7 +291,7 @@ export const T2174 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
'x-index': 1,
properties: {
ppgwx2drpng: {
@ -335,7 +335,7 @@ export const T2174 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -350,7 +350,7 @@ export const T2174 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -370,7 +370,7 @@ export const T2174 = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
'x-index': 1,
properties: {
actions: {
@ -438,7 +438,7 @@ export const T2174 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
'x-index': 1,
properties: {
g8w7wq09bgo: {
@ -492,7 +492,7 @@ export const T2174 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
'x-index': 1,
properties: {
s3hhb0ohnv1: {
@ -543,7 +543,7 @@ export const T2174 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'CreateFormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -722,7 +722,7 @@ export const T2174 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
'x-index': 1,
'x-uid': 'roog7uz0d2o',
'x-async': false,
@ -888,7 +888,7 @@ export const T2614: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
vv0l8wohslb: {
_isJSONSchemaObject: true,
@ -928,7 +928,7 @@ export const T2614: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -943,7 +943,7 @@ export const T2614: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -962,7 +962,7 @@ export const T2614: PageConfig = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
properties: {
actions: {
_isJSONSchemaObject: true,
@ -1024,7 +1024,7 @@ export const T2614: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {
qbl84fadyr0: {
_isJSONSchemaObject: true,
@ -1069,8 +1069,7 @@ export const T2614: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer':
'ReadPrettyFormActionInitializers',
'x-initializer': 'details:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -1086,8 +1085,7 @@ export const T2614: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer':
'ReadPrettyFormItemInitializers',
'x-initializer': 'details:configureFields',
properties: {
i39cn9ve66b: {
_isJSONSchemaObject: true,
@ -1128,7 +1126,7 @@ export const T2614: PageConfig = {
type: 'void',
'x-component': 'Grid',
'x-initializer':
'FormItemInitializers',
'form:configureFields',
properties: {
e5kqdzyj562: {
_isJSONSchemaObject:
@ -1355,7 +1353,7 @@ export const T2614: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {
z79dioevb4n: {
_isJSONSchemaObject: true,
@ -1403,7 +1401,7 @@ export const T2614: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
properties: {
j9egu0k0tkq: {
_isJSONSchemaObject: true,
@ -1444,7 +1442,7 @@ export const T2614: PageConfig = {
type: 'void',
'x-component': 'Grid',
'x-initializer':
'FormItemInitializers',
'form:configureFields',
properties: {
esgv9d2n3jl: {
_isJSONSchemaObject:
@ -1581,7 +1579,7 @@ export const T2614: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'UpdateFormActionInitializers',
'x-initializer': 'editForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -1724,7 +1722,7 @@ export const T2993: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
'x-index': 1,
properties: {
vv0l8wohslb: {
@ -1768,7 +1766,7 @@ export const T2993: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -1830,7 +1828,7 @@ export const T2993: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'CreateFormBlockInitializers',
'x-initializer': 'popup:addNew:addBlock',
properties: {
kvyqrrxvggn: {
_isJSONSchemaObject: true,
@ -1875,7 +1873,7 @@ export const T2993: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
properties: {
itg7al9oxaw: {
_isJSONSchemaObject: true,
@ -1917,7 +1915,7 @@ export const T2993: PageConfig = {
type: 'void',
'x-component': 'Grid',
'x-initializer':
'FormItemInitializers',
'form:configureFields',
properties: {
um4p1ariq2x: {
_isJSONSchemaObject: true,
@ -2017,7 +2015,7 @@ export const T2993: PageConfig = {
'x-component':
'Grid',
'x-initializer':
'FormItemInitializers',
'form:configureFields',
properties: {
uscd5l8tu2t:
{
@ -2136,7 +2134,7 @@ export const T2993: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'CreateFormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -2201,7 +2199,7 @@ export const T2993: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -2221,7 +2219,7 @@ export const T2993: PageConfig = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
'x-index': 1,
properties: {
actions: {
@ -2311,7 +2309,7 @@ export const T2615: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
'1valv0kj8vs': {
_isJSONSchemaObject: true,
@ -2351,7 +2349,7 @@ export const T2615: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -2412,7 +2410,7 @@ export const T2615: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'CreateFormBlockInitializers',
'x-initializer': 'popup:addNew:addBlock',
properties: {
'8ei3tsaojf6': {
_isJSONSchemaObject: true,
@ -2457,7 +2455,7 @@ export const T2615: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
properties: {
i7cb2o172ey: {
_isJSONSchemaObject: true,
@ -2546,7 +2544,7 @@ export const T2615: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'CreateFormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -2612,7 +2610,7 @@ export const T2615: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -2631,7 +2629,7 @@ export const T2615: PageConfig = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
properties: {
actions: {
_isJSONSchemaObject: true,
@ -2693,7 +2691,7 @@ export const T2615: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {
l79xm6sfjst: {
_isJSONSchemaObject: true,
@ -2741,7 +2739,7 @@ export const T2615: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
properties: {
'7eayo28dgzo': {
_isJSONSchemaObject: true,
@ -2830,7 +2828,7 @@ export const T2615: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'UpdateFormActionInitializers',
'x-initializer': 'editForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -2936,7 +2934,7 @@ export const T2615: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {
nlnfd9hnl53: {
_isJSONSchemaObject: true,
@ -2981,8 +2979,7 @@ export const T2615: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer':
'ReadPrettyFormActionInitializers',
'x-initializer': 'details:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -2998,8 +2995,7 @@ export const T2615: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer':
'ReadPrettyFormItemInitializers',
'x-initializer': 'details:configureFields',
properties: {
j9mxulol74m: {
_isJSONSchemaObject: true,
@ -3215,7 +3211,7 @@ export const T2845: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
'x-index': 1,
properties: {
'1valv0kj8vs': {
@ -3259,7 +3255,7 @@ export const T2845: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -3325,7 +3321,7 @@ export const T2845: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'CreateFormBlockInitializers',
'x-initializer': 'popup:addNew:addBlock',
'x-index': 1,
properties: {
'8ei3tsaojf6': {
@ -3375,7 +3371,7 @@ export const T2845: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
'x-index': 1,
properties: {
i7cb2o172ey: {
@ -3463,7 +3459,7 @@ export const T2845: PageConfig = {
type: 'void',
'x-component': 'Grid',
'x-initializer':
'FormItemInitializers',
'form:configureFields',
properties: {
'3wg2gga1tgx': {
_isJSONSchemaObject: true,
@ -3564,7 +3560,7 @@ export const T2845: PageConfig = {
'x-component':
'Grid',
'x-initializer':
'RecordBlockInitializers',
'popup:common:addBlock',
'x-uid':
'fen65isdi05',
'x-async':
@ -3650,7 +3646,7 @@ export const T2845: PageConfig = {
type: 'void',
'x-component': 'Grid',
'x-initializer':
'RecordBlockInitializers',
'popup:common:addBlock',
properties: {
dksoesw9cnq: {
_isJSONSchemaObject:
@ -3728,7 +3724,7 @@ export const T2845: PageConfig = {
'x-component':
'Grid',
'x-initializer':
'FormItemInitializers',
'form:configureFields',
'x-uid':
'slesgjv4uxx',
'x-async':
@ -3743,7 +3739,7 @@ export const T2845: PageConfig = {
'2.0',
type: 'void',
'x-initializer':
'UpdateFormActionInitializers',
'editForm:configureActions',
'x-component':
'ActionBar',
'x-component-props':
@ -3824,7 +3820,7 @@ export const T2845: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'CreateFormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -3880,7 +3876,7 @@ export const T2845: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -3900,7 +3896,7 @@ export const T2845: PageConfig = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
'x-index': 1,
properties: {
actions: {
@ -3967,7 +3963,7 @@ export const T2845: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
'x-index': 1,
properties: {
l79xm6sfjst: {
@ -4020,7 +4016,7 @@ export const T2845: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
'x-index': 1,
properties: {
'7eayo28dgzo': {
@ -4107,7 +4103,7 @@ export const T2845: PageConfig = {
type: 'void',
'x-component': 'Grid',
'x-initializer':
'FormItemInitializers',
'form:configureFields',
properties: {
ddo3fvkz6hw: {
_isJSONSchemaObject:
@ -4235,7 +4231,7 @@ export const T2845: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'UpdateFormActionInitializers',
'x-initializer': 'editForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -4336,7 +4332,7 @@ export const T2845: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
'x-index': 1,
properties: {
nlnfd9hnl53: {
@ -4386,8 +4382,7 @@ export const T2845: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer':
'ReadPrettyFormActionInitializers',
'x-initializer': 'details:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -4403,8 +4398,7 @@ export const T2845: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer':
'ReadPrettyFormItemInitializers',
'x-initializer': 'details:configureFields',
'x-index': 2,
properties: {
j9mxulol74m: {
@ -4491,7 +4485,7 @@ export const T2845: PageConfig = {
type: 'void',
'x-component': 'Grid',
'x-initializer':
'FormItemInitializers',
'form:configureFields',
properties: {
c5mcb8foh05: {
_isJSONSchemaObject:
@ -4697,7 +4691,7 @@ export const T2200 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
ai6ojrzwkiv: {
_isJSONSchemaObject: true,
@ -4737,7 +4731,7 @@ export const T2200 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -4752,7 +4746,7 @@ export const T2200 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -4771,7 +4765,7 @@ export const T2200 = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
properties: {
actions: {
_isJSONSchemaObject: true,
@ -4832,7 +4826,7 @@ export const T2200 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {
dv88ljcl0qw: {
_isJSONSchemaObject: true,
@ -4880,7 +4874,7 @@ export const T2200 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
properties: {
'3i87cpmv87x': {
_isJSONSchemaObject: true,
@ -4926,7 +4920,7 @@ export const T2200 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'UpdateFormActionInitializers',
'x-initializer': 'editForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -5039,7 +5033,7 @@ export const T3106: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
'x-index': 1,
properties: {
cxk2aa058lc: {
@ -5089,7 +5083,7 @@ export const T3106: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
'x-index': 1,
properties: {
wbvuzjzl83g: {
@ -5123,7 +5117,7 @@ export const T3106: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'AssociationField.SubTable',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-initializer-props': {
action: false,
},
@ -5187,7 +5181,7 @@ export const T3106: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'FormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -5259,7 +5253,7 @@ export const T3251: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
xovhjqo0uig: {
_isJSONSchemaObject: true,
@ -5305,7 +5299,7 @@ export const T3251: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
'x-linkage-rules': [
{
condition: {
@ -5448,7 +5442,7 @@ export const T3251: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'FormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
@ -5505,7 +5499,7 @@ export const T3469: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
'x-index': 1,
properties: {
isaxpp1w32b: {
@ -5557,7 +5551,7 @@ export const T3469: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
'x-index': 1,
properties: {
e4ke3wqxm2o: {
@ -5716,7 +5710,7 @@ export const T3529: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
l62athlwjbe: {
_isJSONSchemaObject: true,
@ -5758,7 +5752,7 @@ export const T3529: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -5773,7 +5767,7 @@ export const T3529: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -5792,7 +5786,7 @@ export const T3529: PageConfig = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
properties: {
'7glkmum3znh': {
_isJSONSchemaObject: true,
@ -5853,7 +5847,7 @@ export const T3529: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'RecordBlockInitializers',
'x-initializer': 'popup:common:addBlock',
properties: {
'5ubuvb82lbu': {
_isJSONSchemaObject: true,
@ -5904,7 +5898,7 @@ export const T3529: PageConfig = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
'x-uid': 'aigmsbzdyeb',
'x-async': false,
'x-index': 1,
@ -5913,7 +5907,7 @@ export const T3529: PageConfig = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'CreateFormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',

View File

@ -7,7 +7,7 @@ test.describe('where edit form block can be added', () => {
await nocoPage.goto();
await page.getByLabel('action-Action.Link-Edit-update-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-RecordBlockInitializers-general').hover();
await page.getByLabel('schema-initializer-Grid-popup:common:addBlock-general').hover();
await page.getByText('Form').first().click();
await page.mouse.move(300, 0);

View File

@ -1,6 +1,9 @@
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
export const createFormActionInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const createFormActionInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'CreateFormActionInitializers',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
@ -46,3 +49,50 @@ export const createFormActionInitializers = new SchemaInitializer({
},
],
});
export const createFormActionInitializers = new CompatibleSchemaInitializer(
{
name: 'createForm:configureActions',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
items: [
{
type: 'itemGroup',
title: '{{t("Enable actions")}}',
name: 'enableActions',
children: [
{
name: 'submit',
title: '{{t("Submit")}}',
Component: 'CreateSubmitActionInitializer',
schema: {
'x-action-settings': {},
},
},
],
},
{
name: 'divider',
type: 'divider',
},
{
type: 'subMenu',
title: '{{t("Customize")}}',
name: 'customize',
children: [
{
name: 'saveRecord',
title: '{{t("Save record")}}',
Component: 'SaveRecordActionInitializer',
},
{
name: 'customRequest',
title: '{{t("Custom request")}}',
Component: 'CustomRequestInitializer',
},
],
},
],
},
createFormActionInitializers_deprecated,
);

View File

@ -1,7 +1,9 @@
import { SchemaInitializerItemType } from '../../../../application';
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
// 表单的操作配置
/**
* @deprecated
*
*/
export const formActionInitializers = new SchemaInitializer({
name: 'FormActionInitializers',
title: '{{t("Configure actions")}}',
@ -27,7 +29,7 @@ export const formActionInitializers = new SchemaInitializer({
type: 'divider',
},
{
name: 'custom',
name: 'customize',
type: 'subMenu',
title: '{{t("Customize")}}',
children: [

View File

@ -1,10 +1,12 @@
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { gridRowColWrap, useFormItemInitializerFields } from '../../../../schema-initializer/utils';
import { ParentCollectionFields, AssociatedFields } from '../../../../schema-initializer/buttons/FormItemInitializers';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
// 表单里配置字段
export const formItemInitializers = new SchemaInitializer({
/**
* @deprecated
*
*/
export const formItemInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'FormItemInitializers',
wrap: gridRowColWrap,
icon: 'SettingOutlined',
@ -35,3 +37,38 @@ export const formItemInitializers = new SchemaInitializer({
},
],
});
export const formItemInitializers = new CompatibleSchemaInitializer(
{
name: 'form:configureFields',
wrap: gridRowColWrap,
icon: 'SettingOutlined',
title: '{{t("Configure fields")}}',
items: [
{
type: 'itemGroup',
name: 'displayFields',
title: '{{t("Display fields")}}',
useChildren: useFormItemInitializerFields,
},
{
name: 'parentCollectionFields',
Component: ParentCollectionFields,
},
{
name: 'associationFields',
Component: AssociatedFields,
},
{
name: 'divider',
type: 'divider',
},
{
name: 'addText',
title: '{{t("Add text")}}',
Component: 'MarkdownFormItemInitializer',
},
],
},
formItemInitializers_deprecated,
);

View File

@ -1,6 +1,9 @@
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
export const updateFormActionInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const updateFormActionInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'UpdateFormActionInitializers',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
@ -57,3 +60,61 @@ export const updateFormActionInitializers = new SchemaInitializer({
},
],
});
export const updateFormActionInitializers = new CompatibleSchemaInitializer(
{
name: 'editForm:configureActions',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
items: [
{
type: 'itemGroup',
title: '{{t("Enable actions")}}',
name: 'enableActions',
children: [
{
name: 'submit',
title: '{{t("Submit")}}',
Component: 'UpdateSubmitActionInitializer',
schema: {
'x-action-settings': {},
},
},
],
},
{
name: 'divider',
type: 'divider',
},
{
type: 'subMenu',
title: '{{t("Customize")}}',
name: 'customize',
children: [
{
name: 'popup',
title: '{{t("Popup")}}',
Component: 'PopupActionInitializer',
useComponentProps() {
return {
'x-component': 'Action',
};
},
},
{
name: 'saveRecord',
title: '{{t("Save record")}}',
Component: 'SaveRecordActionInitializer',
},
{
type: 'item',
name: 'customRequest',
title: '{{t("Custom request")}}',
Component: 'CustomRequestInitializer',
},
],
},
],
},
updateFormActionInitializers_deprecated,
);

View File

@ -1,8 +1,10 @@
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
import { useCollection_deprecated } from '../../../../collection-manager';
// 表单的操作配置
export const gridCardActionInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const gridCardActionInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'GridCardActionInitializers',
title: "{{t('Configure actions')}}",
icon: 'SettingOutlined',
@ -80,3 +82,85 @@ export const gridCardActionInitializers = new SchemaInitializer({
},
],
});
export const gridCardActionInitializers = new CompatibleSchemaInitializer(
{
name: 'gridCard:configureActions',
title: "{{t('Configure actions')}}",
icon: 'SettingOutlined',
style: {
marginLeft: 8,
},
items: [
{
type: 'itemGroup',
title: "{{t('Enable actions')}}",
name: 'enableActions',
children: [
{
name: 'filter',
title: "{{t('Filter')}}",
Component: 'FilterActionInitializer',
schema: {
'x-align': 'left',
},
},
{
name: 'addNew',
title: "{{t('Add new')}}",
Component: 'CreateActionInitializer',
schema: {
'x-align': 'right',
'x-decorator': 'ACLActionProvider',
'x-acl-action-props': {
skipScopeCheck: true,
},
},
useVisible() {
const collection = useCollection_deprecated();
return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView;
},
},
{
name: 'refresh',
title: "{{t('Refresh')}}",
Component: 'RefreshActionInitializer',
schema: {
'x-align': 'right',
},
},
{
name: 'import',
title: "{{t('Import')}}",
Component: 'ImportActionInitializer',
schema: {
'x-align': 'right',
'x-acl-action': 'importXlsx',
'x-decorator': 'ACLActionProvider',
'x-acl-action-props': {
skipScopeCheck: true,
},
},
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
{
name: 'export',
title: "{{t('Export')}}",
Component: 'ExportActionInitializer',
schema: {
'x-align': 'right',
'x-decorator': 'ACLActionProvider',
'x-acl-action-props': {
skipScopeCheck: true,
},
},
},
],
},
],
},
gridCardActionInitializers_deprecated,
);

View File

@ -4,8 +4,35 @@ import { useSchemaInitializer, useSchemaInitializerItem } from '../../../../appl
import { useCollectionManager_deprecated } from '../../../../collection-manager';
import { createGridCardBlockSchema } from '../../../../schema-initializer/utils';
import { DataBlockInitializer } from '../../../../schema-initializer/items/DataBlockInitializer';
import { Collection, CollectionFieldOptions } from '../../../../data-source/collection/Collection';
export const GridCardBlockInitializer = () => {
export const GridCardBlockInitializer = ({
filterCollections,
onlyCurrentDataSource,
hideSearch,
createBlockSchema,
componentType = 'FormItem',
templateWrap,
showAssociationFields,
}: {
filterCollections: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean;
onlyCurrentDataSource: boolean;
hideSearch?: boolean;
createBlockSchema?: (options: any) => any;
/**
* template
*/
componentType?: 'FormItem';
templateWrap?: (
templateSchema: any,
{
item,
}: {
item: any;
},
) => any;
showAssociationFields?: boolean;
}) => {
const { insert } = useSchemaInitializer();
const { getCollection } = useCollectionManager_deprecated();
const itemConfig = useSchemaInitializerItem();
@ -15,6 +42,10 @@ export const GridCardBlockInitializer = () => {
icon={<OrderedListOutlined />}
componentType={'GridCard'}
onCreateBlockSchema={async ({ item }) => {
if (createBlockSchema) {
return createBlockSchema({ item });
}
const collection = getCollection(item.name, item.dataSource);
const schema = createGridCardBlockSchema({
collection: item.name,
@ -24,6 +55,10 @@ export const GridCardBlockInitializer = () => {
});
insert(schema);
}}
onlyCurrentDataSource={onlyCurrentDataSource}
hideSearch={hideSearch}
filter={filterCollections}
showAssociationFields={showAssociationFields}
/>
);
};

View File

@ -4,7 +4,7 @@ test.describe('where grid card block can be added', () => {
test('page', async ({ page, mockPage }) => {
await mockPage().goto();
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
await createBlockInPage(page, 'Grid Card');
await expect(page.getByLabel('block-item-BlockItem-users-grid-card')).toBeVisible();
});
@ -16,7 +16,7 @@ test.describe('configure global actions', () => {
test('filter & add new & refresh', async ({ page, mockPage }) => {
await mockPage(oneEmptyGridCardBlock).goto();
await page.getByLabel('schema-initializer-ActionBar-GridCardActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-gridCard:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Filter' }).click();
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('menuitem', { name: 'Refresh' }).click();
@ -31,7 +31,7 @@ test.describe('configure global actions', () => {
await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible();
// delete buttons
await page.getByLabel('schema-initializer-ActionBar-GridCardActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-gridCard:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Filter' }).click();
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('menuitem', { name: 'Refresh' }).click();
@ -53,7 +53,7 @@ test.describe('configure item actions', () => {
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('schema-initializer-ActionBar-GridCardItemActionInitializers-general').first().hover();
await page.getByLabel('schema-initializer-ActionBar-gridCard:configureItemActions-general').first().hover();
await page.getByRole('menuitem', { name: 'View' }).click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
@ -68,7 +68,7 @@ test.describe('configure item actions', () => {
await expect(page.getByLabel('action-Action.Link-Delete-destroy-general-grid-card').first()).toBeVisible();
// delete buttons
await page.getByLabel('schema-initializer-ActionBar-GridCardItemActionInitializers-general').first().hover();
await page.getByLabel('schema-initializer-ActionBar-gridCard:configureItemActions-general').first().hover();
await page.getByRole('menuitem', { name: 'View' }).click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
@ -88,7 +88,7 @@ test.describe('configure item actions', () => {
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('schema-initializer-ActionBar-GridCardItemActionInitializers-general').first().hover();
await page.getByLabel('schema-initializer-ActionBar-gridCard:configureItemActions-general').first().hover();
await page.getByRole('menuitem', { name: 'Customize' }).hover();
await page.getByRole('menuitem', { name: 'Popup' }).click();
await page.getByRole('menuitem', { name: 'Update record' }).click();
@ -107,9 +107,7 @@ test.describe('configure fields', () => {
await mockRecord('general');
await nocoPage.goto();
const formItemInitializer = page
.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general')
.first();
const formItemInitializer = page.getByLabel('schema-initializer-Grid-details:configureFields-general').first();
await formItemInitializer.hover();
await page.getByRole('menuitem', { name: 'ID', exact: true }).click();

View File

@ -18,6 +18,7 @@ import {
import { SchemaSettingsTemplate } from '../../../../schema-settings';
import { columnCountMarks } from './utils';
import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope';
import { setDataLoadingModeSettingsItem } from '../details-multi/setDataLoadingModeSettingsItem';
export const gridCardBlockSettings = new SchemaSettings({
name: 'blockSettings:gridCard',
@ -90,7 +91,6 @@ export const gridCardBlockSettings = new SchemaSettings({
const { form } = useFormBlockContext();
const field = useField();
const { dn } = useDesignable();
const defaultSort = fieldSchema?.['x-decorator-props']?.params?.sort || [];
return {
collectionName: name,
@ -224,6 +224,7 @@ export const gridCardBlockSettings = new SchemaSettings({
};
},
},
setDataLoadingModeSettingsItem,
{
name: 'RecordsPerPage',
type: 'select',

View File

@ -1,7 +1,10 @@
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
import { useCollection_deprecated } from '../../../../collection-manager';
export const gridCardItemActionInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const gridCardItemActionInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'GridCardItemActionInitializers',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
@ -98,3 +101,104 @@ export const gridCardItemActionInitializers = new SchemaInitializer({
},
],
});
export const gridCardItemActionInitializers = new CompatibleSchemaInitializer(
{
name: 'gridCard:configureItemActions',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
items: [
{
type: 'itemGroup',
title: '{{t("Enable actions")}}',
name: 'enable-actions',
children: [
{
name: 'view',
title: '{{t("View")}}',
Component: 'ViewActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'view',
'x-decorator': 'ACLActionProvider',
'x-align': 'left',
},
},
{
name: 'edit',
title: '{{t("Edit")}}',
Component: 'UpdateActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'update',
'x-decorator': 'ACLActionProvider',
'x-align': 'left',
},
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
{
name: 'delete',
title: '{{t("Delete")}}',
Component: 'DestroyActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'destroy',
'x-decorator': 'ACLActionProvider',
'x-align': 'left',
},
useVisible() {
const collection = useCollection_deprecated();
return collection.template !== 'sql';
},
},
],
},
{
name: 'divider',
type: 'divider',
},
{
type: 'subMenu',
title: '{{t("Customize")}}',
name: 'customize',
children: [
{
name: 'popup',
title: '{{t("Popup")}}',
Component: 'PopupActionInitializer',
useComponentProps() {
return {
'x-component': 'Action.Link',
};
},
},
{
name: 'update-record',
title: '{{t("Update record")}}',
Component: 'UpdateRecordActionInitializer',
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
{
name: 'customRequest',
title: '{{t("Custom request")}}',
Component: 'CustomRequestInitializer',
schema: {
'x-action': 'customize:table:request',
},
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
],
},
],
},
gridCardItemActionInitializers_deprecated,
);

View File

@ -1,8 +1,11 @@
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
import { useCollection_deprecated } from '../../../../collection-manager';
// 表单的操作配置
export const listActionInitializers = new SchemaInitializer({
/**
* @deprecated
*
*/
export const listActionInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'ListActionInitializers',
title: "{{t('Configure actions')}}",
icon: 'SettingOutlined',
@ -84,3 +87,89 @@ export const listActionInitializers = new SchemaInitializer({
},
],
});
export const listActionInitializers = new CompatibleSchemaInitializer(
{
name: 'list:configureActions',
title: "{{t('Configure actions')}}",
icon: 'SettingOutlined',
style: {
marginLeft: 8,
},
items: [
{
type: 'itemGroup',
name: 'enableActions',
title: "{{t('Enable actions')}}",
children: [
{
name: 'filter',
title: "{{t('Filter')}}",
Component: 'FilterActionInitializer',
schema: {
'x-align': 'left',
},
},
{
name: 'addNew',
title: "{{t('Add new')}}",
Component: 'CreateActionInitializer',
schema: {
'x-align': 'right',
'x-decorator': 'ACLActionProvider',
'x-acl-action-props': {
skipScopeCheck: true,
},
},
useVisible() {
const collection = useCollection_deprecated();
return (
(collection.template !== 'view' || collection?.writableView) &&
collection.template !== 'file' &&
collection.template !== 'sql'
);
},
},
{
name: 'refresh',
title: "{{t('Refresh')}}",
Component: 'RefreshActionInitializer',
schema: {
'x-align': 'right',
},
},
{
name: 'import',
title: "{{t('Import')}}",
Component: 'ImportActionInitializer',
schema: {
'x-align': 'right',
'x-acl-action': 'importXlsx',
'x-decorator': 'ACLActionProvider',
'x-acl-action-props': {
skipScopeCheck: true,
},
},
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
{
name: 'export',
title: "{{t('Export')}}",
Component: 'ExportActionInitializer',
schema: {
'x-align': 'right',
'x-decorator': 'ACLActionProvider',
'x-acl-action-props': {
skipScopeCheck: true,
},
},
},
],
},
],
},
listActionInitializers_deprecated,
);

View File

@ -4,8 +4,35 @@ import { useSchemaInitializer, useSchemaInitializerItem } from '../../../../appl
import { useCollectionManager_deprecated } from '../../../../collection-manager';
import { createListBlockSchema } from '../../../../schema-initializer/utils';
import { DataBlockInitializer } from '../../../../schema-initializer/items/DataBlockInitializer';
import { Collection, CollectionFieldOptions } from '../../../../data-source/collection/Collection';
export const ListBlockInitializer = () => {
export const ListBlockInitializer = ({
filterCollections,
onlyCurrentDataSource,
hideSearch,
createBlockSchema,
componentType = 'FormItem',
templateWrap,
showAssociationFields,
}: {
filterCollections: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean;
onlyCurrentDataSource: boolean;
hideSearch?: boolean;
createBlockSchema?: (options: any) => any;
/**
* template
*/
componentType?: 'FormItem';
templateWrap?: (
templateSchema: any,
{
item,
}: {
item: any;
},
) => any;
showAssociationFields?: boolean;
}) => {
const { getCollection } = useCollectionManager_deprecated();
const { insert } = useSchemaInitializer();
const itemConfig = useSchemaInitializerItem();
@ -15,6 +42,10 @@ export const ListBlockInitializer = () => {
icon={<OrderedListOutlined />}
componentType={'List'}
onCreateBlockSchema={async ({ item }) => {
if (createBlockSchema) {
return createBlockSchema({ item });
}
const collection = getCollection(item.name, item.dataSource);
const schema = createListBlockSchema({
collection: item.name,
@ -24,6 +55,10 @@ export const ListBlockInitializer = () => {
});
insert(schema);
}}
onlyCurrentDataSource={onlyCurrentDataSource}
hideSearch={hideSearch}
filter={filterCollections}
showAssociationFields={showAssociationFields}
/>
);
};

View File

@ -4,7 +4,7 @@ test.describe('where list block can be added', () => {
test('page', async ({ page, mockPage }) => {
await mockPage().goto();
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
await createBlockInPage(page, 'List');
await expect(page.getByLabel('block-item-CardItem-users-list')).toBeVisible();
});
@ -14,7 +14,7 @@ test.describe('configure global actions', () => {
test('filter & add new & refresh', async ({ page, mockPage }) => {
await mockPage(oneEmptyListBlock).goto();
await page.getByLabel('schema-initializer-ActionBar-ListActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-list:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Filter' }).click();
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('menuitem', { name: 'Refresh' }).click();
@ -29,7 +29,7 @@ test.describe('configure global actions', () => {
await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible();
// delete buttons
await page.getByLabel('schema-initializer-ActionBar-ListActionInitializers-general').hover();
await page.getByLabel('schema-initializer-ActionBar-list:configureActions-general').hover();
await page.getByRole('menuitem', { name: 'Filter' }).click();
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('menuitem', { name: 'Refresh' }).click();
@ -51,7 +51,7 @@ test.describe('configure item actions', () => {
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('schema-initializer-ActionBar-ListItemActionInitializers-general').first().hover();
await page.getByLabel('schema-initializer-ActionBar-list:configureItemActions-general').first().hover();
await page.getByRole('menuitem', { name: 'View' }).click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
@ -66,7 +66,7 @@ test.describe('configure item actions', () => {
await expect(page.getByLabel('action-Action.Link-Delete-destroy-general-list').first()).toBeVisible();
// delete buttons
await page.getByLabel('schema-initializer-ActionBar-ListItemActionInitializers-general').first().hover();
await page.getByLabel('schema-initializer-ActionBar-list:configureItemActions-general').first().hover();
await page.getByRole('menuitem', { name: 'View' }).click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
@ -86,7 +86,7 @@ test.describe('configure item actions', () => {
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('schema-initializer-ActionBar-ListItemActionInitializers-general').first().hover();
await page.getByLabel('schema-initializer-ActionBar-list:configureItemActions-general').first().hover();
await page.getByRole('menuitem', { name: 'Customize' }).hover();
await page.getByRole('menuitem', { name: 'Popup' }).click();
await page.getByRole('menuitem', { name: 'Update record' }).click();
@ -105,9 +105,7 @@ test.describe('configure fields', () => {
await mockRecord('general');
await nocoPage.goto();
const formItemInitializer = page
.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general')
.first();
const formItemInitializer = page.getByLabel('schema-initializer-Grid-details:configureFields-general').first();
// add fields
await formItemInitializer.hover();

View File

@ -8,6 +8,7 @@ import { useCollection_deprecated, useSortFields } from '../../../../collection-
import { removeNullCondition, useDesignable } from '../../../../schema-component';
import { SchemaSettingsBlockTitleItem, SchemaSettingsTemplate } from '../../../../schema-settings';
import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope';
import { setDataLoadingModeSettingsItem } from '../details-multi/setDataLoadingModeSettingsItem';
export const listBlockSettings = new SchemaSettings({
name: 'blockSettings:list',
@ -156,6 +157,7 @@ export const listBlockSettings = new SchemaSettings({
};
},
},
setDataLoadingModeSettingsItem,
{
name: 'RecordsPerPage',
type: 'select',

View File

@ -1,7 +1,10 @@
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
import { useCollection_deprecated } from '../../../../collection-manager';
export const listItemActionInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const listItemActionInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'ListItemActionInitializers',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
@ -98,3 +101,104 @@ export const listItemActionInitializers = new SchemaInitializer({
},
],
});
export const listItemActionInitializers = new CompatibleSchemaInitializer(
{
name: 'list:configureItemActions',
title: '{{t("Configure actions")}}',
icon: 'SettingOutlined',
items: [
{
type: 'itemGroup',
name: 'enableActions',
title: '{{t("Enable actions")}}',
children: [
{
name: 'view',
title: '{{t("View")}}',
Component: 'ViewActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'view',
'x-decorator': 'ACLActionProvider',
'x-align': 'left',
},
},
{
name: 'edit',
title: '{{t("Edit")}}',
Component: 'UpdateActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'update',
'x-decorator': 'ACLActionProvider',
'x-align': 'left',
},
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
{
name: 'delete',
title: '{{t("Delete")}}',
Component: 'DestroyActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'destroy',
'x-decorator': 'ACLActionProvider',
'x-align': 'left',
},
useVisible() {
const collection = useCollection_deprecated();
return collection.template !== 'sql';
},
},
],
},
{
name: 'divider',
type: 'divider',
},
{
type: 'subMenu',
title: '{{t("Customize")}}',
name: 'customize',
children: [
{
name: 'popup',
title: '{{t("Popup")}}',
Component: 'PopupActionInitializer',
useComponentProps() {
return {
'x-component': 'Action.Link',
};
},
},
{
name: 'updateRecord',
title: '{{t("Update record")}}',
Component: 'UpdateRecordActionInitializer',
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
{
name: 'customRequest',
title: '{{t("Custom request")}}',
Component: 'CustomRequestInitializer',
schema: {
'x-action': 'customize:table:request',
},
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
],
},
],
},
listItemActionInitializers_deprecated,
);

View File

@ -20,7 +20,7 @@ test.describe('configure actions', () => {
await createTable({ page, mockPage, fieldName: 'manyToOne' });
// add buttons
await page.getByLabel('schema-initializer-ActionBar-TableActionInitializers-users').hover();
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-users').hover();
await page.getByRole('menuitem', { name: 'Filter' }).click();
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
@ -38,7 +38,7 @@ test.describe('configure actions', () => {
await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible();
// delete buttons
await page.getByLabel('schema-initializer-ActionBar-TableActionInitializers-users').hover();
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-users').hover();
await page.getByRole('menuitem', { name: 'Filter' }).click();
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
@ -59,7 +59,7 @@ test.describe('configure actions', () => {
test('customize: bulk update', async ({ page, mockPage }) => {
await createTable({ page, mockPage, fieldName: 'manyToOne' });
await page.getByLabel('schema-initializer-ActionBar-TableActionInitializers-users').hover();
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-users').hover();
await page.getByRole('menuitem', { name: 'Customize' }).hover();
await page.getByRole('menuitem', { name: 'Bulk update' }).click();
@ -99,6 +99,6 @@ test.describe('configure actions column', () => {
});
async function createActionColumn(page: Page) {
await page.getByLabel('schema-initializer-TableV2.Selector-TableColumnInitializers-users').hover();
await page.getByLabel('schema-initializer-TableV2.Selector-table:configureColumns-users').hover();
await page.getByRole('menuitem', { name: 'Action column' }).click();
}

View File

@ -18,7 +18,7 @@ export async function createTable({
.click();
// create a table block
await page.getByLabel('schema-initializer-Grid-TableSelectorInitializers-users').hover();
await page.getByLabel('schema-initializer-Grid-popup:tableSelector:addBlock-users').hover();
await page.getByRole('menuitem', { name: 'form Table' }).click();
await page.mouse.move(300, 0);
}

View File

@ -12,6 +12,7 @@ import {
} from '../../../../collection-manager';
import { removeNullCondition, useDesignable } from '../../../../schema-component';
import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope';
import { setDataLoadingModeSettingsItem, useDataLoadingMode } from '../details-multi/setDataLoadingModeSettingsItem';
export const tableSelectorBlockSettings = new SchemaSettings({
name: 'blockSettings:tableSelector',
@ -26,6 +27,7 @@ export const tableSelectorBlockSettings = new SchemaSettings({
const { form } = useFormBlockContext();
const { service, extraFilter } = useTableSelectorContext();
const { dn } = useDesignable();
const dataLoadingMode = useDataLoadingMode();
const onDataScopeSubmit = useCallback(
({ filter }) => {
filter = removeNullCondition(filter);
@ -43,7 +45,11 @@ export const tableSelectorBlockSettings = new SchemaSettings({
serviceFilter = extraFilter;
}
}
service.run({ ...service.params?.[0], filter: serviceFilter, page: 1 });
if (dataLoadingMode === 'auto') {
service.run({ ...service.params?.[0], filter: serviceFilter, page: 1 });
}
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
@ -51,7 +57,7 @@ export const tableSelectorBlockSettings = new SchemaSettings({
},
});
},
[dn, field.decoratorProps, fieldSchema, service, extraFilter],
[field.decoratorProps, fieldSchema, extraFilter, dataLoadingMode, dn, service],
);
return {
@ -223,6 +229,7 @@ export const tableSelectorBlockSettings = new SchemaSettings({
return !dragSort;
},
},
setDataLoadingModeSettingsItem,
{
name: 'RecordsPerPage',
type: 'select',

View File

@ -4,11 +4,13 @@ import _ from 'lodash';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useAPIClient } from '../../../../api-client';
import { SchemaInitializerActionModal, SchemaInitializerItem, useSchemaInitializer } from '../../../../application';
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { useCollection_deprecated } from '../../../../collection-manager';
import { createDesignable, useDesignable } from '../../../../schema-component';
import { useGetAriaLabelOfDesigner } from '../../../../schema-settings/hooks/useGetAriaLabelOfDesigner';
import { SchemaInitializerActionModal } from '../../../../application/schema-initializer/components/SchemaInitializerActionModal';
import { useSchemaInitializer } from '../../../../application/schema-initializer/context';
import { SchemaInitializerItem } from '../../../../application/schema-initializer/components/SchemaInitializerItem';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
export const Resizable = () => {
const { t } = useTranslation();
@ -63,7 +65,10 @@ export const Resizable = () => {
);
};
export const tableActionColumnInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const tableActionColumnInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'TableActionColumnInitializers',
insertPosition: 'beforeEnd',
useInsert: function useInsert() {
@ -221,3 +226,165 @@ export const tableActionColumnInitializers = new SchemaInitializer({
},
],
});
export const tableActionColumnInitializers = new CompatibleSchemaInitializer(
{
name: 'table:configureItemActions',
insertPosition: 'beforeEnd',
useInsert: function useInsert() {
const { refresh } = useDesignable();
const fieldSchema = useFieldSchema();
const api = useAPIClient();
const { t } = useTranslation();
return function insert(schema) {
const spaceSchema = fieldSchema.reduceProperties((buf, schema) => {
if (schema['x-component'] === 'Space') {
return schema;
}
return buf;
}, null);
if (!spaceSchema) {
return;
}
_.set(schema, 'x-designer-props.linkageAction', true);
const dn = createDesignable({
t,
api,
refresh,
current: spaceSchema,
});
dn.loadAPIClientEvents();
dn.insertBeforeEnd(schema);
};
},
Component: (props: any) => {
const { getAriaLabel } = useGetAriaLabelOfDesigner();
return (
<MenuOutlined
{...props}
role="button"
aria-label={getAriaLabel('schema-settings')}
style={{ cursor: 'pointer' }}
/>
);
},
items: [
{
type: 'itemGroup',
name: 'actions',
title: '{{t("Enable actions")}}',
children: [
{
type: 'item',
title: '{{t("View")}}',
name: 'view',
Component: 'ViewActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'view',
'x-decorator': 'ACLActionProvider',
},
},
{
type: 'item',
name: 'edit',
title: '{{t("Edit")}}',
Component: 'UpdateActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'update',
'x-decorator': 'ACLActionProvider',
},
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
{
type: 'item',
title: '{{t("Delete")}}',
name: 'delete',
Component: 'DestroyActionInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'destroy',
'x-decorator': 'ACLActionProvider',
},
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
{
type: 'item',
title: '{{t("Add child")}}',
name: 'addChildren',
Component: 'CreateChildInitializer',
schema: {
'x-component': 'Action.Link',
'x-action': 'create',
'x-decorator': 'ACLActionProvider',
},
useVisible() {
const fieldSchema = useFieldSchema();
const collection = useCollection_deprecated();
const { treeTable } = fieldSchema?.parent?.parent['x-decorator-props'] || {};
return collection.tree && treeTable !== false;
},
},
],
},
{
name: 'divider',
type: 'divider',
},
{
type: 'subMenu',
title: '{{t("Customize")}}',
name: 'customize',
children: [
{
type: 'item',
title: '{{t("Popup")}}',
name: 'popup',
Component: 'PopupActionInitializer',
},
{
type: 'item',
title: '{{t("Update record")}}',
name: 'updateRecord',
Component: 'UpdateRecordActionInitializer',
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
{
name: 'customRequest',
title: '{{t("Custom request")}}',
Component: 'CustomRequestInitializer',
schema: {
'x-action': 'customize:table:request',
},
useVisible() {
const collection = useCollection_deprecated();
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
},
},
],
},
{
name: 'divider2',
type: 'divider',
},
{
type: 'item',
name: 'columnWidth',
title: 't("Column width")',
Component: Resizable,
},
],
},
tableActionColumnInitializers_deprecated,
);

View File

@ -1,9 +1,12 @@
import { useFieldSchema } from '@formily/react';
import { useCollection_deprecated } from '../../../..';
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
import { useCollection_deprecated } from '../../../../collection-manager/hooks/useCollection_deprecated';
// 表格操作配置
export const tableActionInitializers = new SchemaInitializer({
/**
* @deprecated
*
*/
export const tableActionInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'TableActionInitializers',
title: "{{t('Configure actions')}}",
icon: 'SettingOutlined',
@ -116,3 +119,120 @@ export const tableActionInitializers = new SchemaInitializer({
},
],
});
export const tableActionInitializers = new CompatibleSchemaInitializer(
{
name: 'table:configureActions',
title: "{{t('Configure actions')}}",
icon: 'SettingOutlined',
style: {
marginLeft: 8,
},
items: [
{
type: 'itemGroup',
name: 'enableActions',
title: "{{t('Enable actions')}}",
children: [
{
type: 'item',
name: 'filter',
title: "{{t('Filter')}}",
Component: 'FilterActionInitializer',
schema: {
'x-align': 'left',
},
},
{
type: 'item',
title: "{{t('Add new')}}",
name: 'addNew',
Component: 'CreateActionInitializer',
schema: {
'x-align': 'right',
'x-decorator': 'ACLActionProvider',
'x-acl-action-props': {
skipScopeCheck: true,
},
},
useVisible() {
const collection = useCollection_deprecated();
return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView;
},
},
{
type: 'item',
title: "{{t('Delete')}}",
name: 'delete',
Component: 'BulkDestroyActionInitializer',
schema: {
'x-align': 'right',
'x-decorator': 'ACLActionProvider',
},
useVisible() {
const collection = useCollection_deprecated();
return !['view', 'sql'].includes(collection.template) || collection?.writableView;
},
},
{
type: 'item',
title: "{{t('Refresh')}}",
name: 'refresh',
Component: 'RefreshActionInitializer',
schema: {
'x-align': 'right',
},
},
{
name: 'toggle',
title: "{{t('Expand/Collapse')}}",
Component: 'ExpandableActionInitializer',
schema: {
'x-align': 'right',
},
useVisible() {
const schema = useFieldSchema();
const collection = useCollection_deprecated();
const { treeTable } = schema?.parent?.['x-decorator-props'] || {};
return collection.tree && treeTable !== false;
},
},
],
},
{
name: 'divider',
type: 'divider',
useVisible() {
const collection = useCollection_deprecated();
return !['view', 'sql'].includes(collection.template) || collection?.writableView;
},
},
{
type: 'subMenu',
name: 'customize',
title: '{{t("Customize")}}',
children: [
{
type: 'item',
title: '{{t("Add record")}}',
name: 'addRecord',
Component: 'CustomizeAddRecordActionInitializer',
schema: {
'x-align': 'right',
'x-decorator': 'ACLActionProvider',
'x-acl-action': 'create',
'x-acl-action-props': {
skipScopeCheck: true,
},
},
},
],
useVisible() {
const collection = useCollection_deprecated();
return !['view', 'sql'].includes(collection.template) || collection?.writableView;
},
},
],
},
tableActionInitializers_deprecated,
);

View File

@ -4,8 +4,30 @@ import { useCollectionManager_deprecated } from '../../../../collection-manager/
import { DataBlockInitializer } from '../../../../schema-initializer/items/DataBlockInitializer';
import { createTableBlockSchema } from '../../../../schema-initializer/utils';
import React from 'react';
import { Collection, CollectionFieldOptions } from '../../../../data-source/collection/Collection';
export const TableBlockInitializer = () => {
export const TableBlockInitializer = ({
filterCollections,
onlyCurrentDataSource,
hideSearch,
createBlockSchema,
templateWrap,
showAssociationFields,
}: {
filterCollections: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean;
onlyCurrentDataSource: boolean;
hideSearch?: boolean;
createBlockSchema?: (options: any) => any;
templateWrap?: (
templateSchema: any,
{
item,
}: {
item: any;
},
) => any;
showAssociationFields?: boolean;
}) => {
const { insert } = useSchemaInitializer();
const { getCollection } = useCollectionManager_deprecated();
const itemConfig = useSchemaInitializerItem();
@ -15,6 +37,10 @@ export const TableBlockInitializer = () => {
icon={<TableOutlined />}
componentType={'Table'}
onCreateBlockSchema={async ({ item }) => {
if (createBlockSchema) {
return createBlockSchema({ item });
}
const collection = getCollection(item.name, item.dataSource);
const schema = createTableBlockSchema({
collection: item.name,
@ -23,6 +49,10 @@ export const TableBlockInitializer = () => {
});
insert(schema);
}}
onlyCurrentDataSource={onlyCurrentDataSource}
hideSearch={hideSearch}
filter={filterCollections}
showAssociationFields={showAssociationFields}
/>
);
};

View File

@ -1,14 +1,14 @@
import { useFieldSchema } from '@formily/react';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { SchemaInitializerChildren } from '../../../../application';
import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer';
import { useCompile } from '../../../../schema-component';
import {
useAssociatedTableColumnInitializerFields,
useInheritsTableColumnInitializerFields,
useTableColumnInitializerFields,
} from '../../../../schema-initializer/utils';
import { SchemaInitializerChildren } from '../../../../application/schema-initializer/components/SchemaInitializerChildren';
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
// 表格列配置
const ParentCollectionFields = () => {
@ -47,7 +47,10 @@ const AssociatedFields = () => {
return <SchemaInitializerChildren>{schema}</SchemaInitializerChildren>;
};
export const tableColumnInitializers = new SchemaInitializer({
/**
* @deprecated
*/
export const tableColumnInitializers_deprecated = new CompatibleSchemaInitializer({
name: 'TableColumnInitializers',
insertPosition: 'beforeEnd',
icon: 'SettingOutlined',
@ -106,3 +109,66 @@ export const tableColumnInitializers = new SchemaInitializer({
},
],
});
export const tableColumnInitializers = new CompatibleSchemaInitializer(
{
name: 'table:configureColumns',
insertPosition: 'beforeEnd',
icon: 'SettingOutlined',
title: '{{t("Configure columns")}}',
wrap: (s, { isInSubTable }) => {
if (s['x-action-column']) {
return s;
}
return {
type: 'void',
'x-decorator': 'TableV2.Column.Decorator',
// 'x-designer': 'TableV2.Column.Designer',
'x-toolbar': 'TableColumnSchemaToolbar',
'x-settings': 'fieldSettings:TableColumn',
'x-component': 'TableV2.Column',
properties: {
[s.name]: {
...s,
},
},
};
},
items: [
{
name: 'displayFields',
type: 'itemGroup',
title: '{{t("Display fields")}}',
// children: DisplayFields,
useChildren: useTableColumnInitializerFields,
},
{
name: 'parentCollectionFields',
Component: ParentCollectionFields,
},
{
name: 'associationFields',
Component: AssociatedFields,
},
{
name: 'divider',
type: 'divider',
useVisible() {
const fieldSchema = useFieldSchema();
return fieldSchema['x-component'] !== 'AssociationField.SubTable';
},
},
{
type: 'item',
name: 'add',
title: '{{t("Action column")}}',
Component: 'TableActionColumnInitializer',
useVisible() {
const fieldSchema = useFieldSchema();
return fieldSchema['x-component'] !== 'AssociationField.SubTable';
},
},
],
},
tableColumnInitializers_deprecated,
);

View File

@ -2,7 +2,7 @@ import { expect, oneEmptyTableBlockBasedOnUsers, test } from '@nocobase/test/e2e
test('actions', async ({ page, mockPage }) => {
await mockPage(oneEmptyTableBlockBasedOnUsers).goto();
await page.getByLabel('schema-initializer-ActionBar-TableActionInitializers-users').hover();
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-users').hover();
//添加按钮
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();

View File

@ -4,7 +4,7 @@ test.describe('where table block can be added', () => {
test('page', async ({ page, mockPage }) => {
await mockPage().goto();
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
await page.getByLabel('schema-initializer-Grid-page:addBlock').hover();
await createBlockInPage(page, 'Table');
await expect(page.getByLabel('block-item-CardItem-users-table')).toBeVisible();
});
@ -17,7 +17,7 @@ test.describe('configure actions', () => {
await mockPage(oneEmptyTable).goto();
// add buttons
await page.getByLabel('schema-initializer-ActionBar-TableActionInitializers-t_unp4scqamw9').hover();
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-t_unp4scqamw9').hover();
await page.getByRole('menuitem', { name: 'Filter' }).click();
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
@ -35,7 +35,7 @@ test.describe('configure actions', () => {
await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible();
// delete buttons
await page.getByLabel('schema-initializer-ActionBar-TableActionInitializers-t_unp4scqamw9').hover();
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-t_unp4scqamw9').hover();
await page.getByRole('menuitem', { name: 'Filter' }).click();
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
@ -56,7 +56,7 @@ test.describe('configure actions', () => {
test('customize: add record', async ({ page, mockPage }) => {
await mockPage(oneEmptyTable).goto();
await page.getByLabel('schema-initializer-ActionBar-TableActionInitializers-t_unp4scqamw9').hover();
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-t_unp4scqamw9').hover();
await page.getByRole('menuitem', { name: 'Customize' }).hover();
await page.getByRole('menuitem', { name: 'add record' }).click();
@ -70,7 +70,7 @@ test.describe('configure columns', () => {
test.describe.configure({ retries: process.env.CI ? 4 : 0 });
test('action column & display collection fields & display association fields', async ({ page, mockPage }) => {
await mockPage(oneEmptyTable).goto();
const configureColumnButton = page.getByLabel('schema-initializer-TableV2-TableColumnInitializers-t_unp4scqamw9');
const configureColumnButton = page.getByLabel('schema-initializer-TableV2-table:configureColumns-t_unp4scqamw9');
// Action column -------------------------------------------------------------
// 1. 点击开关,可以开启和关闭 Action column

View File

@ -101,7 +101,7 @@ test.describe('table block schema settings', () => {
).toBeChecked();
await expect(page.getByRole('menuitem', { name: 'Set default sorting rules' })).toBeHidden();
// 显示出来 email 和 ID
await page.getByLabel('schema-initializer-TableV2-TableColumnInitializers-general').hover();
await page.getByLabel('schema-initializer-TableV2-table:configureColumns-general').hover();
await page.getByRole('menuitem', { name: 'email' }).click();
await page.getByRole('menuitem', { name: 'ID', exact: true }).click();
await page.getByLabel('schema-initializer-TableV2-').click();
@ -141,7 +141,7 @@ test.describe('table block schema settings', () => {
}
async function createColumnItem(page: Page, fieldName: string) {
await page.getByLabel('schema-initializer-TableV2-TableColumnInitializers-general').hover();
await page.getByLabel('schema-initializer-TableV2-table:configureColumns-general').hover();
await page.getByRole('menuitem', { name: fieldName, exact: true }).click();
await page.mouse.move(300, 0);
}
@ -213,7 +213,7 @@ test.describe('table block schema settings', () => {
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 显示出来 email 和 ID
await page.getByLabel('schema-initializer-TableV2-TableColumnInitializers-general').hover();
await page.getByLabel('schema-initializer-TableV2-table:configureColumns-general').hover();
await page.getByRole('menuitem', { name: 'email' }).click();
await page.getByRole('menuitem', { name: 'ID', exact: true }).click();
await page.mouse.move(300, 0);
@ -567,7 +567,7 @@ test.describe('actions schema settings', () => {
test.describe('popup', () => {
const addSomeCustomActions = async (page: Page) => {
// 先删除掉之前的 actions
await page.getByRole('button', { name: 'Actions' }).hover();
await page.getByRole('button', { name: 'Actions', exact: true }).hover();
await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-general').hover();
await page.getByRole('menuitem', { name: 'View' }).click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
@ -624,7 +624,7 @@ test.describe('actions schema settings', () => {
test.describe('update record', () => {
const addSomeCustomActions = async (page: Page) => {
// 先删除掉之前的 actions
await page.getByRole('button', { name: 'Actions' }).hover();
await page.getByRole('button', { name: 'Actions', exact: true }).hover();
await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-general').hover();
await page.getByRole('menuitem', { name: 'View' }).click();
await page.getByRole('menuitem', { name: 'Edit' }).click();
@ -677,13 +677,13 @@ test.describe('actions schema settings', () => {
// 添加一行数据
// TODO: 使用 mockRecord 为 tree 表添加一行数据无效
await page.getByLabel('schema-initializer-ActionBar-TableActionInitializers-treeCollection').hover();
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-treeCollection').hover();
await page.getByRole('menuitem', { name: 'Add new' }).click();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel('schema-initializer-Grid-CreateFormBlockInitializers-treeCollection').hover();
await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-treeCollection').hover();
await page.getByRole('menuitem', { name: 'form Form' }).click();
await page.mouse.move(300, 0);
await page.getByLabel('schema-initializer-ActionBar-CreateFormActionInitializers-treeCollection').hover();
await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-treeCollection').hover();
await page.getByRole('menuitem', { name: 'Submit' }).click();
await page.mouse.move(300, 0);
await page.getByRole('button', { name: 'Submit' }).click();

View File

@ -10,7 +10,7 @@ export const T2183 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
'1n5r9s23amo': {
_isJSONSchemaObject: true,
@ -50,7 +50,7 @@ export const T2183 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -87,7 +87,7 @@ export const T2183 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -106,7 +106,7 @@ export const T2183 = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
properties: {
actions: {
_isJSONSchemaObject: true,
@ -169,7 +169,7 @@ export const T2186 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
'0r1mwh6fgdj': {
_isJSONSchemaObject: true,
@ -209,7 +209,7 @@ export const T2186 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -246,7 +246,7 @@ export const T2186 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -265,7 +265,7 @@ export const T2186 = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
properties: {
actions: {
_isJSONSchemaObject: true,
@ -328,7 +328,7 @@ export const T2187 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
'x-initializer': 'page:addBlock',
properties: {
zp24b63pujf: {
_isJSONSchemaObject: true,
@ -368,7 +368,7 @@ export const T2187 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-initializer': 'table:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
style: {
@ -383,7 +383,7 @@ export const T2187 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'array',
'x-initializer': 'TableColumnInitializers',
'x-initializer': 'table:configureColumns',
'x-component': 'TableV2',
'x-component-props': {
rowKey: 'id',
@ -402,7 +402,7 @@ export const T2187 = {
'x-decorator': 'TableV2.Column.ActionBar',
'x-component': 'TableV2.Column',
'x-designer': 'TableV2.ActionColumnDesigner',
'x-initializer': 'TableActionColumnInitializers',
'x-initializer': 'table:configureItemActions',
properties: {
actions: {
_isJSONSchemaObject: true,
@ -468,7 +468,7 @@ export const T2187 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'CreateFormBlockInitializers',
'x-initializer': 'popup:addNew:addBlock',
properties: {
qvyfk3a9a2g: {
_isJSONSchemaObject: true,
@ -513,7 +513,7 @@ export const T2187 = {
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FormItemInitializers',
'x-initializer': 'form:configureFields',
properties: {
h191s1ni4am: {
_isJSONSchemaObject: true,
@ -573,7 +573,7 @@ export const T2187 = {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'CreateFormActionInitializers',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',

View File

@ -21,6 +21,7 @@ import { useTranslation } from 'react-i18next';
import { ArrayItems } from '@formily/antd-v5';
import { FixedBlockDesignerItem } from '../../../../schema-component/antd/page/FixedBlockDesignerItem';
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
import { setDataLoadingModeSettingsItem, useDataLoadingMode } from '../details-multi/setDataLoadingModeSettingsItem';
export const tableBlockSettings = new SchemaSettings({
name: 'blockSettings:table',
@ -138,6 +139,7 @@ export const tableBlockSettings = new SchemaSettings({
const { form } = useFormBlockContext();
const { service } = useTableBlockContext();
const { dn } = useDesignable();
const dataLoadingMode = useDataLoadingMode();
const onDataScopeSubmit = useCallback(
({ filter }) => {
filter = removeNullCondition(filter);
@ -146,10 +148,14 @@ export const tableBlockSettings = new SchemaSettings({
field.decoratorProps.params = params;
fieldSchema['x-decorator-props']['params'] = params;
const filters = service.params?.[1]?.filters || {};
service.run(
{ ...service.params?.[0], filter: mergeFilter([...Object.values(filters), filter]), page: 1 },
{ filters },
);
if (dataLoadingMode === 'auto') {
service.run(
{ ...service.params?.[0], filter: mergeFilter([...Object.values(filters), filter]), page: 1 },
{ filters },
);
}
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
@ -290,6 +296,7 @@ export const tableBlockSettings = new SchemaSettings({
return !dragSort;
},
},
setDataLoadingModeSettingsItem,
{
name: 'RecordsPerPage',
type: 'select',

Some files were not shown because too many files have changed in this diff Show More