mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 21:49:25 +08:00
refactor: flatten and merge Actions (#4336)
* chore: remove switch * refactor: ensure compatibility with old code * refactor: flatten Actions * refactor: extract options * refactor: remove isCusomeizeCreate * refactor: merge addNew and addRecord actions * refactor: merge Submit and Save record actions * refactor: extract common options * feat: add tow props called 'currentText' and 'otherText' * chore: fix failed tests * refactor: add ActionInitializerItem to replace ActionInitializer * chore: fix failed tests * fix: fix T-4284 * fix: fix inherit * chore: fix failed test * chore: add Switch * chore: add Switch for delete button * test: e2ePageObjectModel --------- Co-authored-by: hongboji <j414562100@qq.com>
This commit is contained in:
parent
779029e348
commit
ec558e3b98
@ -1,83 +0,0 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
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 });
|
||||
});
|
||||
});
|
@ -43,6 +43,23 @@ describe('SchemaInitializer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// 为了能让旧版插件代码正常工作(操作按钮拍平后:https://nocobase.feishu.cn/wiki/O7pjwSbBEigpOWkY9s5c03Yenkh),需要满足下面的测试用例
|
||||
test('add an item with nested name', () => {
|
||||
// 等同于 initializer.add('item1', { title: 'item1 title' });
|
||||
initializer.add('parent.item1', { title: 'item1 title' });
|
||||
|
||||
// 等同于 initializer.get('item1')
|
||||
expect(initializer.get('parent.item1')).toEqual({
|
||||
name: 'item1',
|
||||
title: 'item1 title',
|
||||
});
|
||||
expect(initializer.get('item1')).toEqual({
|
||||
name: 'item1',
|
||||
title: 'item1 title',
|
||||
});
|
||||
expect(initializer.get('parent')).toBe(undefined);
|
||||
});
|
||||
|
||||
test('updates a nested item if it already exists', () => {
|
||||
initializer.add('parent', { title: 'parent title' });
|
||||
initializer.add('parent.item1', { title: 'title' });
|
||||
|
@ -10,7 +10,7 @@
|
||||
import { SchemaInitializer } from './SchemaInitializer';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @deprecated - 该类仅用于兼容旧版 name,不推荐在新插件中使用
|
||||
*
|
||||
* 因为需要把 SchemaInitializer 的 name 统一为一致的命名风格,统一之后新创建的 Schema 将
|
||||
* 使用新的命名风格,而旧的 Schema 仍然使用旧的命名风格,这样会导致一些问题。所以需要有一个方法
|
||||
@ -99,7 +99,7 @@ const oldToNewNameMap = {
|
||||
|
||||
/**
|
||||
* 由于旧版的 schema 的 x-initializer 的值是旧的命名风格,当其与新的命名比较时就存在问题,
|
||||
* 这里通过将新版命名转换为旧版命名再进行比较,已解决这个问题。
|
||||
* 这里通过将新版命名转换为旧版命名再进行比较,以解决这个问题。
|
||||
* @param oldOrNewName x-initializer 的值
|
||||
* @param newName 新的命名
|
||||
*/
|
||||
|
@ -24,14 +24,20 @@ export class SchemaInitializer<P1 = ButtonProps, P2 = {}> {
|
||||
|
||||
add(name: string, item: SchemaInitializerItemTypeWithoutName) {
|
||||
const arr = name.split('.');
|
||||
const data: any = { ...item, name: arr[arr.length - 1] };
|
||||
if (arr.length === 1) {
|
||||
const itemName = arr[arr.length - 1];
|
||||
const data: any = { ...item, name: itemName };
|
||||
|
||||
const pushData = (name: string, data: any) => {
|
||||
const index = this.items.findIndex((item: any) => item.name === name);
|
||||
if (index === -1) {
|
||||
this.items.push(data);
|
||||
} else {
|
||||
this.items[index] = data;
|
||||
}
|
||||
};
|
||||
|
||||
if (arr.length === 1) {
|
||||
pushData(itemName, data);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -48,25 +54,28 @@ export class SchemaInitializer<P1 = ButtonProps, P2 = {}> {
|
||||
} else {
|
||||
parentItem.children[index] = data;
|
||||
}
|
||||
|
||||
// 这里是为了兼容这个改动:https://nocobase.feishu.cn/wiki/O7pjwSbBEigpOWkY9s5c03Yenkh
|
||||
} else {
|
||||
pushData(itemName, data);
|
||||
}
|
||||
}
|
||||
|
||||
get(nestedName: string): SchemaInitializerItemType | undefined {
|
||||
if (!nestedName) return undefined;
|
||||
const arr = nestedName.split('.');
|
||||
let current: any = this.items;
|
||||
let current: any = { children: this.items };
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const name = arr[i];
|
||||
current = current.find((item) => item.name === name);
|
||||
if (!current || i === arr.length - 1) {
|
||||
return current;
|
||||
const _current = current.children?.find((item) => item.name === name);
|
||||
|
||||
if (_current) {
|
||||
current = _current;
|
||||
}
|
||||
|
||||
if (current.children) {
|
||||
current = current.children;
|
||||
} else {
|
||||
return undefined;
|
||||
if (i === arr.length - 1) {
|
||||
return _current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import { Schema, useField } from '@formily/react';
|
||||
import { Spin } from 'antd';
|
||||
import React, { createContext, useContext, useEffect, useMemo, useRef } from 'react';
|
||||
import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps';
|
||||
import { useCollection_deprecated } from '../collection-manager';
|
||||
import {
|
||||
CollectionRecord,
|
||||
useCollectionManager,
|
||||
@ -20,8 +19,8 @@ import {
|
||||
useCollectionRecord,
|
||||
} from '../data-source';
|
||||
import { useTreeParentRecord } from '../modules/blocks/data-blocks/table/TreeRecordProvider';
|
||||
import { RecordProvider, useRecord } from '../record-provider';
|
||||
import { useActionContext, useDesignable } from '../schema-component';
|
||||
import { RecordProvider } from '../record-provider';
|
||||
import { useActionContext } from '../schema-component';
|
||||
import { Templates as DataTemplateSelect } from '../schema-component/antd/form-v2/Templates';
|
||||
import { BlockProvider, useBlockRequestContext } from './BlockProvider';
|
||||
import { TemplateBlockProvider } from './TemplateBlockProvider';
|
||||
@ -125,27 +124,8 @@ export const useIsDetailBlock = () => {
|
||||
};
|
||||
|
||||
export const FormBlockProvider = withDynamicSchemaProps((props) => {
|
||||
const record = useRecord();
|
||||
const parentRecordData = useCollectionParentRecordData();
|
||||
const { collection, isCusomeizeCreate, parentRecord } = props;
|
||||
const { __collection } = record;
|
||||
const currentCollection = useCollection_deprecated();
|
||||
const { designable } = useDesignable();
|
||||
const isDetailBlock = useIsDetailBlock();
|
||||
let detailFlag = false;
|
||||
if (isDetailBlock) {
|
||||
detailFlag = true;
|
||||
if (!designable && __collection) {
|
||||
detailFlag = __collection === collection;
|
||||
}
|
||||
}
|
||||
const createFlag =
|
||||
(currentCollection.name === (collection?.name || collection) && !isDetailBlock) ||
|
||||
!currentCollection.name ||
|
||||
!collection;
|
||||
if (!detailFlag && !createFlag && !isCusomeizeCreate) {
|
||||
return null;
|
||||
}
|
||||
const { parentRecord } = props;
|
||||
|
||||
return (
|
||||
<TemplateBlockProvider>
|
||||
|
@ -39,6 +39,8 @@ export interface AllDataBlockProps {
|
||||
requestService?: UseRequestService<any>;
|
||||
requestOptions?: UseRequestOptions;
|
||||
dataLoadingMode?: 'auto' | 'manual';
|
||||
/** 如果为 true,则区块会被隐藏 */
|
||||
hidden?: boolean;
|
||||
[index: string]: any;
|
||||
}
|
||||
|
||||
@ -149,9 +151,13 @@ export const AssociationOrCollectionProvider = (props: {
|
||||
|
||||
export const DataBlockProvider: FC<DataBlockProviderProps & { children?: ReactNode }> = withDynamicSchemaProps(
|
||||
(props) => {
|
||||
const { collection, association, dataSource, children, ...resets } = props as Partial<AllDataBlockProps>;
|
||||
const { collection, association, dataSource, children, hidden, ...resets } = props as Partial<AllDataBlockProps>;
|
||||
const { dn } = useDesignable();
|
||||
|
||||
if (hidden) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<DataBlockContext.Provider
|
||||
value={{
|
||||
|
@ -628,6 +628,8 @@
|
||||
"Current user": "Current user",
|
||||
"Current role": "Current role",
|
||||
"Current record": "Current record",
|
||||
"Current collection": "Current collection",
|
||||
"Other collections": "Other collections",
|
||||
"Current popup record": "Current popup record",
|
||||
"Associated records": "Associated records",
|
||||
"Parent record": "Parent record",
|
||||
|
@ -617,6 +617,8 @@
|
||||
"Current user": "Usuario actual",
|
||||
"Current role": "Rol actual",
|
||||
"Current record": "Registro actual",
|
||||
"Current collection": "Colección actual",
|
||||
"Other collections": "Otras colecciones",
|
||||
"Current popup record": "Registro actual del popup",
|
||||
"Associated records": "Registros asociados",
|
||||
"Parent record": "Registro padre",
|
||||
|
@ -614,6 +614,8 @@
|
||||
"Current user": "Utilisateur actuel",
|
||||
"Current role": "Rôle actuel",
|
||||
"Current record": "Enregistrement actuel",
|
||||
"Current collection": "Collection actuelle",
|
||||
"Other collections": "Autres collections",
|
||||
"Current popup record": "Enregistrement popup actuel",
|
||||
"Associated records": "Enregistrements associés",
|
||||
"Parent record": "Enregistrement parent",
|
||||
|
@ -517,6 +517,8 @@
|
||||
"Current user": "現在のユーザー",
|
||||
"Current role": "現在の役割",
|
||||
"Current record": "現在のレコード",
|
||||
"Current collection": "現在のコレクション",
|
||||
"Other collections": "他のコレクション",
|
||||
"Current popup record": "現在のポップアップレコード",
|
||||
"Associated records": "関連付けられたレコード",
|
||||
"Popup close method": "ポップアップを閉じる方法",
|
||||
|
@ -642,6 +642,8 @@
|
||||
"Current user": "현재 사용자",
|
||||
"Current role": "현재 역할",
|
||||
"Current record": "현재 레코드",
|
||||
"Current collection": "현재 데이터 테이블",
|
||||
"Other collections": "기타 데이터 테이블",
|
||||
"Current popup record": "현재 팝업 레코드",
|
||||
"Associated records": "관련 레코드",
|
||||
"Parent record": "상위 레코드",
|
||||
|
@ -452,6 +452,8 @@
|
||||
"Current user": "Текущий пользователь",
|
||||
"Current role": "Текущая роль",
|
||||
"Current record": "Текущая запись",
|
||||
"Current collection": "Текущая коллекция",
|
||||
"Other collections": "Другие коллекции",
|
||||
"Current popup record": "Текущая запись всплывающего окна",
|
||||
"Associated records": "Связанные записи",
|
||||
"Parent record": "Родительская запись",
|
||||
|
@ -452,6 +452,8 @@
|
||||
"Current user": "Seçili kullanıcı",
|
||||
"Current role": "Seçili rol",
|
||||
"Current record": "Seçili kayıt",
|
||||
"Current collection": "Seçili koleksiyon",
|
||||
"Other collections": "Diğer koleksiyonlar",
|
||||
"Current popup record": "Açılır pencere kaydı",
|
||||
"Associated records": "İlişkili kayıtlar",
|
||||
"Parent record": "Üst kayıt",
|
||||
|
@ -634,6 +634,8 @@
|
||||
"Current user": "Поточний користувач",
|
||||
"Current role": "Поточна роль",
|
||||
"Current record": "Поточний запис",
|
||||
"Current collection": "Поточна колекція",
|
||||
"Other collections": "Інші колекції",
|
||||
"Current popup record": "Поточний запис спливаючого вікна",
|
||||
"Associated records": "Пов'язані записи",
|
||||
"Parent record": "Батьківський запис",
|
||||
|
@ -646,6 +646,8 @@
|
||||
"Current user": "当前用户",
|
||||
"Current role": "当前角色",
|
||||
"Current record": "当前记录",
|
||||
"Current collection": "当前数据表",
|
||||
"Other collections": "其他数据表",
|
||||
"Current popup record": "当前弹窗记录",
|
||||
"Associated records": "关联记录",
|
||||
"Parent record": "上级记录",
|
||||
|
@ -642,6 +642,8 @@
|
||||
"Current user": "當前使用者",
|
||||
"Current role": "當前角色",
|
||||
"Current record": "當前記錄",
|
||||
"Current collection": "當前資料表",
|
||||
"Other collections": "其他資料表",
|
||||
"Current popup record": "當前彈窗記錄",
|
||||
"Associated records": "關聯記錄",
|
||||
"Parent record": "上級記錄",
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem';
|
||||
export const CreateChildInitializer = (props) => {
|
||||
const schema = {
|
||||
type: 'void',
|
||||
@ -64,5 +64,5 @@ export const CreateChildInitializer = (props) => {
|
||||
},
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import { useSchemaInitializerItem } from '../../../application';
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem';
|
||||
|
||||
export const CreateActionInitializer = () => {
|
||||
const schema = {
|
||||
@ -67,5 +67,5 @@ export const CreateActionInitializer = () => {
|
||||
},
|
||||
};
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
return <ActionInitializer {...itemConfig} item={itemConfig} schema={schema} />;
|
||||
return <ActionInitializerItem {...itemConfig} item={itemConfig} schema={schema} />;
|
||||
};
|
||||
|
@ -7,78 +7,79 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { CompatibleSchemaInitializer } from '../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
import { useCollection } from '../../../data-source/collection/CollectionProvider';
|
||||
import { gridRowColWrap } from '../../../schema-initializer/utils';
|
||||
|
||||
const commonOptions = {
|
||||
wrap: gridRowColWrap,
|
||||
title: '{{t("Add block")}}',
|
||||
icon: 'PlusOutlined',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Data blocks")}}',
|
||||
name: 'dataBlocks',
|
||||
useChildren() {
|
||||
const currentCollection = useCollection();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return [
|
||||
{
|
||||
name: 'form',
|
||||
title: '{{t("Form")}}',
|
||||
Component: 'FormBlockInitializer',
|
||||
collectionName: currentCollection.name,
|
||||
dataSource: currentCollection.dataSource,
|
||||
componentProps: {
|
||||
filterCollections({ collection, associationField }) {
|
||||
if (associationField) {
|
||||
return false;
|
||||
}
|
||||
if (collection.name === currentCollection.name) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
showAssociationFields: true,
|
||||
onlyCurrentDataSource: true,
|
||||
hideSearch: true,
|
||||
componentType: 'FormItem',
|
||||
currentText: t('Current collection'),
|
||||
otherText: t('Other collections'),
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Other blocks")}}',
|
||||
name: 'otherBlocks',
|
||||
children: [
|
||||
{
|
||||
name: 'markdown',
|
||||
title: '{{t("Markdown")}}',
|
||||
Component: 'MarkdownBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `createFormBlockInitializers` instead
|
||||
*/
|
||||
export const createFormBlockInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'CreateFormBlockInitializers',
|
||||
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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
createFormBlockInitializers_deprecated,
|
||||
);
|
||||
|
@ -1,68 +0,0 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useSchemaInitializerItem } from '../../../application';
|
||||
import { BlockInitializer } from '../../../schema-initializer/items/BlockInitializer';
|
||||
|
||||
export const CustomizeAddRecordActionInitializer = () => {
|
||||
const schema = {
|
||||
type: 'void',
|
||||
title: '{{t("Add record")}}',
|
||||
'x-toolbar': 'ActionSchemaToolbar',
|
||||
'x-settings': 'actionSettings:addRecord',
|
||||
'x-component': 'Action',
|
||||
'x-action': 'customize:create',
|
||||
'x-component-props': {
|
||||
openMode: 'drawer',
|
||||
icon: 'PlusOutlined',
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
title: '{{t("Add record")}}',
|
||||
'x-component': 'Action.Container',
|
||||
'x-component-props': {
|
||||
className: 'nb-action-popup',
|
||||
},
|
||||
properties: {
|
||||
tabs: {
|
||||
type: 'void',
|
||||
'x-component': 'Tabs',
|
||||
'x-component-props': {},
|
||||
'x-initializer': 'popup:addTab',
|
||||
'x-initializer-props': {
|
||||
gridInitializer: 'popup:addRecord:addBlock',
|
||||
},
|
||||
properties: {
|
||||
tab1: {
|
||||
type: 'void',
|
||||
title: '{{t("Add record")}}',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-designer': 'Tabs.Designer',
|
||||
'x-component-props': {},
|
||||
properties: {
|
||||
grid: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'popup:addRecord:addBlock',
|
||||
properties: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
|
||||
return <BlockInitializer {...itemConfig} schema={schema} item={itemConfig} />;
|
||||
};
|
@ -10,77 +10,53 @@
|
||||
import { CompatibleSchemaInitializer } from '../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
import { gridRowColWrap } from '../../../schema-initializer/utils';
|
||||
|
||||
const commonOptions = {
|
||||
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',
|
||||
/** 表示是通过 Other collections 选项创建的区块(由于历史遗留问题,这里的命名暂不做更改) */
|
||||
isCusomeizeCreate: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Other blocks")}}',
|
||||
name: 'otherBlocks',
|
||||
children: [
|
||||
{
|
||||
name: 'markdown',
|
||||
title: '{{t("Markdown")}}',
|
||||
Component: 'MarkdownBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `customizeCreateFormBlockInitializers` instead
|
||||
*/
|
||||
export const customizeCreateFormBlockInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'CusomeizeCreateFormBlockInitializers',
|
||||
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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
customizeCreateFormBlockInitializers_deprecated,
|
||||
);
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
import React from 'react';
|
||||
import { useCollection_deprecated } from '../../../collection-manager';
|
||||
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
|
||||
export const BulkDestroyActionInitializer = (props) => {
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
|
||||
export const DestroyActionInitializer = (props) => {
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem';
|
||||
|
||||
export const DisassociateActionInitializer = (props) => {
|
||||
const schema = {
|
||||
@ -31,5 +30,5 @@ export const DisassociateActionInitializer = (props) => {
|
||||
triggerWorkflows: [],
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
|
||||
export const FilterActionInitializer = (props) => {
|
||||
|
@ -1,40 +0,0 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { BlockInitializer } from '../../../schema-initializer/items';
|
||||
import { useSchemaInitializerItem } from '../../../application';
|
||||
|
||||
export const SaveRecordActionInitializer = () => {
|
||||
const schema = {
|
||||
title: '{{ t("Save record") }}',
|
||||
'x-action': 'customize:save',
|
||||
'x-component': 'Action',
|
||||
'x-use-component-props': 'useCreateActionProps',
|
||||
'x-toolbar': 'ActionSchemaToolbar',
|
||||
'x-settings': 'actionSettings:saveRecord',
|
||||
'x-designer-props': {
|
||||
modalTip:
|
||||
'{{ t("When the button is clicked, the following fields will be assigned and saved together with the fields in the form. If there are overlapping fields, the value here will overwrite the value in the form.") }}',
|
||||
},
|
||||
'x-action-settings': {
|
||||
assignedValues: {},
|
||||
skipValidator: false,
|
||||
onSuccess: {
|
||||
manualClose: true,
|
||||
redirecting: false,
|
||||
successMessage: '{{t("Submitted successfully")}}',
|
||||
},
|
||||
triggerWorkflows: [],
|
||||
},
|
||||
};
|
||||
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
return <BlockInitializer {...itemConfig} schema={schema} item={itemConfig} />;
|
||||
};
|
@ -15,13 +15,17 @@ import {
|
||||
AfterSuccess,
|
||||
AssignedFieldValues,
|
||||
ButtonEditor,
|
||||
RefreshDataBlockRequest,
|
||||
RemoveButton,
|
||||
SecondConFirm,
|
||||
SkipValidation,
|
||||
WorkflowConfig,
|
||||
RefreshDataBlockRequest,
|
||||
} from '../../../schema-component/antd/action/Action.Designer';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* 已废弃,继续保留是为了兼容旧版本的 Schema,会在后面的版本中移除
|
||||
*/
|
||||
export const customizeSaveRecordActionSettings = new SchemaSettings({
|
||||
name: 'actionSettings:saveRecord',
|
||||
items: [
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem';
|
||||
|
||||
export const CreateSubmitActionInitializer = (props) => {
|
||||
const schema = {
|
||||
@ -26,5 +26,5 @@ export const CreateSubmitActionInitializer = (props) => {
|
||||
triggerWorkflows: [],
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem';
|
||||
|
||||
export const UpdateSubmitActionInitializer = (props) => {
|
||||
const schema = {
|
||||
@ -28,5 +27,5 @@ export const UpdateSubmitActionInitializer = (props) => {
|
||||
triggerWorkflows: [],
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -7,22 +7,26 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { useFieldSchema, useField, connect, mapProps, ISchema } from '@formily/react';
|
||||
import { ISchema, connect, mapProps, useField, useFieldSchema } from '@formily/react';
|
||||
import { isValid } from '@formily/shared';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Tree as AntdTree } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSchemaToolbar } from '../../../application';
|
||||
import { SchemaSettings } from '../../../application/schema-settings/SchemaSettings';
|
||||
import { useCollection_deprecated } from '../../../collection-manager';
|
||||
import { useDesignable } from '../../../schema-component';
|
||||
import {
|
||||
AfterSuccess,
|
||||
AssignedFieldValues,
|
||||
ButtonEditor,
|
||||
RefreshDataBlockRequest,
|
||||
RemoveButton,
|
||||
SecondConFirm,
|
||||
SkipValidation,
|
||||
WorkflowConfig,
|
||||
} from '../../../schema-component/antd/action/Action.Designer';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDesignable } from '../../../schema-component';
|
||||
import { useCollectionState } from '../../../schema-settings/DataTemplates/hooks/useCollectionState';
|
||||
import { useCollection_deprecated } from '../../../collection-manager';
|
||||
import { SchemaSettingsModalItem } from '../../../schema-settings/SchemaSettings';
|
||||
|
||||
const Tree = connect(
|
||||
@ -132,6 +136,7 @@ export function SaveMode() {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const createSubmitActionSettings = new SchemaSettings({
|
||||
name: 'actionSettings:createSubmit',
|
||||
items: [
|
||||
@ -159,6 +164,31 @@ export const createSubmitActionSettings = new SchemaSettings({
|
||||
name: 'saveMode',
|
||||
Component: SaveMode,
|
||||
},
|
||||
{
|
||||
name: 'assignFieldValues',
|
||||
Component: AssignedFieldValues,
|
||||
},
|
||||
{
|
||||
name: 'skipRequiredValidation',
|
||||
Component: SkipValidation,
|
||||
},
|
||||
{
|
||||
name: 'afterSuccessfulSubmission',
|
||||
Component: AfterSuccess,
|
||||
useVisible() {
|
||||
const fieldSchema = useFieldSchema();
|
||||
return isValid(fieldSchema?.['x-action-settings']?.onSuccess);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'refreshDataBlockRequest',
|
||||
Component: RefreshDataBlockRequest,
|
||||
useComponentProps() {
|
||||
return {
|
||||
isPopupAction: false,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'remove',
|
||||
sort: 100,
|
||||
|
@ -12,9 +12,13 @@ import { isValid } from '@formily/shared';
|
||||
import { isInitializersSame, useSchemaToolbar } from '../../../application';
|
||||
import { SchemaSettings } from '../../../application/schema-settings/SchemaSettings';
|
||||
import {
|
||||
AfterSuccess,
|
||||
AssignedFieldValues,
|
||||
ButtonEditor,
|
||||
RefreshDataBlockRequest,
|
||||
RemoveButton,
|
||||
SecondConFirm,
|
||||
SkipValidation,
|
||||
WorkflowConfig,
|
||||
} from '../../../schema-component/antd/action/Action.Designer';
|
||||
import { SaveMode } from './createSubmitActionSettings';
|
||||
@ -42,6 +46,31 @@ export const updateSubmitActionSettings = new SchemaSettings({
|
||||
return isValid(fieldSchema?.['x-action-settings']?.triggerWorkflows);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'assignFieldValues',
|
||||
Component: AssignedFieldValues,
|
||||
},
|
||||
{
|
||||
name: 'skipRequiredValidation',
|
||||
Component: SkipValidation,
|
||||
},
|
||||
{
|
||||
name: 'afterSuccessfulSubmission',
|
||||
Component: AfterSuccess,
|
||||
useVisible() {
|
||||
const fieldSchema = useFieldSchema();
|
||||
return isValid(fieldSchema?.['x-action-settings']?.onSuccess);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'refreshDataBlockRequest',
|
||||
Component: RefreshDataBlockRequest,
|
||||
useComponentProps() {
|
||||
return {
|
||||
isPopupAction: false,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'remove',
|
||||
sort: 100,
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem';
|
||||
|
||||
export const UpdateActionInitializer = (props) => {
|
||||
const schema = {
|
||||
@ -59,5 +58,5 @@ export const UpdateActionInitializer = (props) => {
|
||||
},
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem';
|
||||
|
||||
export const ViewActionInitializer = (props) => {
|
||||
const schema = {
|
||||
@ -58,5 +57,5 @@ export const ViewActionInitializer = (props) => {
|
||||
},
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -9,13 +9,7 @@
|
||||
|
||||
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `detailsActionInitializers` instead
|
||||
* 表单的操作配置
|
||||
*/
|
||||
export const detailsActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'DetailsActionInitializers',
|
||||
const commonOptions = {
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
style: {
|
||||
@ -50,17 +44,17 @@ export const detailsActionInitializers_deprecated = new CompatibleSchemaInitiali
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
type: 'subMenu',
|
||||
name: 'customize',
|
||||
title: '{{t("Customize")}}',
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `detailsActionInitializers` instead
|
||||
* 表单的操作配置
|
||||
*/
|
||||
export const detailsActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'DetailsActionInitializers',
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
/**
|
||||
@ -70,41 +64,7 @@ export const detailsActionInitializers_deprecated = new CompatibleSchemaInitiali
|
||||
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',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
detailsActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -7,9 +7,16 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { createBlockInPage, expect, oneEmptyDetailsBlock, test } from '@nocobase/test/e2e';
|
||||
import { Page, createBlockInPage, expect, oneEmptyDetailsBlock, test } from '@nocobase/test/e2e';
|
||||
import { oneEmptyTableWithUsers } from './templatesOfBug';
|
||||
|
||||
const deleteButton = async (page: Page, name: string) => {
|
||||
await page.getByRole('button', { name }).hover();
|
||||
await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
};
|
||||
|
||||
test.describe('where multi data details block can be added', () => {
|
||||
test('page', async ({ page, mockPage }) => {
|
||||
await mockPage().goto();
|
||||
@ -109,20 +116,13 @@ test.describe('configure actions', () => {
|
||||
await page.getByRole('menuitem', { name: 'Edit' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Edit' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Delete' })).toBeVisible();
|
||||
|
||||
// delete buttons
|
||||
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 expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked();
|
||||
await deleteButton(page, 'Edit');
|
||||
await deleteButton(page, 'Delete');
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Edit' })).not.toBeVisible();
|
||||
|
@ -15,6 +15,66 @@ const useVisibleCollection = () => {
|
||||
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
|
||||
};
|
||||
|
||||
const commonOptions = {
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
style: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
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: 'popup',
|
||||
title: '{{t("Popup")}}',
|
||||
Component: 'PopupActionInitializer',
|
||||
useComponentProps() {
|
||||
return {
|
||||
'x-component': 'Action',
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'updateRecord',
|
||||
title: '{{t("Update record")}}',
|
||||
Component: 'UpdateRecordActionInitializer',
|
||||
useComponentProps() {
|
||||
return {
|
||||
'x-component': 'Action',
|
||||
};
|
||||
},
|
||||
useVisible: useVisibleCollection,
|
||||
},
|
||||
{
|
||||
name: 'customRequest',
|
||||
title: '{{t("Custom request")}}',
|
||||
Component: 'CustomRequestInitializer',
|
||||
useVisible: useVisibleCollection,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `readPrettyFormActionInitializers` instead
|
||||
@ -22,161 +82,13 @@ const useVisibleCollection = () => {
|
||||
*/
|
||||
export const readPrettyFormActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'ReadPrettyFormActionInitializers',
|
||||
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',
|
||||
};
|
||||
},
|
||||
useVisible: useVisibleCollection,
|
||||
},
|
||||
{
|
||||
name: 'customRequest',
|
||||
title: '{{t("Custom request")}}',
|
||||
Component: 'CustomRequestInitializer',
|
||||
useVisible: useVisibleCollection,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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',
|
||||
};
|
||||
},
|
||||
useVisible: useVisibleCollection,
|
||||
},
|
||||
{
|
||||
name: 'customRequest',
|
||||
title: '{{t("Custom request")}}',
|
||||
Component: 'CustomRequestInitializer',
|
||||
useVisible: useVisibleCollection,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
readPrettyFormActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -54,97 +54,62 @@ const AssociatedFields = () => {
|
||||
return <SchemaInitializerChildren>{schema}</SchemaInitializerChildren>;
|
||||
};
|
||||
|
||||
const commonOptions = {
|
||||
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': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'blockSettings:markdown',
|
||||
'x-component': 'Markdown.Void',
|
||||
'x-component-props': {
|
||||
content: '{{t("This is a demo text, **supports Markdown syntax**.")}}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `readPrettyFormItemInitializers` instead
|
||||
*/
|
||||
export const readPrettyFormItemInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'ReadPrettyFormItemInitializers',
|
||||
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': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'blockSettings:markdown',
|
||||
'x-component': 'Markdown.Void',
|
||||
'x-component-props': {
|
||||
content: '{{t("This is a demo text, **supports Markdown syntax**.")}}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'blockSettings:markdown',
|
||||
'x-component': 'Markdown.Void',
|
||||
'x-component-props': {
|
||||
content: '{{t("This is a demo text, **supports Markdown syntax**.")}}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
readPrettyFormItemInitializers_deprecated,
|
||||
);
|
||||
|
@ -143,13 +143,11 @@ test.describe('configure fields', () => {});
|
||||
async function createAction(page: Page, name: string) {
|
||||
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-details:configureActions-general').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize' }).hover();
|
||||
await page.getByRole('menuitem', { name: name }).click();
|
||||
await page.mouse.move(0, 400);
|
||||
}
|
||||
|
@ -1,75 +0,0 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { FormOutlined } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
|
||||
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
|
||||
import { useCollection_deprecated } from '../../../../collection-manager';
|
||||
import { useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils';
|
||||
import { useSchemaTemplateManager } from '../../../../schema-templates';
|
||||
import { createCreateFormBlockUISchema } from './createCreateFormBlockUISchema';
|
||||
import { useAssociationName } from '../../../../data-source';
|
||||
|
||||
// TODO: `SchemaInitializerItem` items
|
||||
export const CreateFormBlockInitializer = () => {
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
const { onCreateBlockSchema, componentType, createBlockSchema, ...others } = itemConfig;
|
||||
const { getTemplateSchemaByMode } = useSchemaTemplateManager();
|
||||
const { insert } = useSchemaInitializer();
|
||||
const association = useAssociationName();
|
||||
const collection = useCollection_deprecated();
|
||||
return (
|
||||
<SchemaInitializerItem
|
||||
icon={<FormOutlined />}
|
||||
{...others}
|
||||
onClick={async ({ item }) => {
|
||||
if (item.template) {
|
||||
const s = await getTemplateSchemaByMode(item);
|
||||
if (item.template.componentName === 'FormItem') {
|
||||
const blockSchema = createCreateFormBlockUISchema(
|
||||
association
|
||||
? {
|
||||
association,
|
||||
dataSource: collection.dataSource,
|
||||
templateSchema: s,
|
||||
}
|
||||
: {
|
||||
collectionName: collection.name,
|
||||
dataSource: collection.dataSource,
|
||||
templateSchema: s,
|
||||
},
|
||||
);
|
||||
if (item.mode === 'reference') {
|
||||
blockSchema['x-template-key'] = item.template.key;
|
||||
}
|
||||
insert(blockSchema);
|
||||
} else {
|
||||
insert(s);
|
||||
}
|
||||
} else {
|
||||
insert(
|
||||
createCreateFormBlockUISchema(
|
||||
association
|
||||
? {
|
||||
association,
|
||||
dataSource: collection.dataSource,
|
||||
}
|
||||
: {
|
||||
collectionName: collection.name,
|
||||
dataSource: collection.dataSource,
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}}
|
||||
items={useRecordCollectionDataSourceItems('FormItem')}
|
||||
/>
|
||||
);
|
||||
};
|
@ -10,6 +10,7 @@
|
||||
import { FormOutlined } from '@ant-design/icons';
|
||||
import React, { useCallback } from 'react';
|
||||
import { useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
|
||||
import { useAssociationName } from '../../../../data-source/collection/AssociationProvider';
|
||||
import { Collection, CollectionFieldOptions } from '../../../../data-source/collection/Collection';
|
||||
import { DataBlockInitializer } from '../../../../schema-initializer/items/DataBlockInitializer';
|
||||
import { createCreateFormBlockUISchema } from './createCreateFormBlockUISchema';
|
||||
@ -24,6 +25,8 @@ export const FormBlockInitializer = ({
|
||||
showAssociationFields,
|
||||
hideChildrenIfSingleCollection,
|
||||
hideOtherRecordsInPopup,
|
||||
currentText,
|
||||
otherText,
|
||||
}: {
|
||||
filterCollections: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean;
|
||||
onlyCurrentDataSource: boolean;
|
||||
@ -47,6 +50,10 @@ export const FormBlockInitializer = ({
|
||||
* 隐藏弹窗中的 Other records 选项
|
||||
*/
|
||||
hideOtherRecordsInPopup?: boolean;
|
||||
/** 用于更改 Current record 的文案 */
|
||||
currentText?: string;
|
||||
/** 用于更改 Other records 的文案 */
|
||||
otherText?: string;
|
||||
}) => {
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
const { createFormBlock, templateWrap } = useCreateFormBlock();
|
||||
@ -84,42 +91,84 @@ export const FormBlockInitializer = ({
|
||||
showAssociationFields={showAssociationFields}
|
||||
hideChildrenIfSingleCollection={hideChildrenIfSingleCollection}
|
||||
hideOtherRecordsInPopup={hideOtherRecordsInPopup}
|
||||
currentText={currentText}
|
||||
otherText={otherText}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const useCreateFormBlock = () => {
|
||||
const { insert } = useSchemaInitializer();
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
const { isCusomeizeCreate: isCustomizeCreate } = itemConfig;
|
||||
const association = useAssociationName();
|
||||
const { isCusomeizeCreate: isCustomizeCreate } = useSchemaInitializerItem();
|
||||
|
||||
const createFormBlock = useCallback(
|
||||
({ item }) => {
|
||||
({ item, fromOthersInPopup }) => {
|
||||
if (fromOthersInPopup) {
|
||||
insert(
|
||||
createCreateFormBlockUISchema({
|
||||
collectionName: item.collectionName || item.name,
|
||||
dataSource: item.dataSource,
|
||||
isCusomeizeCreate: isCustomizeCreate,
|
||||
isCusomeizeCreate: true,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
insert(
|
||||
createCreateFormBlockUISchema(
|
||||
association
|
||||
? {
|
||||
association,
|
||||
dataSource: item.dataSource,
|
||||
isCusomeizeCreate: isCustomizeCreate,
|
||||
}
|
||||
: {
|
||||
collectionName: item.collectionName || item.name,
|
||||
dataSource: item.dataSource,
|
||||
isCusomeizeCreate: isCustomizeCreate,
|
||||
},
|
||||
[insert, isCustomizeCreate],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
[association, insert, isCustomizeCreate],
|
||||
);
|
||||
|
||||
const templateWrap = useCallback(
|
||||
(templateSchema, { item }) => {
|
||||
const schema = createCreateFormBlockUISchema({
|
||||
isCusomeizeCreate: isCustomizeCreate,
|
||||
(templateSchema, { item, fromOthersInPopup }) => {
|
||||
let schema;
|
||||
|
||||
if (fromOthersInPopup) {
|
||||
schema = createCreateFormBlockUISchema({
|
||||
dataSource: item.dataSource,
|
||||
templateSchema: templateSchema,
|
||||
collectionName: item.name,
|
||||
isCusomeizeCreate: true,
|
||||
});
|
||||
} else {
|
||||
schema = createCreateFormBlockUISchema(
|
||||
association
|
||||
? {
|
||||
dataSource: item.dataSource,
|
||||
templateSchema: templateSchema,
|
||||
collectionName: item.name,
|
||||
association,
|
||||
isCusomeizeCreate: isCustomizeCreate,
|
||||
}
|
||||
: {
|
||||
dataSource: item.dataSource,
|
||||
templateSchema: templateSchema,
|
||||
collectionName: item.name,
|
||||
isCusomeizeCreate: isCustomizeCreate,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (item.template && item.mode === 'reference') {
|
||||
schema['x-template-key'] = item.template.key;
|
||||
}
|
||||
return schema;
|
||||
},
|
||||
[isCustomizeCreate],
|
||||
[association, isCustomizeCreate],
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -62,7 +62,8 @@ test.describe('association form block', () => {
|
||||
.getByLabel('schema-initializer-Grid-popup')
|
||||
.click();
|
||||
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).click();
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Current collection' }).click();
|
||||
await expect(await page.getByLabel('block-item-CardItem-roles-form')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
@ -8,10 +8,17 @@
|
||||
*/
|
||||
|
||||
import { uid } from '@formily/shared';
|
||||
import { createBlockInPage, expect, oneEmptyForm, test } from '@nocobase/test/e2e';
|
||||
import { Page, createBlockInPage, expect, oneEmptyForm, test } from '@nocobase/test/e2e';
|
||||
import { oneEmptyTableWithUsers } from '../../../details-multi/__e2e__/templatesOfBug';
|
||||
import { T3106, T3469, oneFormWithInheritFields } from './templatesOfBug';
|
||||
|
||||
const deleteButton = async (page: Page, name: string) => {
|
||||
await page.getByRole('button', { name }).hover();
|
||||
await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
};
|
||||
|
||||
test.describe('where creation form block can be added', () => {
|
||||
test('page', async ({ page, mockPage }) => {
|
||||
await mockPage().goto();
|
||||
@ -111,16 +118,11 @@ test.describe('configure actions', () => {
|
||||
|
||||
// add button
|
||||
await page.getByRole('menuitem', { name: 'Submit' }).click();
|
||||
await expect(page.getByRole('menuitem', { name: 'Submit' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Submit' })).toBeVisible();
|
||||
|
||||
// delete button
|
||||
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();
|
||||
|
||||
await deleteButton(page, 'Submit');
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Submit' })).not.toBeVisible();
|
||||
});
|
||||
@ -178,14 +180,4 @@ test.describe('configure actions', () => {
|
||||
page.getByLabel('block-item-CollectionField-users-form-users.username-Username').getByRole('textbox'),
|
||||
).toHaveValue('');
|
||||
});
|
||||
|
||||
test('customize: save record', async ({ page, mockPage }) => {
|
||||
await mockPage(oneEmptyForm).goto();
|
||||
|
||||
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();
|
||||
|
||||
await expect(page.getByRole('button', { name: 'Save record' })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
@ -402,16 +402,16 @@ test.describe('actions schema settings', () => {
|
||||
await mockPage(oneFormAndOneTableWithUsers).goto();
|
||||
|
||||
const openPopup = async () => {
|
||||
if (!(await page.getByLabel('action-Action-Save record-').isVisible())) {
|
||||
if (!(await page.getByLabel('action-Action-Submit-').isVisible())) {
|
||||
await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-users').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize right' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Save record' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Submit' }).click();
|
||||
}
|
||||
|
||||
await page.getByLabel('action-Action-Save record-').hover();
|
||||
await page.getByLabel('designer-schema-settings-Action-actionSettings:saveRecord-users').hover();
|
||||
await page.getByLabel('action-Action-Submit-').hover();
|
||||
await page.getByLabel('designer-schema-settings-Action-actionSettings:createSubmit-users').hover();
|
||||
await page.getByRole('menuitem', { name: 'Assign field values' }).click();
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
if (!(await page.getByLabel('block-item-AssignedField-').getByRole('textbox').isVisible())) {
|
||||
await page.getByLabel('schema-initializer-Grid-assignFieldValuesForm:configureFields-users').hover();
|
||||
await page.getByRole('menuitem', { name: 'Nickname' }).click();
|
||||
@ -419,8 +419,7 @@ test.describe('actions schema settings', () => {
|
||||
};
|
||||
|
||||
const expectNewValue = async (value: string) => {
|
||||
await page.getByLabel('action-Action-Save record-').click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-').click();
|
||||
await page.getByLabel('action-Action-Refresh-refresh').click();
|
||||
await expect(page.getByLabel('block-item-CardItem-users-table').getByText(value)).toBeVisible();
|
||||
};
|
||||
@ -431,9 +430,9 @@ test.describe('actions schema settings', () => {
|
||||
// 2. 将 Nickname 字段的值设置为 `123456`
|
||||
await page.getByLabel('block-item-AssignedField-').getByRole('textbox').click();
|
||||
await page.getByLabel('block-item-AssignedField-').getByRole('textbox').fill('123456');
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
await page.getByRole('button', { name: 'Submit', exact: true }).click();
|
||||
|
||||
// 3. 保存后点击 Save record 按钮,然后刷新表格,应该显示一条 Nickname 为 “123456” 的记录
|
||||
// 3. 保存后点击 Submit 按钮,然后刷新表格,应该显示一条 Nickname 为 “123456” 的记录
|
||||
await expectNewValue('123456');
|
||||
|
||||
// 4. 再次打开 Assign field values 配置弹窗,这次为 Nickname 设置一个变量值(Current role)
|
||||
@ -447,9 +446,9 @@ test.describe('actions schema settings', () => {
|
||||
'Current form',
|
||||
]);
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Current role' }).click();
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
await page.getByRole('button', { name: 'Submit', exact: true }).click();
|
||||
|
||||
// 5. 保存后点击 Save record 按钮,然后刷新表格,应该显示一条 Nickname 为 “root” 的记录
|
||||
// 5. 保存后点击 Submit 按钮,然后刷新表格,应该显示一条 Nickname 为 “root” 的记录
|
||||
await expectNewValue('root');
|
||||
});
|
||||
});
|
||||
|
@ -741,6 +741,7 @@ test.describe('creation form block schema settings', () => {
|
||||
await page.getByLabel('action-Action-Add new-create-users-table').click();
|
||||
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: 'Current collection' }).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);
|
||||
|
@ -16,6 +16,7 @@ export interface CreateFormBlockUISchemaOptions {
|
||||
collectionName?: string;
|
||||
association?: string;
|
||||
templateSchema?: ISchema;
|
||||
/** 表示是通过 Other collections 选项创建的区块(由于历史遗留问题,这里的命名暂不做更改) */
|
||||
isCusomeizeCreate?: boolean;
|
||||
}
|
||||
|
||||
|
@ -9,97 +9,39 @@
|
||||
|
||||
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
|
||||
const commonOptions = {
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
name: 'submit',
|
||||
title: '{{t("Submit")}}',
|
||||
Component: 'CreateSubmitActionInitializer',
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'customRequest',
|
||||
title: '{{t("Custom request")}}',
|
||||
Component: 'CustomRequestInitializer',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `createFormActionInitializers` instead
|
||||
*/
|
||||
export const createFormActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'CreateFormActionInitializers',
|
||||
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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
createFormActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -18,11 +18,6 @@ export const formActionInitializers = new SchemaInitializer({
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
name: 'enableActions',
|
||||
title: '{{t("Enable actions")}}',
|
||||
children: [
|
||||
{
|
||||
name: 'submit',
|
||||
title: '{{t("Submit")}}',
|
||||
@ -31,28 +26,10 @@ export const formActionInitializers = new SchemaInitializer({
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
name: 'customize',
|
||||
type: 'subMenu',
|
||||
title: '{{t("Customize")}}',
|
||||
children: [
|
||||
{
|
||||
name: 'saveRecord',
|
||||
title: '{{t("Save record")}}',
|
||||
Component: 'SaveRecordActionInitializer',
|
||||
},
|
||||
{
|
||||
name: 'customRequest',
|
||||
title: '{{t("Custom request")}}',
|
||||
Component: 'CustomRequestInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -11,6 +11,37 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-init
|
||||
import { AssociatedFields, ParentCollectionFields } from '../../../../schema-initializer/buttons/FormItemInitializers';
|
||||
import { gridRowColWrap, useFormItemInitializerFields } from '../../../../schema-initializer/utils';
|
||||
|
||||
const commonOptions = {
|
||||
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',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `formItemInitializers` instead
|
||||
@ -18,67 +49,13 @@ import { gridRowColWrap, useFormItemInitializerFields } from '../../../../schema
|
||||
*/
|
||||
export const formItemInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'FormItemInitializers',
|
||||
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',
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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',
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
formItemInitializers_deprecated,
|
||||
);
|
||||
|
@ -8,10 +8,13 @@
|
||||
*/
|
||||
|
||||
import { useParentRecordCommon } from '../../../useParentRecordCommon';
|
||||
import { useHiddenForInherit } from './useHiddenForInherit';
|
||||
|
||||
export function useCreateFormBlockDecoratorProps(props) {
|
||||
let parentRecord;
|
||||
|
||||
const { hidden } = useHiddenForInherit(props);
|
||||
|
||||
// association 的值是固定不变的,所以这里可以使用 hooks
|
||||
if (props.association) {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
@ -20,5 +23,6 @@ export function useCreateFormBlockDecoratorProps(props) {
|
||||
|
||||
return {
|
||||
parentRecord,
|
||||
hidden,
|
||||
};
|
||||
}
|
||||
|
@ -9,11 +9,14 @@
|
||||
|
||||
import { useParamsFromRecord } from '../../../../../block-provider/BlockProvider';
|
||||
import { useDetailsParentRecord } from '../../details-single/hooks/useDetailsDecoratorProps';
|
||||
import { useHiddenForInherit } from './useHiddenForInherit';
|
||||
|
||||
export function useEditFormBlockDecoratorProps(props) {
|
||||
const params = useFormBlockParams();
|
||||
let parentRecord;
|
||||
|
||||
const { hidden } = useHiddenForInherit(props);
|
||||
|
||||
// association 的值是固定不变的,所以这里可以使用 hooks
|
||||
if (props.association) {
|
||||
// 复用详情区块的 sourceId 获取逻辑
|
||||
@ -24,6 +27,7 @@ export function useEditFormBlockDecoratorProps(props) {
|
||||
return {
|
||||
params,
|
||||
parentRecord,
|
||||
hidden,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { useIsDetailBlock } from '../../../../../block-provider/FormBlockProvider';
|
||||
import { useCollection } from '../../../../../data-source/collection/CollectionProvider';
|
||||
import { useRecord } from '../../../../../record-provider';
|
||||
import { useDesignable } from '../../../../../schema-component/hooks/useDesignable';
|
||||
|
||||
/**
|
||||
* 用于在继承表的场景下,隐藏区块。
|
||||
* 具体文档:https://nocobase.feishu.cn/docx/A3L9dNZhnoMBjRxVciBcFzwLnae
|
||||
*/
|
||||
export const useHiddenForInherit = (props) => {
|
||||
const record = useRecord();
|
||||
const { collection, isCusomeizeCreate, hidden } = props;
|
||||
const { __collection } = record;
|
||||
const currentCollection = useCollection();
|
||||
const { designable } = useDesignable();
|
||||
const isDetailBlock = useIsDetailBlock();
|
||||
|
||||
if (!currentCollection) {
|
||||
return {
|
||||
hidden: hidden || false,
|
||||
};
|
||||
}
|
||||
|
||||
let detailFlag = false;
|
||||
if (isDetailBlock) {
|
||||
detailFlag = true;
|
||||
if (!designable && __collection) {
|
||||
detailFlag = __collection === collection;
|
||||
}
|
||||
}
|
||||
const createFlag =
|
||||
(currentCollection.name === (collection?.name || collection) && !isDetailBlock) ||
|
||||
!currentCollection.name ||
|
||||
!collection;
|
||||
|
||||
return {
|
||||
hidden: hidden || (!detailFlag && !createFlag && !isCusomeizeCreate),
|
||||
};
|
||||
};
|
@ -7,7 +7,6 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
export * from './CreateFormBlockInitializer';
|
||||
export * from './FormBlockInitializer';
|
||||
export * from './FormItemSchemaToolbar';
|
||||
export * from './RecordFormBlockInitializer';
|
||||
|
@ -9,119 +9,50 @@
|
||||
|
||||
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
|
||||
const commonOptions = {
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
name: 'submit',
|
||||
title: '{{t("Submit")}}',
|
||||
Component: 'UpdateSubmitActionInitializer',
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'popup',
|
||||
title: '{{t("Popup")}}',
|
||||
Component: 'PopupActionInitializer',
|
||||
useComponentProps() {
|
||||
return {
|
||||
'x-component': 'Action',
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
name: 'customRequest',
|
||||
title: '{{t("Custom request")}}',
|
||||
Component: 'CustomRequestInitializer',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `updateFormActionInitializers` instead
|
||||
*/
|
||||
export const updateFormActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'UpdateFormActionInitializers',
|
||||
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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
updateFormActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -10,167 +10,90 @@
|
||||
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
import { useCollection_deprecated } from '../../../../collection-manager';
|
||||
|
||||
const commonOptions = {
|
||||
title: "{{t('Configure actions')}}",
|
||||
icon: 'SettingOutlined',
|
||||
style: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `gridCardActionInitializers` instead
|
||||
*/
|
||||
export const gridCardActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'GridCardActionInitializers',
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
gridCardActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -7,10 +7,17 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { createBlockInPage, expect, oneEmptyGridCardBlock, test } from '@nocobase/test/e2e';
|
||||
import { Page, createBlockInPage, expect, oneEmptyGridCardBlock, test } from '@nocobase/test/e2e';
|
||||
import { oneEmptyTableWithUsers } from '../../details-multi/__e2e__/templatesOfBug';
|
||||
import { oneGridCardWithInheritFields } from './templatesOfBug';
|
||||
|
||||
const deleteButton = async (page: Page, name: string) => {
|
||||
await page.getByRole('button', { name }).hover();
|
||||
await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
};
|
||||
|
||||
test.describe('where grid card block can be added', () => {
|
||||
test('page', async ({ page, mockPage }) => {
|
||||
await mockPage().goto();
|
||||
@ -63,24 +70,15 @@ test.describe('configure global actions', () => {
|
||||
await page.getByRole('menuitem', { name: 'Add new' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Refresh' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Filter' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible();
|
||||
|
||||
// delete buttons
|
||||
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();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).not.toBeChecked();
|
||||
await deleteButton(page, 'Filter');
|
||||
await deleteButton(page, 'Add new');
|
||||
await deleteButton(page, 'Refresh');
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Filter' })).not.toBeVisible();
|
||||
@ -100,24 +98,15 @@ test.describe('configure item actions', () => {
|
||||
await page.getByRole('menuitem', { name: 'Edit' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByLabel('action-Action.Link-View-view-general-grid-card').first()).toBeVisible();
|
||||
await expect(page.getByLabel('action-Action.Link-Edit-update-general-grid-card').first()).toBeVisible();
|
||||
await expect(page.getByLabel('action-Action.Link-Delete-destroy-general-grid-card').first()).toBeVisible();
|
||||
|
||||
// delete buttons
|
||||
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();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked();
|
||||
await deleteButton(page, 'View');
|
||||
await deleteButton(page, 'Edit');
|
||||
await deleteButton(page, 'Delete');
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByLabel('action-Action.Link-View-view-general-grid-card').first()).not.toBeVisible();
|
||||
@ -131,7 +120,6 @@ test.describe('configure item actions', () => {
|
||||
await nocoPage.goto();
|
||||
|
||||
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();
|
||||
|
||||
|
@ -10,205 +10,98 @@
|
||||
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
import { useCollection_deprecated } from '../../../../collection-manager';
|
||||
|
||||
const commonOptions = {
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
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: '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';
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `gridCardItemActionInitializers` instead
|
||||
*/
|
||||
export const gridCardItemActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'GridCardItemActionInitializers',
|
||||
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';
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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';
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
gridCardItemActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -10,6 +10,81 @@
|
||||
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
import { useCollection_deprecated } from '../../../../collection-manager';
|
||||
|
||||
const commonOptions = {
|
||||
title: "{{t('Configure actions')}}",
|
||||
icon: 'SettingOutlined',
|
||||
style: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `listActionInitializers` instead
|
||||
@ -17,169 +92,13 @@ import { useCollection_deprecated } from '../../../../collection-manager';
|
||||
*/
|
||||
export const listActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'ListActionInitializers',
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
listActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -7,9 +7,16 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { createBlockInPage, expect, oneEmptyListBlock, test } from '@nocobase/test/e2e';
|
||||
import { Page, createBlockInPage, expect, oneEmptyListBlock, test } from '@nocobase/test/e2e';
|
||||
import { oneEmptyTableWithUsers } from '../../details-multi/__e2e__/templatesOfBug';
|
||||
|
||||
const deleteButton = async (page: Page, name: string) => {
|
||||
await page.getByRole('button', { name }).hover();
|
||||
await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
};
|
||||
|
||||
test.describe('where list block can be added', () => {
|
||||
test('page', async ({ page, mockPage }) => {
|
||||
await mockPage().goto();
|
||||
@ -60,24 +67,15 @@ test.describe('configure global actions', () => {
|
||||
await page.getByRole('menuitem', { name: 'Add new' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Refresh' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Filter' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible();
|
||||
|
||||
// delete buttons
|
||||
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();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).not.toBeChecked();
|
||||
await deleteButton(page, 'Filter');
|
||||
await deleteButton(page, 'Add new');
|
||||
await deleteButton(page, 'Refresh');
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Filter' })).not.toBeVisible();
|
||||
@ -97,24 +95,15 @@ test.describe('configure item actions', () => {
|
||||
await page.getByRole('menuitem', { name: 'Edit' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByLabel('action-Action.Link-View-view-general-list').first()).toBeVisible();
|
||||
await expect(page.getByLabel('action-Action.Link-Edit-update-general-list').first()).toBeVisible();
|
||||
await expect(page.getByLabel('action-Action.Link-Delete-destroy-general-list').first()).toBeVisible();
|
||||
|
||||
// delete buttons
|
||||
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();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked();
|
||||
await deleteButton(page, 'View');
|
||||
await deleteButton(page, 'Edit');
|
||||
await deleteButton(page, 'Delete');
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByLabel('action-Action.Link-View-view-general-list').first()).not.toBeVisible();
|
||||
@ -128,7 +117,6 @@ test.describe('configure item actions', () => {
|
||||
await nocoPage.goto();
|
||||
|
||||
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();
|
||||
|
||||
|
@ -10,205 +10,98 @@
|
||||
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
import { useCollection_deprecated } from '../../../../collection-manager';
|
||||
|
||||
const commonOptions = {
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
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: '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';
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `listItemActionInitializers` instead
|
||||
*/
|
||||
export const listItemActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'ListItemActionInitializers',
|
||||
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';
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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';
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
listItemActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -10,6 +10,13 @@
|
||||
import { Page, expect, test } from '@nocobase/test/e2e';
|
||||
import { createTable } from './utils';
|
||||
|
||||
const deleteButton = async (page: Page, name: string) => {
|
||||
await page.getByRole('button', { name }).hover();
|
||||
await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
};
|
||||
|
||||
test.describe('where table data selector can be added', () => {
|
||||
test('popup', async ({ page, mockPage }) => {
|
||||
await createTable({ page, mockPage, fieldName: 'manyToOne' });
|
||||
@ -35,11 +42,6 @@ test.describe('configure actions', () => {
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Refresh' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Filter' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible();
|
||||
@ -47,16 +49,10 @@ test.describe('configure actions', () => {
|
||||
await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible();
|
||||
|
||||
// delete buttons
|
||||
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();
|
||||
await page.getByRole('menuitem', { name: 'Refresh' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).not.toBeChecked();
|
||||
await deleteButton(page, 'Filter');
|
||||
await deleteButton(page, 'Add new');
|
||||
await deleteButton(page, 'Delete');
|
||||
await deleteButton(page, 'Refresh');
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Filter' })).not.toBeVisible();
|
||||
@ -69,7 +65,6 @@ test.describe('configure actions', () => {
|
||||
await createTable({ page, mockPage, fieldName: 'manyToOne' });
|
||||
|
||||
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();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import { MenuOutlined } from '@ant-design/icons';
|
||||
import { ISchema, useFieldSchema, useField } from '@formily/react';
|
||||
import { ISchema, useField, useFieldSchema } from '@formily/react';
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -18,10 +18,10 @@ import { SchemaInitializerActionModal } from '../../../../application/schema-ini
|
||||
import { SchemaInitializerItem } from '../../../../application/schema-initializer/components/SchemaInitializerItem';
|
||||
import { useSchemaInitializer } from '../../../../application/schema-initializer/context';
|
||||
import { useCollection_deprecated } from '../../../../collection-manager';
|
||||
import { SelectWithTitle } from '../../../../common/SelectWithTitle';
|
||||
import { useDataBlockProps } from '../../../../data-source';
|
||||
import { createDesignable, useDesignable } from '../../../../schema-component';
|
||||
import { useGetAriaLabelOfDesigner } from '../../../../schema-settings/hooks/useGetAriaLabelOfDesigner';
|
||||
import { SelectWithTitle } from '../../../../common/SelectWithTitle';
|
||||
|
||||
export const Resizable = () => {
|
||||
const { t } = useTranslation();
|
||||
@ -112,6 +112,7 @@ export const SchemaSettingsFixed = () => {
|
||||
</SchemaInitializerItem>
|
||||
);
|
||||
};
|
||||
|
||||
const commonOptions = {
|
||||
insertPosition: 'beforeEnd',
|
||||
useInsert: function useInsert() {
|
||||
@ -153,11 +154,6 @@ const commonOptions = {
|
||||
);
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
name: 'actions',
|
||||
title: '{{t("Enable actions")}}',
|
||||
children: [
|
||||
{
|
||||
type: 'item',
|
||||
title: '{{t("View")}}',
|
||||
@ -237,17 +233,6 @@ const commonOptions = {
|
||||
return collection.tree && treeTable;
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
type: 'subMenu',
|
||||
title: '{{t("Customize")}}',
|
||||
name: 'customize',
|
||||
children: [
|
||||
{
|
||||
type: 'item',
|
||||
title: '{{t("Popup")}}',
|
||||
@ -276,23 +261,24 @@ const commonOptions = {
|
||||
return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql';
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'divider2',
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
sort: 100,
|
||||
},
|
||||
{
|
||||
name: 'fixed',
|
||||
title: 't("Fixed")',
|
||||
type: 'item',
|
||||
Component: SchemaSettingsFixed,
|
||||
sort: 100,
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
name: 'columnWidth',
|
||||
title: 't("Column width")',
|
||||
Component: Resizable,
|
||||
sort: 100,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -11,6 +11,79 @@ import { useFieldSchema } from '@formily/react';
|
||||
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
import { useCollection_deprecated } from '../../../../collection-manager/hooks/useCollection_deprecated';
|
||||
|
||||
const commonOptions = {
|
||||
title: "{{t('Configure actions')}}",
|
||||
icon: 'SettingOutlined',
|
||||
style: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
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;
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `tableActionInitializers` instead
|
||||
@ -18,231 +91,13 @@ import { useCollection_deprecated } from '../../../../collection-manager/hooks/u
|
||||
*/
|
||||
export const tableActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'TableActionInitializers',
|
||||
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;
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
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;
|
||||
},
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
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;
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
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;
|
||||
},
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
tableActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -7,9 +7,16 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { expect, oneEmptyTable, test } from '@nocobase/test/e2e';
|
||||
import { Page, expect, oneEmptyTable, test } from '@nocobase/test/e2e';
|
||||
import { oneTableWithInheritFields } from './templatesOfBug';
|
||||
|
||||
const deleteButton = async (page: Page, name: string) => {
|
||||
await page.getByLabel(`action-Action.Link-${name}-`).hover();
|
||||
await page.getByLabel(`action-Action.Link-${name}-`).getByLabel('designer-schema-settings-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
};
|
||||
|
||||
test.describe('configure columns', () => {
|
||||
// 该用例在 CI 并发环境下容易报错,原因未知,通过增加重试次数可以解决
|
||||
test.describe.configure({ retries: process.env.CI ? 4 : 0 });
|
||||
@ -135,11 +142,6 @@ test.describe('configure actions column', () => {
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Duplicate' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Duplicate' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByLabel('action-Action.Link-View-view-t_unp4scqamw9-table-0')).toBeVisible();
|
||||
await expect(page.getByLabel('action-Action.Link-Edit-update-t_unp4scqamw9-table-0')).toBeVisible();
|
||||
@ -147,17 +149,10 @@ test.describe('configure actions column', () => {
|
||||
await expect(page.getByLabel('action-Action.Link-Duplicate-duplicate-t_unp4scqamw9-table-0')).toBeVisible();
|
||||
|
||||
// delete view & Edit & Delete & Duplicate ------------------------------------------------------------
|
||||
await page.getByText('Actions', { exact: true }).hover();
|
||||
await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-t_unp4scqamw9').hover();
|
||||
await page.getByRole('menuitem', { name: 'View' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Edit' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Duplicate' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Duplicate' }).getByRole('switch')).not.toBeChecked();
|
||||
await deleteButton(page, 'View');
|
||||
await deleteButton(page, 'Edit');
|
||||
await deleteButton(page, 'Delete');
|
||||
await deleteButton(page, 'Duplicate');
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByLabel('action-Action.Link-View-view-t_unp4scqamw9-table-0')).not.toBeVisible();
|
||||
@ -168,7 +163,6 @@ test.describe('configure actions column', () => {
|
||||
// add custom action ------------------------------------------------------------
|
||||
await page.getByText('Actions', { exact: true }).hover();
|
||||
await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-t_unp4scqamw9').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize' }).hover();
|
||||
|
||||
await page.getByRole('menuitem', { name: 'Popup' }).click();
|
||||
// 此时二级菜单,不应该关闭,可以继续点击?
|
||||
|
@ -7,9 +7,16 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { createBlockInPage, expect, oneEmptyTable, test } from '@nocobase/test/e2e';
|
||||
import { Page, createBlockInPage, expect, oneEmptyTable, test } from '@nocobase/test/e2e';
|
||||
import { T3686, T4005 } from './templatesOfBug';
|
||||
|
||||
const deleteButton = async (page: Page, name: string) => {
|
||||
await page.getByRole('button', { name }).hover();
|
||||
await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
};
|
||||
|
||||
test.describe('where table block can be added', () => {
|
||||
test('page', async ({ page, mockPage }) => {
|
||||
await mockPage().goto();
|
||||
@ -116,11 +123,6 @@ test.describe('configure actions', () => {
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Refresh' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Filter' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible();
|
||||
@ -128,16 +130,10 @@ test.describe('configure actions', () => {
|
||||
await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible();
|
||||
|
||||
// delete buttons
|
||||
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();
|
||||
await page.getByRole('menuitem', { name: 'Refresh' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).not.toBeChecked();
|
||||
await deleteButton(page, 'Filter');
|
||||
await deleteButton(page, 'Add new');
|
||||
await deleteButton(page, 'Delete');
|
||||
await deleteButton(page, 'Refresh');
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Filter' })).not.toBeVisible();
|
||||
@ -145,15 +141,4 @@ test.describe('configure actions', () => {
|
||||
await expect(page.getByRole('button', { name: 'Delete' })).not.toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Refresh' })).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('customize: add record', async ({ page, mockPage }) => {
|
||||
await mockPage(oneEmptyTable).goto();
|
||||
|
||||
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();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Add record' })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
@ -19,6 +19,27 @@ import {
|
||||
} from '@nocobase/test/e2e';
|
||||
import { T3843, oneTableWithColumnFixed, oneTableWithUpdateRecord } from './templatesOfBug';
|
||||
|
||||
const addSomeCustomActions = async (page: Page) => {
|
||||
// 先删除掉之前的 actions
|
||||
const deleteAction = async (name: string) => {
|
||||
await page.getByLabel(`action-Action.Link-${name}-`).hover();
|
||||
await page.getByRole('button', { name: 'designer-schema-settings-Action.Link-Action.Designer-general' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
};
|
||||
|
||||
await deleteAction('View');
|
||||
await deleteAction('Edit');
|
||||
await deleteAction('Delete');
|
||||
await deleteAction('Duplicate');
|
||||
|
||||
// 再增加两个自定义的 actions
|
||||
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: 'Popup' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Update record' }).click();
|
||||
};
|
||||
|
||||
test.describe('actions schema settings', () => {
|
||||
test.describe('add new', () => {
|
||||
const showMenu = async (page: Page) => {
|
||||
@ -295,21 +316,6 @@ test.describe('actions schema settings', () => {
|
||||
});
|
||||
|
||||
test.describe('popup', () => {
|
||||
const addSomeCustomActions = async (page: Page) => {
|
||||
// 先删除掉之前的 actions
|
||||
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();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Duplicate' }).click();
|
||||
|
||||
// 再增加两个自定义的 actions
|
||||
await page.getByRole('menuitem', { name: 'Customize' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Popup' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Update record' }).click();
|
||||
};
|
||||
|
||||
const showMenu = async (page: Page) => {
|
||||
await page.getByLabel('action-Action.Link-Popup-customize:popup-general-table-0').hover();
|
||||
await page
|
||||
@ -352,21 +358,6 @@ test.describe('actions schema settings', () => {
|
||||
});
|
||||
|
||||
test.describe('update record', () => {
|
||||
const addSomeCustomActions = async (page: Page) => {
|
||||
// 先删除掉之前的 actions
|
||||
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();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Duplicate' }).click();
|
||||
|
||||
// 再增加两个自定义的 actions
|
||||
await page.getByRole('menuitem', { name: 'Customize' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Popup' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Update record' }).click();
|
||||
};
|
||||
|
||||
const showMenu = async (page: Page) => {
|
||||
await page.getByLabel('action-Action.Link-Update record-customize:update-general-table-0').hover();
|
||||
await page
|
||||
@ -403,7 +394,6 @@ test.describe('actions schema settings', () => {
|
||||
if (!(await page.getByLabel('action-Action.Link-Update record-customize:update-users2-table-0').isVisible())) {
|
||||
await page.getByRole('button', { name: 'Actions', exact: true }).hover();
|
||||
await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-users2').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize right' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Update record' }).click();
|
||||
}
|
||||
|
||||
@ -473,7 +463,8 @@ test.describe('actions schema settings', () => {
|
||||
await page.getByRole('menuitem', { name: 'Add new' }).click();
|
||||
await page.getByRole('button', { name: 'Add new' }).click();
|
||||
await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-treeCollection').hover();
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).click();
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Current collection' }).click();
|
||||
await page.mouse.move(300, 0);
|
||||
await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-treeCollection').hover();
|
||||
await page.getByRole('menuitem', { name: 'Submit' }).click();
|
||||
@ -500,7 +491,8 @@ test.describe('actions schema settings', () => {
|
||||
position: { x: 5, y: 5 }, // 防止按钮被遮挡
|
||||
});
|
||||
await page.getByLabel('schema-initializer-Grid-popup').hover();
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).click();
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Current collection' }).click();
|
||||
await page.mouse.move(300, 0);
|
||||
await page.getByLabel('schema-initializer-Grid-form:').hover();
|
||||
await page.getByRole('menuitem', { name: 'Parent', exact: true }).click();
|
||||
|
@ -8,6 +8,28 @@
|
||||
*/
|
||||
|
||||
import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
const commonOptions = {
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
name: 'filter',
|
||||
title: '{{t("Filter")}}',
|
||||
Component: 'CreateFilterActionInitializer',
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'reset',
|
||||
title: '{{t("Reset")}}',
|
||||
Component: 'CreateResetActionInitializer',
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
@ -16,65 +38,13 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-init
|
||||
*/
|
||||
export const filterFormActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'FilterFormActionInitializers',
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Enable actions")}}',
|
||||
name: 'enableActions',
|
||||
children: [
|
||||
{
|
||||
name: 'filter',
|
||||
title: '{{t("Filter")}}',
|
||||
Component: 'CreateFilterActionInitializer',
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'reset',
|
||||
title: '{{t("Reset")}}',
|
||||
Component: 'CreateResetActionInitializer',
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const filterFormActionInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'filterForm:configureActions',
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Enable actions")}}',
|
||||
name: 'enableActions',
|
||||
children: [
|
||||
{
|
||||
name: 'filter',
|
||||
title: '{{t("Filter")}}',
|
||||
Component: 'CreateFilterActionInitializer',
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'reset',
|
||||
title: '{{t("Reset")}}',
|
||||
Component: 'CreateResetActionInitializer',
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
filterFormActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -7,9 +7,16 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { createBlockInPage, expect, oneEmptyFilterFormBlock, test } from '@nocobase/test/e2e';
|
||||
import { Page, createBlockInPage, expect, oneEmptyFilterFormBlock, test } from '@nocobase/test/e2e';
|
||||
import { oneFilterFormWithInherit } from './templatesOfBug';
|
||||
|
||||
const deleteButton = async (page: Page, name: string) => {
|
||||
await page.getByLabel(`action-Action-${name}-`).hover();
|
||||
await page.getByLabel(`action-Action-${name}-`).getByLabel('designer-schema-settings-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
};
|
||||
|
||||
test.describe('where filter form block can be added', () => {
|
||||
test('page', async ({ page, mockPage }) => {
|
||||
await mockPage().goto();
|
||||
@ -104,21 +111,13 @@ test.describe('configure actions', () => {
|
||||
await page.getByRole('menuitem', { name: 'Filter' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Reset' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Reset' }).getByRole('switch')).toBeChecked();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByLabel('action-Action-Filter-submit-general-filter-form')).toBeVisible();
|
||||
await expect(page.getByLabel('action-Action-Reset-general-filter-form')).toBeVisible();
|
||||
|
||||
// delete buttons
|
||||
await page.getByLabel('schema-initializer-ActionBar-filterForm:configureActions-general').hover();
|
||||
await page.getByRole('menuitem', { name: 'Filter' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Reset' }).click();
|
||||
|
||||
await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked();
|
||||
await expect(page.getByRole('menuitem', { name: 'Reset' }).getByRole('switch')).not.toBeChecked();
|
||||
|
||||
await deleteButton(page, 'Filter');
|
||||
await deleteButton(page, 'Reset');
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByLabel('action-Action-Filter-submit-general-filter-form')).not.toBeVisible();
|
||||
await expect(page.getByLabel('action-Action-Reset-general-filter-form')).not.toBeVisible();
|
||||
|
@ -14,73 +14,50 @@ import {
|
||||
} from '../../../../schema-initializer/buttons/FormItemInitializers';
|
||||
import { gridRowColWrap, useFilterFormItemInitializerFields } from '../../../../schema-initializer/utils';
|
||||
|
||||
const commonOptions = {
|
||||
wrap: gridRowColWrap,
|
||||
icon: 'SettingOutlined',
|
||||
title: '{{t("Configure fields")}}',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
name: 'displayFields',
|
||||
title: '{{t("Display fields")}}',
|
||||
useChildren: useFilterFormItemInitializerFields,
|
||||
},
|
||||
{
|
||||
name: 'parentCollectionFields',
|
||||
Component: FilterParentCollectionFields,
|
||||
},
|
||||
{
|
||||
name: 'associationFields',
|
||||
Component: FilterAssociatedFields,
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
title: '{{t("Add text")}}',
|
||||
Component: 'MarkdownFormItemInitializer',
|
||||
name: 'addText',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `filterFormItemInitializers` instead
|
||||
*/
|
||||
export const filterFormItemInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'FilterFormItemInitializers',
|
||||
wrap: gridRowColWrap,
|
||||
icon: 'SettingOutlined',
|
||||
title: '{{t("Configure fields")}}',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
name: 'displayFields',
|
||||
title: '{{t("Display fields")}}',
|
||||
useChildren: useFilterFormItemInitializerFields,
|
||||
},
|
||||
{
|
||||
name: 'parentCollectionFields',
|
||||
Component: FilterParentCollectionFields,
|
||||
},
|
||||
{
|
||||
name: 'associationFields',
|
||||
Component: FilterAssociatedFields,
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
title: '{{t("Add text")}}',
|
||||
Component: 'MarkdownFormItemInitializer',
|
||||
name: 'addText',
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const filterFormItemInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'filterForm:configureFields',
|
||||
wrap: gridRowColWrap,
|
||||
icon: 'SettingOutlined',
|
||||
title: '{{t("Configure fields")}}',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
name: 'displayFields',
|
||||
title: '{{t("Display fields")}}',
|
||||
useChildren: useFilterFormItemInitializerFields,
|
||||
},
|
||||
{
|
||||
name: 'parentCollectionFields',
|
||||
Component: FilterParentCollectionFields,
|
||||
},
|
||||
{
|
||||
name: 'associationFields',
|
||||
Component: FilterAssociatedFields,
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
title: '{{t("Add text")}}',
|
||||
Component: 'MarkdownFormItemInitializer',
|
||||
name: 'addText',
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
filterFormItemInitializers_deprecated,
|
||||
);
|
||||
|
@ -10,149 +10,88 @@
|
||||
import { CompatibleSchemaInitializer } from '../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
import { gridRowColWrap } from '../../schema-initializer/utils';
|
||||
|
||||
const commonOptions = {
|
||||
title: '{{t("Add block")}}',
|
||||
icon: 'PlusOutlined',
|
||||
wrap: gridRowColWrap,
|
||||
items: [
|
||||
{
|
||||
name: 'dataBlocks',
|
||||
title: '{{t("Data blocks")}}',
|
||||
type: 'itemGroup',
|
||||
children: [
|
||||
{
|
||||
name: 'table',
|
||||
title: '{{t("Table")}}',
|
||||
Component: 'TableBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'form',
|
||||
title: '{{t("Form")}}',
|
||||
Component: 'FormBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'details',
|
||||
title: '{{t("Details")}}',
|
||||
Component: 'DetailsBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'list',
|
||||
title: '{{t("List")}}',
|
||||
Component: 'ListBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'gridCard',
|
||||
title: '{{t("Grid Card")}}',
|
||||
Component: 'GridCardBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'filterBlocks',
|
||||
title: '{{t("Filter blocks")}}',
|
||||
type: 'itemGroup',
|
||||
children: [
|
||||
{
|
||||
name: 'filterForm',
|
||||
title: '{{t("Form")}}',
|
||||
Component: 'FilterFormBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'filterCollapse',
|
||||
title: '{{t("Collapse")}}',
|
||||
Component: 'FilterCollapseBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'otherBlocks',
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Other blocks")}}',
|
||||
children: [
|
||||
{
|
||||
name: 'markdown',
|
||||
title: '{{t("Markdown")}}',
|
||||
Component: 'MarkdownBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `blockInitializers` instead
|
||||
*/
|
||||
export const blockInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'BlockInitializers',
|
||||
title: '{{t("Add block")}}',
|
||||
icon: 'PlusOutlined',
|
||||
wrap: gridRowColWrap,
|
||||
items: [
|
||||
{
|
||||
name: 'dataBlocks',
|
||||
title: '{{t("Data blocks")}}',
|
||||
type: 'itemGroup',
|
||||
children: [
|
||||
{
|
||||
name: 'table',
|
||||
title: '{{t("Table")}}',
|
||||
Component: 'TableBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'form',
|
||||
title: '{{t("Form")}}',
|
||||
Component: 'FormBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'details',
|
||||
title: '{{t("Details")}}',
|
||||
Component: 'DetailsBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'list',
|
||||
title: '{{t("List")}}',
|
||||
Component: 'ListBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'gridCard',
|
||||
title: '{{t("Grid Card")}}',
|
||||
Component: 'GridCardBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'filterBlocks',
|
||||
title: '{{t("Filter blocks")}}',
|
||||
type: 'itemGroup',
|
||||
children: [
|
||||
{
|
||||
name: 'filterForm',
|
||||
title: '{{t("Form")}}',
|
||||
Component: 'FilterFormBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'filterCollapse',
|
||||
title: '{{t("Collapse")}}',
|
||||
Component: 'FilterCollapseBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'otherBlocks',
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Other blocks")}}',
|
||||
children: [
|
||||
{
|
||||
name: 'markdown',
|
||||
title: '{{t("Markdown")}}',
|
||||
Component: 'MarkdownBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const blockInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'page:addBlock',
|
||||
title: '{{t("Add block")}}',
|
||||
icon: 'PlusOutlined',
|
||||
wrap: gridRowColWrap,
|
||||
items: [
|
||||
{
|
||||
name: 'dataBlocks',
|
||||
title: '{{t("Data blocks")}}',
|
||||
type: 'itemGroup',
|
||||
children: [
|
||||
{
|
||||
name: 'table',
|
||||
title: '{{t("Table")}}',
|
||||
Component: 'TableBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'form',
|
||||
title: '{{t("Form")}}',
|
||||
Component: 'FormBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'details',
|
||||
title: '{{t("Details")}}',
|
||||
Component: 'DetailsBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'list',
|
||||
title: '{{t("List")}}',
|
||||
Component: 'ListBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'gridCard',
|
||||
title: '{{t("Grid Card")}}',
|
||||
Component: 'GridCardBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'filterBlocks',
|
||||
title: '{{t("Filter blocks")}}',
|
||||
type: 'itemGroup',
|
||||
children: [
|
||||
{
|
||||
name: 'filterForm',
|
||||
title: '{{t("Form")}}',
|
||||
Component: 'FilterFormBlockInitializer',
|
||||
},
|
||||
{
|
||||
name: 'filterCollapse',
|
||||
title: '{{t("Collapse")}}',
|
||||
Component: 'FilterCollapseBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'otherBlocks',
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Other blocks")}}',
|
||||
children: [
|
||||
{
|
||||
name: 'markdown',
|
||||
title: '{{t("Markdown")}}',
|
||||
Component: 'MarkdownBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
blockInitializers_deprecated,
|
||||
);
|
||||
|
@ -33,8 +33,9 @@ test.describe('where to open a popup and what can be added to it', () => {
|
||||
|
||||
// add blocks
|
||||
await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-general').hover();
|
||||
await page.getByText('Form').click();
|
||||
await page.getByText('Markdown').click();
|
||||
await page.getByText('Form').hover();
|
||||
await page.getByRole('menuitem', { name: 'Current collection' }).click();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { SchemaComponentContext, createDesignable } from '../..';
|
||||
import { useAPIClient } from '../../../api-client';
|
||||
import { useBlockRequestContext } from '../../../block-provider';
|
||||
import { mergeFilter } from '../../../filter-provider/utils';
|
||||
import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer';
|
||||
import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
@ -58,5 +58,5 @@ export const ActionBarAssociationFilterAction = (props) => {
|
||||
wrap: (s) => s,
|
||||
};
|
||||
|
||||
return <ActionInitializer {...newProps} schema={schema} />;
|
||||
return <ActionInitializerItem {...newProps} schema={schema} />;
|
||||
};
|
||||
|
@ -33,47 +33,37 @@ const ParentCollectionFields = () => {
|
||||
return <SchemaInitializerChildren>{res}</SchemaInitializerChildren>;
|
||||
};
|
||||
|
||||
const commonOptions = {
|
||||
wrap: gridRowColWrap,
|
||||
icon: 'SettingOutlined',
|
||||
title: '{{t("Configure fields")}}',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Configure fields")}}',
|
||||
name: 'configureFields',
|
||||
useChildren: useCustomFormItemInitializerFields,
|
||||
},
|
||||
{
|
||||
name: 'parentCollectionFields',
|
||||
Component: ParentCollectionFields,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `customFormItemInitializers` instead
|
||||
*/
|
||||
export const customFormItemInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'CustomFormItemInitializers',
|
||||
wrap: gridRowColWrap,
|
||||
icon: 'SettingOutlined',
|
||||
title: '{{t("Configure fields")}}',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Configure fields")}}',
|
||||
name: 'configureFields',
|
||||
useChildren: useCustomFormItemInitializerFields,
|
||||
},
|
||||
{
|
||||
name: 'parentCollectionFields',
|
||||
Component: ParentCollectionFields,
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const customFormItemInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'assignFieldValuesForm:configureFields',
|
||||
wrap: gridRowColWrap,
|
||||
icon: 'SettingOutlined',
|
||||
title: '{{t("Configure fields")}}',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Configure fields")}}',
|
||||
name: 'configureFields',
|
||||
useChildren: useCustomFormItemInitializerFields,
|
||||
},
|
||||
{
|
||||
name: 'parentCollectionFields',
|
||||
Component: ParentCollectionFields,
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
customFormItemInitializers_deprecated,
|
||||
);
|
||||
|
@ -170,13 +170,13 @@ function useRecordBlocks() {
|
||||
componentType: 'FormItem',
|
||||
createBlockSchema: ({ item, fromOthersInPopup }) => {
|
||||
if (fromOthersInPopup) {
|
||||
return createFormBlock({ item });
|
||||
return createFormBlock({ item, fromOthersInPopup });
|
||||
}
|
||||
createAssociationFormBlock({ item });
|
||||
},
|
||||
templateWrap: (templateSchema, { item, fromOthersInPopup }) => {
|
||||
if (fromOthersInPopup) {
|
||||
return templateWrapCollection(templateSchema, { item });
|
||||
return templateWrapCollection(templateSchema, { item, fromOthersInPopup });
|
||||
}
|
||||
templateWrap(templateSchema, { item });
|
||||
},
|
||||
|
@ -9,6 +9,39 @@
|
||||
|
||||
import { CompatibleSchemaInitializer } from '../../application/schema-initializer/CompatibleSchemaInitializer';
|
||||
|
||||
const commonOptions = {
|
||||
title: "{{t('Configure actions')}}",
|
||||
icon: 'SettingOutlined',
|
||||
style: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: "{{t('Enable actions')}}",
|
||||
name: 'enableActions',
|
||||
children: [
|
||||
{
|
||||
name: 'addNew',
|
||||
title: "{{t('Add new')}}",
|
||||
Component: 'CreateActionInitializer',
|
||||
schema: {
|
||||
'x-align': 'right',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
title: "{{t('Delete')}}",
|
||||
Component: 'BulkDestroyActionInitializer',
|
||||
schema: {
|
||||
'x-align': 'right',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `subTableActionInitializers` instead
|
||||
@ -16,71 +49,13 @@ import { CompatibleSchemaInitializer } from '../../application/schema-initialize
|
||||
*/
|
||||
export const subTableActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'SubTableActionInitializers',
|
||||
title: "{{t('Configure actions')}}",
|
||||
icon: 'SettingOutlined',
|
||||
style: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: "{{t('Enable actions')}}",
|
||||
name: 'enableActions',
|
||||
children: [
|
||||
{
|
||||
name: 'addNew',
|
||||
title: "{{t('Add new')}}",
|
||||
Component: 'CreateActionInitializer',
|
||||
schema: {
|
||||
'x-align': 'right',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
title: "{{t('Delete')}}",
|
||||
Component: 'BulkDestroyActionInitializer',
|
||||
schema: {
|
||||
'x-align': 'right',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const subTableActionInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'subTable:configureActions',
|
||||
title: "{{t('Configure actions')}}",
|
||||
icon: 'SettingOutlined',
|
||||
style: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: "{{t('Enable actions')}}",
|
||||
name: 'enableActions',
|
||||
children: [
|
||||
{
|
||||
name: 'addNew',
|
||||
title: "{{t('Add new')}}",
|
||||
Component: 'CreateActionInitializer',
|
||||
schema: {
|
||||
'x-align': 'right',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
title: "{{t('Delete')}}",
|
||||
Component: 'BulkDestroyActionInitializer',
|
||||
schema: {
|
||||
'x-align': 'right',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
subTableActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -14,7 +14,6 @@ import {
|
||||
createFormBlockInitializers,
|
||||
createFormBlockInitializers_deprecated,
|
||||
} from '../modules/actions/add-new/createFormBlockInitializers';
|
||||
import { CustomizeAddRecordActionInitializer } from '../modules/actions/add-record/CustomizeAddRecordActionInitializer';
|
||||
import {
|
||||
customizeCreateFormBlockInitializers,
|
||||
customizeCreateFormBlockInitializers_deprecated,
|
||||
@ -25,7 +24,6 @@ import { DisassociateActionInitializer } from '../modules/actions/disassociate/D
|
||||
import { ExpandableActionInitializer } from '../modules/actions/expand-collapse/ExpandableActionInitializer';
|
||||
import { FilterActionInitializer } from '../modules/actions/filter/FilterActionInitializer';
|
||||
import { RefreshActionInitializer } from '../modules/actions/refresh/RefreshActionInitializer';
|
||||
import { SaveRecordActionInitializer } from '../modules/actions/save-record/SaveRecordActionInitializer';
|
||||
import { CreateSubmitActionInitializer } from '../modules/actions/submit/CreateSubmitActionInitializer';
|
||||
import { UpdateSubmitActionInitializer } from '../modules/actions/submit/UpdateSubmitActionInitializer';
|
||||
import { UpdateRecordActionInitializer } from '../modules/actions/update-record/UpdateRecordActionInitializer';
|
||||
@ -47,7 +45,6 @@ import {
|
||||
readPrettyFormItemInitializers_deprecated,
|
||||
} from '../modules/blocks/data-blocks/details-single/ReadPrettyFormItemInitializers';
|
||||
import { RecordReadPrettyFormBlockInitializer } from '../modules/blocks/data-blocks/details-single/RecordReadPrettyFormBlockInitializer';
|
||||
import { CreateFormBlockInitializer } from '../modules/blocks/data-blocks/form/CreateFormBlockInitializer';
|
||||
import { FormBlockInitializer } from '../modules/blocks/data-blocks/form/FormBlockInitializer';
|
||||
import { RecordFormBlockInitializer } from '../modules/blocks/data-blocks/form/RecordFormBlockInitializer';
|
||||
import {
|
||||
@ -155,7 +152,6 @@ export class SchemaInitializerPlugin extends Plugin {
|
||||
...initializerComponents,
|
||||
...items,
|
||||
DestroyActionInitializer,
|
||||
CreateFormBlockInitializer,
|
||||
FormBlockInitializer,
|
||||
RecordFormBlockInitializer,
|
||||
TableBlockInitializer,
|
||||
@ -171,12 +167,10 @@ export class SchemaInitializerPlugin extends Plugin {
|
||||
TableCollectionFieldInitializer,
|
||||
CollectionFieldInitializer,
|
||||
CreateActionInitializer,
|
||||
CustomizeAddRecordActionInitializer,
|
||||
CreateChildInitializer,
|
||||
ViewActionInitializer,
|
||||
UpdateActionInitializer,
|
||||
PopupActionInitializer,
|
||||
SaveRecordActionInitializer,
|
||||
UpdateRecordActionInitializer,
|
||||
CreateSubmitActionInitializer,
|
||||
UpdateSubmitActionInitializer,
|
||||
|
@ -9,9 +9,15 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { InitializerWithSwitch } from './InitializerWithSwitch';
|
||||
import { useSchemaInitializerItem } from '../../application';
|
||||
import { InitializerWithSwitch } from './InitializerWithSwitch';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use ActionInitializerItem instead
|
||||
* @param props
|
||||
* @returns
|
||||
*/
|
||||
export const ActionInitializer = (props) => {
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
return <InitializerWithSwitch {...itemConfig} {...props} item={itemConfig} type={'x-action'} />;
|
||||
|
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { merge } from '@formily/shared';
|
||||
import React from 'react';
|
||||
|
||||
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../application';
|
||||
|
||||
export const ActionInitializerItem = (props) => {
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
const { insert } = useSchemaInitializer();
|
||||
|
||||
return (
|
||||
<SchemaInitializerItem
|
||||
title={itemConfig.title}
|
||||
onClick={() => {
|
||||
const s = merge(props.schema || {}, itemConfig.schema || {});
|
||||
itemConfig?.schemaInitialize?.(s);
|
||||
insert(s);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from './ActionInitializer';
|
||||
|
||||
export const CreateFilterActionInitializer = (props) => {
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from './ActionInitializer';
|
||||
|
||||
export const CreateResetActionInitializer = (props) => {
|
||||
|
@ -301,6 +301,10 @@ export interface DataBlockInitializerProps {
|
||||
*/
|
||||
hideOtherRecordsInPopup?: boolean;
|
||||
onClick?: (args: any) => void;
|
||||
/** 用于更改 Current record 的文案 */
|
||||
currentText?: string;
|
||||
/** 用于更改 Other records 的文案 */
|
||||
otherText?: string;
|
||||
}
|
||||
|
||||
export const DataBlockInitializer = (props: DataBlockInitializerProps) => {
|
||||
@ -321,6 +325,8 @@ export const DataBlockInitializer = (props: DataBlockInitializerProps) => {
|
||||
hideOtherRecordsInPopup,
|
||||
onClick: propsOnClick,
|
||||
filterOtherRecordsCollection,
|
||||
currentText,
|
||||
otherText,
|
||||
} = props;
|
||||
const { insert, setVisible } = useSchemaInitializer();
|
||||
const compile = useCompile();
|
||||
@ -358,6 +364,8 @@ export const DataBlockInitializer = (props: DataBlockInitializerProps) => {
|
||||
dataBlockInitializerProps: props,
|
||||
hideOtherRecordsInPopup,
|
||||
onClick,
|
||||
currentText,
|
||||
otherText,
|
||||
});
|
||||
const getMenuItems = useGetSchemaInitializerMenuItems(onClick);
|
||||
const childItems = useMemo(() => {
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from './ActionInitializer';
|
||||
import { ActionInitializerItem } from './ActionInitializerItem';
|
||||
|
||||
export const DeleteEventActionInitializer = (props) => {
|
||||
const schema = {
|
||||
@ -26,5 +25,5 @@ export const DeleteEventActionInitializer = (props) => {
|
||||
},
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ActionInitializer } from './ActionInitializer';
|
||||
import { ActionInitializerItem } from './ActionInitializerItem';
|
||||
|
||||
export const SelectActionInitializer = (props) => {
|
||||
const schema = {
|
||||
@ -65,5 +65,5 @@ export const SelectActionInitializer = (props) => {
|
||||
},
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from './ActionInitializer';
|
||||
import { ActionInitializerItem } from './ActionInitializerItem';
|
||||
|
||||
export const SubmitActionInitializer = (props) => {
|
||||
const schema = {
|
||||
@ -24,5 +23,5 @@ export const SubmitActionInitializer = (props) => {
|
||||
htmlType: 'submit',
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -13,6 +13,7 @@ export * from '../../schema-component/antd/association-filter/AssociationFilter'
|
||||
export * from '../../schema-component/antd/association-filter/AssociationFilterDesignerDelete';
|
||||
export * from '../../schema-component/antd/association-filter/AssociationFilterDesignerDisplayField';
|
||||
export * from './ActionInitializer';
|
||||
export * from './ActionInitializerItem';
|
||||
export * from './BlockInitializer';
|
||||
export * from './CreateFilterActionInitializer';
|
||||
export * from './CreateResetActionInitializer';
|
||||
|
@ -857,6 +857,8 @@ export const useCollectionDataSourceItems = ({
|
||||
hideOtherRecordsInPopup,
|
||||
onClick,
|
||||
filterOtherRecordsCollection,
|
||||
currentText,
|
||||
otherText,
|
||||
}: {
|
||||
componentName;
|
||||
filter?: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean;
|
||||
@ -873,6 +875,8 @@ export const useCollectionDataSourceItems = ({
|
||||
* 用来筛选弹窗中的 “Other records” 选项中的数据表
|
||||
*/
|
||||
filterOtherRecordsCollection?: (collection: Collection) => boolean;
|
||||
currentText?: string;
|
||||
otherText?: string;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const dm = useDataSourceManager();
|
||||
@ -932,7 +936,7 @@ export const useCollectionDataSourceItems = ({
|
||||
componentProps: {
|
||||
...dataBlockInitializerProps,
|
||||
icon: null,
|
||||
title: t('Current record'),
|
||||
title: currentText || t('Current record'),
|
||||
name: 'currentRecord',
|
||||
hideSearch: false,
|
||||
hideChildrenIfSingleCollection: true,
|
||||
@ -970,7 +974,7 @@ export const useCollectionDataSourceItems = ({
|
||||
onClick() {},
|
||||
componentProps: {
|
||||
icon: null,
|
||||
title: t('Other records'),
|
||||
title: otherText || t('Other records'),
|
||||
name: 'otherRecords',
|
||||
showAssociationFields: false,
|
||||
onlyCurrentDataSource: false,
|
||||
@ -1031,6 +1035,7 @@ export const useCollectionDataSourceItems = ({
|
||||
collection.name,
|
||||
componentName,
|
||||
dataBlockInitializerProps,
|
||||
filterOtherRecordsCollection,
|
||||
hideOtherRecordsInPopup,
|
||||
noAssociationMenu,
|
||||
onClick,
|
||||
|
@ -47,75 +47,51 @@ export const CreateFormBulkEditBlockInitializers: SchemaInitializer = new Schema
|
||||
],
|
||||
});
|
||||
|
||||
const commonOptions = {
|
||||
wrap: gridRowColWrap,
|
||||
title: '{{t("Add block")}}',
|
||||
icon: 'PlusOutlined',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Data blocks")}}',
|
||||
name: 'dataBlocks',
|
||||
children: [
|
||||
{
|
||||
name: 'form',
|
||||
title: '{{t("Form")}}',
|
||||
Component: CreateFormBulkEditBlockInitializer,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Other blocks")}}',
|
||||
name: 'otherBlocks',
|
||||
children: [
|
||||
{
|
||||
name: 'markdown',
|
||||
title: '{{t("Markdown")}}',
|
||||
Component: 'MarkdownBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `bulkEditBlockInitializers` instead
|
||||
*/
|
||||
export const BulkEditBlockInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'BulkEditBlockInitializers',
|
||||
wrap: gridRowColWrap,
|
||||
title: '{{t("Add block")}}',
|
||||
icon: 'PlusOutlined',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Data blocks")}}',
|
||||
name: 'dataBlocks',
|
||||
children: [
|
||||
{
|
||||
name: 'form',
|
||||
title: '{{t("Form")}}',
|
||||
Component: CreateFormBulkEditBlockInitializer,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Other blocks")}}',
|
||||
name: 'otherBlocks',
|
||||
children: [
|
||||
{
|
||||
name: 'markdown',
|
||||
title: '{{t("Markdown")}}',
|
||||
Component: 'MarkdownBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const bulkEditBlockInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'popup:bulkEdit: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: CreateFormBulkEditBlockInitializer,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Other blocks")}}',
|
||||
name: 'otherBlocks',
|
||||
children: [
|
||||
{
|
||||
name: 'markdown',
|
||||
title: '{{t("Markdown")}}',
|
||||
Component: 'MarkdownBlockInitializer',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
BulkEditBlockInitializers_deprecated,
|
||||
);
|
||||
|
@ -10,55 +10,41 @@
|
||||
import { CompatibleSchemaInitializer } from '@nocobase/client';
|
||||
import { BulkEditSubmitActionInitializer } from './BulkEditSubmitActionInitializer';
|
||||
|
||||
const commonOptions = {
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Enable actions")}}',
|
||||
name: 'enableActions',
|
||||
children: [
|
||||
{
|
||||
name: 'submit',
|
||||
title: '{{t("Submit")}}',
|
||||
Component: BulkEditSubmitActionInitializer,
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `bulkEditFormActionInitializers` instead
|
||||
*/
|
||||
export const BulkEditFormActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'BulkEditFormActionInitializers',
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Enable actions")}}',
|
||||
name: 'enableActions',
|
||||
children: [
|
||||
{
|
||||
name: 'submit',
|
||||
title: '{{t("Submit")}}',
|
||||
Component: BulkEditSubmitActionInitializer,
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const bulkEditFormActionInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'bulkEditForm:configureActions',
|
||||
title: '{{t("Configure actions")}}',
|
||||
icon: 'SettingOutlined',
|
||||
items: [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Enable actions")}}',
|
||||
name: 'enableActions',
|
||||
children: [
|
||||
{
|
||||
name: 'submit',
|
||||
title: '{{t("Submit")}}',
|
||||
Component: BulkEditSubmitActionInitializer,
|
||||
schema: {
|
||||
'x-action-settings': {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
BulkEditFormActionInitializers_deprecated,
|
||||
);
|
||||
|
@ -10,81 +10,54 @@
|
||||
import { CompatibleSchemaInitializer, gridRowColWrap } from '@nocobase/client';
|
||||
import { useCustomBulkEditFormItemInitializerFields } from './utils';
|
||||
|
||||
const commonOptions = {
|
||||
wrap: gridRowColWrap,
|
||||
icon: 'SettingOutlined',
|
||||
title: '{{t("Configure fields")}}',
|
||||
items: [
|
||||
{
|
||||
name: 'displayFields',
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Display fields")}}',
|
||||
useChildren: useCustomBulkEditFormItemInitializerFields,
|
||||
},
|
||||
{
|
||||
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': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'blockSettings:markdown',
|
||||
'x-component': 'Markdown.Void',
|
||||
'x-component-props': {
|
||||
content: '{{t("This is a demo text, **supports Markdown syntax**.")}}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `bulkEditFormItemInitializers` instead
|
||||
*/
|
||||
export const BulkEditFormItemInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'BulkEditFormItemInitializers',
|
||||
wrap: gridRowColWrap,
|
||||
icon: 'SettingOutlined',
|
||||
title: '{{t("Configure fields")}}',
|
||||
items: [
|
||||
{
|
||||
name: 'displayFields',
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Display fields")}}',
|
||||
useChildren: useCustomBulkEditFormItemInitializerFields,
|
||||
},
|
||||
{
|
||||
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': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'blockSettings:markdown',
|
||||
'x-component': 'Markdown.Void',
|
||||
'x-component-props': {
|
||||
content: '{{t("This is a demo text, **supports Markdown syntax**.")}}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const bulkEditFormItemInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'bulkEditForm:configureFields',
|
||||
wrap: gridRowColWrap,
|
||||
icon: 'SettingOutlined',
|
||||
title: '{{t("Configure fields")}}',
|
||||
items: [
|
||||
{
|
||||
name: 'displayFields',
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Display fields")}}',
|
||||
useChildren: useCustomBulkEditFormItemInitializerFields,
|
||||
},
|
||||
{
|
||||
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': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'blockSettings:markdown',
|
||||
'x-component': 'Markdown.Void',
|
||||
'x-component-props': {
|
||||
content: '{{t("This is a demo text, **supports Markdown syntax**.")}}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
BulkEditFormItemInitializers_deprecated,
|
||||
);
|
||||
|
@ -7,8 +7,8 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { ActionInitializerItem } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
import { ActionInitializer } from '@nocobase/client';
|
||||
|
||||
export const BulkEditSubmitActionInitializer = (props) => {
|
||||
const schema = {
|
||||
@ -24,5 +24,5 @@ export const BulkEditSubmitActionInitializer = (props) => {
|
||||
htmlType: 'submit',
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -14,7 +14,6 @@ test.describe('TableActionInitializers & GanttActionInitializers & MapActionInit
|
||||
test('bulk edit in TableActionInitializers', async ({ page, mockPage }) => {
|
||||
await mockPage(oneEmptyTableBlockWithActions).goto();
|
||||
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-general').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize right' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Bulk edit' }).click();
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByLabel('Bulk edit')).toBeVisible();
|
||||
@ -24,7 +23,6 @@ test.describe('TableActionInitializers & GanttActionInitializers & MapActionInit
|
||||
await mockRecords('general', 3);
|
||||
await nocoPage.goto();
|
||||
await page.getByLabel('schema-initializer-ActionBar-gantt:configureActions-general').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize right' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Bulk edit' }).click();
|
||||
await expect(page.getByLabel('Bulk edit')).toBeVisible();
|
||||
});
|
||||
|
@ -14,7 +14,6 @@ test.describe('TableActionInitializers & GanttActionInitializers & MapActionInit
|
||||
test('TableActionInitializers should add bulk update', async ({ page, mockPage }) => {
|
||||
await mockPage(oneEmptyTableBlockWithCustomizeActions).goto();
|
||||
await page.getByLabel('schema-initializer-ActionBar-table:configureActions-general').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize right' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Bulk update' }).click();
|
||||
await expect(page.getByLabel('action-Action-Bulk update-customize:bulkUpdate-general-table')).toBeVisible();
|
||||
});
|
||||
@ -23,7 +22,6 @@ test.describe('TableActionInitializers & GanttActionInitializers & MapActionInit
|
||||
await mockRecords('general', 3);
|
||||
await nocoPage.goto();
|
||||
await page.getByLabel('schema-initializer-ActionBar-gantt:configureActions-general').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize right' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Bulk update' }).click();
|
||||
await page.mouse.move(300, 0);
|
||||
await expect(page.getByRole('button', { name: 'Bulk update' })).toBeVisible();
|
||||
|
@ -18,7 +18,6 @@ test.describe('custom request action', () => {
|
||||
// 新建一个 custom request action
|
||||
await page.getByRole('button', { name: 'Actions', exact: true }).hover();
|
||||
await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize right' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Custom request' }).click();
|
||||
|
||||
// 打开编辑按钮弹窗
|
||||
@ -37,7 +36,6 @@ test.describe('custom request action', () => {
|
||||
|
||||
// 1. 新建一个 custom request action
|
||||
await page.getByLabel('schema-initializer-ActionBar-').hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Custom request' }).click();
|
||||
|
||||
// 2. 打开编辑按钮弹窗
|
||||
|
@ -7,7 +7,7 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { ActionInitializer } from '@nocobase/client';
|
||||
import { ActionInitializerItem } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
|
||||
export const DuplicateActionInitializer = (props) => {
|
||||
@ -58,5 +58,5 @@ export const DuplicateActionInitializer = (props) => {
|
||||
},
|
||||
},
|
||||
};
|
||||
return <ActionInitializer {...props} schema={schema} />;
|
||||
return <ActionInitializerItem {...props} schema={schema} />;
|
||||
};
|
||||
|
@ -45,7 +45,8 @@ test.describe('direct duplicate & copy into the form and continue to fill in', (
|
||||
await page.getByLabel('action-Action.Link-Duplicate-duplicate-general-table-0').click();
|
||||
await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-general').hover();
|
||||
//配置表单区块
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).click();
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Current collection' }).click();
|
||||
await page.mouse.move(300, 0);
|
||||
await page.getByLabel('schema-initializer-Grid-form:configureFields-general').hover();
|
||||
await page.getByRole('menuitem', { name: 'singleLineText' }).click();
|
||||
|
@ -7,12 +7,11 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { Schema, useFieldSchema } from '@formily/react';
|
||||
import { Schema } from '@formily/react';
|
||||
import { merge } from '@formily/shared';
|
||||
import {
|
||||
SchemaInitializerSwitch,
|
||||
SchemaInitializerItem,
|
||||
useCollection_deprecated,
|
||||
useDesignable,
|
||||
useSchemaInitializer,
|
||||
useSchemaInitializerItem,
|
||||
} from '@nocobase/client';
|
||||
@ -31,21 +30,6 @@ const findSchema = (schema: Schema, key: string, action: string) => {
|
||||
return buf;
|
||||
});
|
||||
};
|
||||
const removeSchema = (schema, cb) => {
|
||||
return cb(schema);
|
||||
};
|
||||
export const useCurrentSchema = (action: string, key: string, find = findSchema, rm = removeSchema) => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { remove } = useDesignable();
|
||||
const schema = find(fieldSchema, key, action);
|
||||
return {
|
||||
schema,
|
||||
exists: !!schema,
|
||||
remove() {
|
||||
schema && rm(schema, remove);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const initExportSettings = (fields) => {
|
||||
const exportSettings = fields?.filter((f) => !f.children).map((f) => ({ dataIndex: [f.name] }));
|
||||
@ -55,7 +39,6 @@ const initExportSettings = (fields) => {
|
||||
export const ExportActionInitializer = () => {
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
const { insert } = useSchemaInitializer();
|
||||
const { exists, remove } = useCurrentSchema('export', 'x-action', itemConfig.find, itemConfig.remove);
|
||||
const { name } = useCollection_deprecated();
|
||||
const fields = useFields(name);
|
||||
|
||||
@ -75,15 +58,11 @@ export const ExportActionInitializer = () => {
|
||||
icon: 'clouddownloadoutlined',
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<SchemaInitializerSwitch
|
||||
{...itemConfig}
|
||||
checked={exists}
|
||||
<SchemaInitializerItem
|
||||
title={itemConfig.title}
|
||||
onClick={() => {
|
||||
if (exists) {
|
||||
return remove();
|
||||
}
|
||||
schema['x-action-settings']['exportSettings'] = initExportSettings(fields);
|
||||
const s = merge(schema || {}, itemConfig.schema || {});
|
||||
itemConfig?.schemaInitialize?.(s);
|
||||
|
@ -8,21 +8,20 @@
|
||||
*/
|
||||
|
||||
import type { ISchema } from '@formily/react';
|
||||
import { Schema, useFieldSchema } from '@formily/react';
|
||||
import { Schema } from '@formily/react';
|
||||
import { merge } from '@formily/shared';
|
||||
import {
|
||||
SchemaInitializerSwitch,
|
||||
SchemaInitializerItem,
|
||||
css,
|
||||
useCollection_deprecated,
|
||||
useDesignable,
|
||||
useSchemaInitializer,
|
||||
useSchemaInitializerItem,
|
||||
} from '@nocobase/client';
|
||||
import { Alert } from 'antd';
|
||||
import React from 'react';
|
||||
import { NAMESPACE } from './constants';
|
||||
import { useFields } from './useFields';
|
||||
import { Alert } from 'antd';
|
||||
import { useImportTranslation } from './locale';
|
||||
import { useFields } from './useFields';
|
||||
|
||||
const findSchema = (schema: Schema, key: string, action: string) => {
|
||||
return schema.reduceProperties((buf, s) => {
|
||||
@ -36,21 +35,6 @@ const findSchema = (schema: Schema, key: string, action: string) => {
|
||||
return buf;
|
||||
});
|
||||
};
|
||||
const removeSchema = (schema, cb) => {
|
||||
return cb(schema);
|
||||
};
|
||||
export const useCurrentSchema = (action: string, key: string, find = findSchema, rm = removeSchema) => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { remove } = useDesignable();
|
||||
const schema = find(fieldSchema, key, action);
|
||||
return {
|
||||
schema,
|
||||
exists: !!schema,
|
||||
remove() {
|
||||
schema && rm(schema, remove);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const initImportSettings = (fields) => {
|
||||
const importColumns = fields?.filter((f) => !f.children).map((f) => ({ dataIndex: [f.name] }));
|
||||
@ -65,7 +49,6 @@ export const ImportWarning = () => {
|
||||
export const ImportActionInitializer = () => {
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
const { insert } = useSchemaInitializer();
|
||||
const { exists, remove } = useCurrentSchema('importXlsx', 'x-action', itemConfig.find, itemConfig.remove);
|
||||
const { name } = useCollection_deprecated();
|
||||
const fields = useFields(name);
|
||||
const schema: ISchema = {
|
||||
@ -196,15 +179,11 @@ export const ImportActionInitializer = () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<SchemaInitializerSwitch
|
||||
{...itemConfig}
|
||||
checked={exists}
|
||||
<SchemaInitializerItem
|
||||
title={itemConfig.title}
|
||||
onClick={() => {
|
||||
if (exists) {
|
||||
return remove();
|
||||
}
|
||||
schema['x-action-settings']['importSettings'] = initImportSettings(fields);
|
||||
const s = merge(schema || {}, itemConfig.schema || {});
|
||||
itemConfig?.schemaInitialize?.(s);
|
||||
|
@ -7,9 +7,8 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ActionInitializer } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
|
||||
export const PrintActionInitializer = (props) => {
|
||||
const schema = {
|
||||
|
@ -7,7 +7,7 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { ActionInitializer } from '@nocobase/client';
|
||||
import { ActionInitializerItem } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
|
||||
export const AuditLogsViewActionInitializer = () => {
|
||||
@ -346,5 +346,5 @@ export const AuditLogsViewActionInitializer = () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
return <ActionInitializer schema={schema} />;
|
||||
return <ActionInitializerItem schema={schema} />;
|
||||
};
|
||||
|
@ -19,133 +19,80 @@ import {
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const commonOptions = {
|
||||
insertPosition: 'beforeEnd',
|
||||
Component: (props: any) => <MenuOutlined {...props} style={{ cursor: 'pointer' }} />,
|
||||
useInsert() {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const api = useAPIClient();
|
||||
const { refresh } = useDesignable();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (schema) => {
|
||||
const spaceSchema = fieldSchema.reduceProperties((buf, schema) => {
|
||||
if (schema['x-component'] === 'Space') {
|
||||
return schema;
|
||||
}
|
||||
return buf;
|
||||
}, null);
|
||||
if (!spaceSchema) {
|
||||
return;
|
||||
}
|
||||
const dn = createDesignable({
|
||||
t,
|
||||
api,
|
||||
refresh,
|
||||
current: spaceSchema,
|
||||
});
|
||||
dn.loadAPIClientEvents();
|
||||
dn.insertBeforeEnd(schema);
|
||||
};
|
||||
},
|
||||
items: [
|
||||
{
|
||||
name: 'enableActions',
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Enable actions")}}',
|
||||
children: [
|
||||
{
|
||||
name: 'view',
|
||||
type: 'item',
|
||||
title: '{{t("View")}}',
|
||||
Component: 'AuditLogsViewActionInitializer',
|
||||
schema: {
|
||||
'x-component': 'Action.Link',
|
||||
'x-action': 'view',
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
name: 'columnWidth',
|
||||
type: 'item',
|
||||
title: '{{t("Column width")}}',
|
||||
Component: Resizable,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `auditLogsTableActionColumnInitializers` instead
|
||||
*/
|
||||
export const auditLogsTableActionColumnInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'AuditLogsTableActionColumnInitializers',
|
||||
insertPosition: 'beforeEnd',
|
||||
Component: (props: any) => <MenuOutlined {...props} style={{ cursor: 'pointer' }} />,
|
||||
useInsert() {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const api = useAPIClient();
|
||||
const { refresh } = useDesignable();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (schema) => {
|
||||
const spaceSchema = fieldSchema.reduceProperties((buf, schema) => {
|
||||
if (schema['x-component'] === 'Space') {
|
||||
return schema;
|
||||
}
|
||||
return buf;
|
||||
}, null);
|
||||
if (!spaceSchema) {
|
||||
return;
|
||||
}
|
||||
const dn = createDesignable({
|
||||
t,
|
||||
api,
|
||||
refresh,
|
||||
current: spaceSchema,
|
||||
});
|
||||
dn.loadAPIClientEvents();
|
||||
dn.insertBeforeEnd(schema);
|
||||
};
|
||||
},
|
||||
items: [
|
||||
{
|
||||
name: 'enableActions',
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Enable actions")}}',
|
||||
children: [
|
||||
{
|
||||
name: 'view',
|
||||
type: 'item',
|
||||
title: '{{t("View")}}',
|
||||
Component: 'AuditLogsViewActionInitializer',
|
||||
schema: {
|
||||
'x-component': 'Action.Link',
|
||||
'x-action': 'view',
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
name: 'columnWidth',
|
||||
type: 'item',
|
||||
title: '{{t("Column width")}}',
|
||||
Component: Resizable,
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const auditLogsTableActionColumnInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'auditLogsTable:configureItemActions',
|
||||
insertPosition: 'beforeEnd',
|
||||
Component: (props: any) => <MenuOutlined {...props} style={{ cursor: 'pointer' }} />,
|
||||
useInsert() {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const api = useAPIClient();
|
||||
const { refresh } = useDesignable();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (schema) => {
|
||||
const spaceSchema = fieldSchema.reduceProperties((buf, schema) => {
|
||||
if (schema['x-component'] === 'Space') {
|
||||
return schema;
|
||||
}
|
||||
return buf;
|
||||
}, null);
|
||||
if (!spaceSchema) {
|
||||
return;
|
||||
}
|
||||
const dn = createDesignable({
|
||||
t,
|
||||
api,
|
||||
refresh,
|
||||
current: spaceSchema,
|
||||
});
|
||||
dn.loadAPIClientEvents();
|
||||
dn.insertBeforeEnd(schema);
|
||||
};
|
||||
},
|
||||
items: [
|
||||
{
|
||||
name: 'enableActions',
|
||||
type: 'itemGroup',
|
||||
title: '{{t("Enable actions")}}',
|
||||
children: [
|
||||
{
|
||||
name: 'view',
|
||||
type: 'item',
|
||||
title: '{{t("View")}}',
|
||||
Component: 'AuditLogsViewActionInitializer',
|
||||
schema: {
|
||||
'x-component': 'Action.Link',
|
||||
'x-action': 'view',
|
||||
'x-decorator': 'ACLActionProvider',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
name: 'columnWidth',
|
||||
type: 'item',
|
||||
title: '{{t("Column width")}}',
|
||||
Component: Resizable,
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
auditLogsTableActionColumnInitializers_deprecated,
|
||||
);
|
||||
|
@ -9,6 +9,39 @@
|
||||
|
||||
import { CompatibleSchemaInitializer } from '@nocobase/client';
|
||||
|
||||
const commonOptions = {
|
||||
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: 'refresh',
|
||||
title: "{{t('Refresh')}}",
|
||||
Component: 'RefreshActionInitializer',
|
||||
schema: {
|
||||
'x-align': 'right',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* use `auditLogsTableActionInitializers` instead
|
||||
@ -16,71 +49,13 @@ import { CompatibleSchemaInitializer } from '@nocobase/client';
|
||||
*/
|
||||
export const auditLogsTableActionInitializers_deprecated = new CompatibleSchemaInitializer({
|
||||
name: 'AuditLogsTableActionInitializers',
|
||||
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: 'refresh',
|
||||
title: "{{t('Refresh')}}",
|
||||
Component: 'RefreshActionInitializer',
|
||||
schema: {
|
||||
'x-align': 'right',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
});
|
||||
|
||||
export const auditLogsTableActionInitializers = new CompatibleSchemaInitializer(
|
||||
{
|
||||
name: 'auditLogsTable: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: 'refresh',
|
||||
title: "{{t('Refresh')}}",
|
||||
Component: 'RefreshActionInitializer',
|
||||
schema: {
|
||||
'x-align': 'right',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
...commonOptions,
|
||||
},
|
||||
auditLogsTableActionInitializers_deprecated,
|
||||
);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user