mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-01 18:52:20 +08:00
feat: actions 2.0 (#7105)
* refactor: streamline AddNewActionModel and remove unused imports in TableModel * feat: add LinkPopupActionModel and update PopupActionModel usage * feat: add PopupRecordActionModel and update index export * feat: remove LinkPopupActionModel * refactor: update ViewActionModel to extend RecordActionModel and remove LinkPopupActionModel export * fix: correct import path for ReactiveField in FormFieldModel * fix: correct import path for ReactiveField in FormFieldModel * refactor: update ActionModel to improve button rendering and props handling * refactor: simplify AddNewActionModel by removing unused imports and streamlining flow registration * refactor: streamline DeleteActionModel by removing unnecessary confirmation steps * feat: enhance LinkActionModel with new navigation and parameter handling features * feat: add Emotion CSS support to LinkActionModel * refactor: update BulkDeleteActionModel to improve flow registration and event handling * refactor: update AddNewActionModel and BulkDeleteActionModel to use title and icon props * refactor: update RefreshActionModel to use title and icon props, and improve flow registration * refactor: rename LinkActionModel to LinkRecordActionModel * feat: add LinkGlobalActionModel and register flow for link handling * feat: implement openLinkAction and integrate with LinkGlobalActionModel and LinkRecordActionModel * feat: add CustomRequestRecordActionModel and update index export * feat: add CustomRequestGlobalActionModel and update index export * feat: add BulkEditActionModel and update index export
This commit is contained in:
parent
1e28346b0e
commit
78d4b27690
94
packages/core/client/src/flow/actions/openLinkAction.tsx
Normal file
94
packages/core/client/src/flow/actions/openLinkAction.tsx
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* 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 { css } from '@emotion/css';
|
||||
import { Variable } from '../../schema-component/antd/variable/Variable';
|
||||
|
||||
export const openLinkAction = {
|
||||
title: '编辑链接',
|
||||
uiSchema: {
|
||||
url: {
|
||||
title: 'URL',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': Variable.TextArea,
|
||||
description: 'Do not concatenate search params in the URL',
|
||||
},
|
||||
params: {
|
||||
type: 'array',
|
||||
'x-component': 'ArrayItems',
|
||||
'x-decorator': 'FormItem',
|
||||
title: `Search parameters`,
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
space: {
|
||||
type: 'void',
|
||||
'x-component': 'Space',
|
||||
'x-component-props': {
|
||||
style: {
|
||||
flexWrap: 'nowrap',
|
||||
maxWidth: '100%',
|
||||
},
|
||||
className: css`
|
||||
& > .ant-space-item:first-child,
|
||||
& > .ant-space-item:last-child {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
`,
|
||||
},
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
'x-component-props': {
|
||||
placeholder: `{{t("Name")}}`,
|
||||
},
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': Variable.TextArea,
|
||||
'x-component-props': {
|
||||
placeholder: `{{t("Value")}}`,
|
||||
useTypedConstant: true,
|
||||
changeOnSelect: true,
|
||||
},
|
||||
},
|
||||
remove: {
|
||||
type: 'void',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'ArrayItems.Remove',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
add: {
|
||||
type: 'void',
|
||||
title: 'Add parameter',
|
||||
'x-component': 'ArrayItems.Addition',
|
||||
},
|
||||
},
|
||||
},
|
||||
openInNewWindow: {
|
||||
type: 'boolean',
|
||||
'x-content': 'Open in new window',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Checkbox',
|
||||
},
|
||||
},
|
||||
handler(ctx, params) {
|
||||
ctx.globals.modal.confirm({
|
||||
title: `TODO`,
|
||||
content: JSON.stringify(params, null, 2),
|
||||
});
|
||||
},
|
||||
};
|
@ -8,63 +8,25 @@
|
||||
*/
|
||||
|
||||
import { ButtonProps } from 'antd';
|
||||
import React from 'react';
|
||||
import { FlowPage } from '../../FlowPage';
|
||||
import { GlobalActionModel } from '../base/ActionModel';
|
||||
import { openModeAction } from '../../actions/openModeAction';
|
||||
|
||||
export class AddNewActionModel extends GlobalActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
type: 'primary',
|
||||
children: 'Add new',
|
||||
title: 'Add new',
|
||||
icon: 'PlusOutlined',
|
||||
};
|
||||
}
|
||||
|
||||
AddNewActionModel.registerFlow({
|
||||
sort: 200,
|
||||
title: '事件',
|
||||
key: 'event1',
|
||||
title: '点击事件',
|
||||
key: 'handleClick',
|
||||
on: {
|
||||
eventName: 'click',
|
||||
},
|
||||
steps: {
|
||||
step1: {
|
||||
title: '弹窗配置',
|
||||
uiSchema: {
|
||||
width: {
|
||||
type: 'number',
|
||||
title: '宽度',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'NumberPicker',
|
||||
'x-component-props': {
|
||||
placeholder: '请输入宽度',
|
||||
},
|
||||
},
|
||||
},
|
||||
defaultParams: {
|
||||
width: 800,
|
||||
},
|
||||
handler(ctx, params) {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let currentDrawer: any;
|
||||
|
||||
function DrawerContent() {
|
||||
return (
|
||||
<div>
|
||||
<FlowPage
|
||||
parentId={ctx.model.uid}
|
||||
sharedContext={{ parentBlockModel: ctx.shared.currentBlockModel, currentDrawer }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
currentDrawer = ctx.globals.drawer.open({
|
||||
// title: '命令式 Drawer',
|
||||
header: null,
|
||||
width: params.width,
|
||||
content: <DrawerContent />,
|
||||
});
|
||||
},
|
||||
},
|
||||
open: openModeAction,
|
||||
},
|
||||
});
|
||||
|
@ -10,20 +10,25 @@
|
||||
import { MultiRecordResource } from '@nocobase/flow-engine';
|
||||
import { ButtonProps } from 'antd';
|
||||
import { GlobalActionModel } from '../base/ActionModel';
|
||||
import { secondaryConfirmationAction } from '../../actions/secondaryConfirmationAction';
|
||||
import { refreshOnCompleteAction } from '../../actions/refreshOnCompleteAction';
|
||||
|
||||
export class BulkDeleteActionModel extends GlobalActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
children: 'Delete',
|
||||
title: 'Delete',
|
||||
icon: 'DeleteOutlined',
|
||||
};
|
||||
}
|
||||
|
||||
BulkDeleteActionModel.registerFlow({
|
||||
key: 'event1',
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
||||
eventName: 'click',
|
||||
},
|
||||
steps: {
|
||||
step1: {
|
||||
secondaryConfirmationAction,
|
||||
delete: {
|
||||
async handler(ctx, params) {
|
||||
if (!ctx.shared?.currentBlockModel?.resource) {
|
||||
ctx.globals.message.error('No resource selected for deletion.');
|
||||
@ -38,5 +43,6 @@ BulkDeleteActionModel.registerFlow({
|
||||
ctx.globals.message.success('Selected records deleted successfully.');
|
||||
},
|
||||
},
|
||||
refreshOnCompleteAction,
|
||||
},
|
||||
});
|
||||
|
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* 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 { MultiRecordResource } from '@nocobase/flow-engine';
|
||||
import { ButtonProps } from 'antd';
|
||||
import { GlobalActionModel } from '../base/ActionModel';
|
||||
import { openModeAction } from '../../actions/openModeAction';
|
||||
|
||||
export class BulkEditActionModel extends GlobalActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
title: 'Bulk edit',
|
||||
icon: 'EditOutlined',
|
||||
};
|
||||
}
|
||||
|
||||
BulkEditActionModel.registerFlow({
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
||||
eventName: 'click',
|
||||
},
|
||||
steps: {
|
||||
openModeAction,
|
||||
bulkEdit: {
|
||||
title: '更新的数据',
|
||||
uiSchema: {
|
||||
updateMode: {
|
||||
'x-component': 'Radio.Group',
|
||||
'x-component-props': {
|
||||
options: [
|
||||
{ label: '更新选中行', value: 'selected' },
|
||||
{ label: '更新所有行', value: 'all' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
defaultParams(ctx) {
|
||||
return {
|
||||
updateMode: 'selected',
|
||||
};
|
||||
},
|
||||
async handler(ctx, params) {
|
||||
if (!ctx.shared?.currentBlockModel?.resource) {
|
||||
ctx.globals.message.error('No resource selected for bulk edit.');
|
||||
return;
|
||||
}
|
||||
const resource = ctx.shared.currentBlockModel.resource as MultiRecordResource;
|
||||
if (resource.getSelectedRows().length === 0) {
|
||||
ctx.globals.message.warning('No records selected for bulk edit.');
|
||||
return;
|
||||
}
|
||||
await resource.destroySelectedRows();
|
||||
ctx.globals.message.success('Successfully.');
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
@ -15,9 +15,8 @@ import { refreshOnCompleteAction } from '../../actions/refreshOnCompleteAction';
|
||||
import { secondaryConfirmationAction } from '../../actions/secondaryConfirmationAction';
|
||||
import { GlobalActionModel } from '../base/ActionModel';
|
||||
|
||||
export class CustomRequestActionModel extends GlobalActionModel {
|
||||
export class CustomRequestGlobalActionModel extends GlobalActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
type: 'link',
|
||||
title: 'Custom request',
|
||||
};
|
||||
}
|
||||
@ -35,7 +34,7 @@ const useVariableProps = () => {
|
||||
};
|
||||
};
|
||||
|
||||
CustomRequestActionModel.registerFlow({
|
||||
CustomRequestGlobalActionModel.registerFlow({
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
@ -0,0 +1,304 @@
|
||||
/**
|
||||
* 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 type { ButtonProps } from 'antd/es/button';
|
||||
import { useGlobalVariable } from '../../../application/hooks/useGlobalVariable';
|
||||
import { BlocksSelector } from '../../../schema-component/antd/action/Action.Designer';
|
||||
import { useAfterSuccessOptions } from '../../../schema-component/antd/action/hooks/useGetAfterSuccessVariablesOptions';
|
||||
import { refreshOnCompleteAction } from '../../actions/refreshOnCompleteAction';
|
||||
import { secondaryConfirmationAction } from '../../actions/secondaryConfirmationAction';
|
||||
import { RecordActionModel } from '../base/ActionModel';
|
||||
|
||||
export class CustomRequestRecordActionModel extends RecordActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
type: 'link',
|
||||
title: 'Custom request',
|
||||
};
|
||||
}
|
||||
|
||||
const fieldNames = {
|
||||
value: 'value',
|
||||
label: 'label',
|
||||
};
|
||||
const useVariableProps = () => {
|
||||
const environmentVariables = useGlobalVariable('$env');
|
||||
const scope = useAfterSuccessOptions();
|
||||
return {
|
||||
scope: [environmentVariables, ...scope].filter(Boolean),
|
||||
fieldNames,
|
||||
};
|
||||
};
|
||||
|
||||
CustomRequestRecordActionModel.registerFlow({
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
||||
eventName: 'click',
|
||||
},
|
||||
steps: {
|
||||
secondaryConfirmation: secondaryConfirmationAction,
|
||||
request: {
|
||||
title: '请求设置',
|
||||
uiSchema: {
|
||||
method: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
title: 'HTTP method',
|
||||
'x-decorator-props': {
|
||||
tooltip:
|
||||
'When the HTTP method is Post, Put or Patch, and this custom request inside the form, the request body will be automatically filled in with the form data',
|
||||
},
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Select',
|
||||
'x-component-props': {
|
||||
showSearch: false,
|
||||
allowClear: false,
|
||||
className: 'auto-width',
|
||||
},
|
||||
enum: [
|
||||
{ label: 'GET', value: 'GET' },
|
||||
{ label: 'POST', value: 'POST' },
|
||||
{ label: 'PUT', value: 'PUT' },
|
||||
{ label: 'PATCH', value: 'PATCH' },
|
||||
{ label: 'DELETE', value: 'DELETE' },
|
||||
],
|
||||
default: 'POST',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
title: 'URL',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Variable.TextArea',
|
||||
'x-use-component-props': useVariableProps,
|
||||
'x-component-props': {
|
||||
placeholder: 'https://www.nocobase.com',
|
||||
},
|
||||
},
|
||||
headers: {
|
||||
type: 'array',
|
||||
'x-component': 'ArrayItems',
|
||||
'x-decorator': 'FormItem',
|
||||
title: 'Headers',
|
||||
description: '"Content-Type" only support "application/json", and no need to specify',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
space: {
|
||||
type: 'void',
|
||||
'x-component': 'Space',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
'x-component-props': {
|
||||
placeholder: 'Name',
|
||||
},
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Variable.TextArea',
|
||||
'x-use-component-props': useVariableProps,
|
||||
},
|
||||
remove: {
|
||||
type: 'void',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'ArrayItems.Remove',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
add: {
|
||||
type: 'void',
|
||||
title: 'Add request header',
|
||||
'x-component': 'ArrayItems.Addition',
|
||||
},
|
||||
},
|
||||
},
|
||||
params: {
|
||||
type: 'array',
|
||||
'x-component': 'ArrayItems',
|
||||
'x-decorator': 'FormItem',
|
||||
title: 'Parameters',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
space: {
|
||||
type: 'void',
|
||||
'x-component': 'Space',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
'x-component-props': {
|
||||
placeholder: 'Name',
|
||||
},
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Variable.TextArea',
|
||||
'x-use-component-props': useVariableProps,
|
||||
},
|
||||
remove: {
|
||||
type: 'void',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'ArrayItems.Remove',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
add: {
|
||||
type: 'void',
|
||||
title: 'Add parameter',
|
||||
'x-component': 'ArrayItems.Addition',
|
||||
},
|
||||
},
|
||||
},
|
||||
data: {
|
||||
type: 'string',
|
||||
title: 'Body',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-decorator-props': {},
|
||||
'x-component': 'Variable.JSON',
|
||||
'x-component-props': {
|
||||
scope: '{{useCustomRequestVariableOptions}}',
|
||||
fieldNames: {
|
||||
value: 'name',
|
||||
label: 'title',
|
||||
},
|
||||
changeOnSelect: true,
|
||||
autoSize: {
|
||||
minRows: 10,
|
||||
},
|
||||
placeholder: 'Input request data',
|
||||
},
|
||||
description: 'Only support standard JSON data',
|
||||
},
|
||||
timeout: {
|
||||
type: 'number',
|
||||
title: 'Timeout config',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-decorator-props': {},
|
||||
'x-component': 'InputNumber',
|
||||
'x-component-props': {
|
||||
addonAfter: 'ms',
|
||||
min: 1,
|
||||
step: 1000,
|
||||
defaultValue: 5000,
|
||||
},
|
||||
},
|
||||
responseType: {
|
||||
type: 'string',
|
||||
title: 'Response type',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-decorator-props': {},
|
||||
'x-component': 'Select',
|
||||
default: 'json',
|
||||
enum: [
|
||||
{ value: 'json', label: 'JSON' },
|
||||
{ value: 'stream', label: 'Stream' },
|
||||
],
|
||||
},
|
||||
},
|
||||
async handler(ctx, params) {
|
||||
ctx.globals.modal({
|
||||
title: 'TODO: Custom request action handler',
|
||||
});
|
||||
},
|
||||
},
|
||||
afterSuccess: {
|
||||
title: '提交成功后',
|
||||
uiSchema: {
|
||||
successMessage: {
|
||||
title: 'Popup message',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input.TextArea',
|
||||
'x-component-props': {},
|
||||
},
|
||||
manualClose: {
|
||||
title: 'Message popup close method',
|
||||
enum: [
|
||||
{ label: 'Automatic close', value: false },
|
||||
{ label: 'Manually close', value: true },
|
||||
],
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Radio.Group',
|
||||
'x-component-props': {},
|
||||
},
|
||||
redirecting: {
|
||||
title: 'Then',
|
||||
'x-hidden': true,
|
||||
enum: [
|
||||
{ label: 'Stay on current page', value: false },
|
||||
{ label: 'Redirect to', value: true },
|
||||
],
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Radio.Group',
|
||||
'x-component-props': {},
|
||||
'x-reactions': {
|
||||
target: 'redirectTo',
|
||||
fulfill: {
|
||||
state: {
|
||||
visible: '{{!!$self.value}}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
actionAfterSuccess: {
|
||||
title: 'Action after successful submission',
|
||||
enum: [
|
||||
{ label: 'Stay on the current popup or page', value: 'stay' },
|
||||
{ label: 'Return to the previous popup or page', value: 'previous' },
|
||||
{ label: 'Redirect to', value: 'redirect' },
|
||||
],
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Radio.Group',
|
||||
'x-component-props': {},
|
||||
'x-reactions': {
|
||||
target: 'redirectTo',
|
||||
fulfill: {
|
||||
state: {
|
||||
visible: "{{$self.value==='redirect'}}",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
redirectTo: {
|
||||
title: 'Link',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Variable.TextArea',
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
'x-use-component-props': () => useVariableProps(),
|
||||
},
|
||||
blocksToRefresh: {
|
||||
type: 'array',
|
||||
title: 'Refresh data blocks',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-use-decorator-props': () => {
|
||||
return {
|
||||
tooltip: 'After successful submission, the selected data blocks will be automatically refreshed.',
|
||||
};
|
||||
},
|
||||
'x-component': BlocksSelector,
|
||||
// 'x-hidden': isInBlockTemplateConfigPage, // 模板配置页面暂不支持该配置
|
||||
},
|
||||
},
|
||||
handler(ctx, params) {},
|
||||
},
|
||||
refresh: refreshOnCompleteAction,
|
||||
},
|
||||
});
|
@ -7,54 +7,28 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { MultiRecordResource } from '@nocobase/flow-engine';
|
||||
import type { ButtonProps } from 'antd';
|
||||
import type { ButtonProps } from 'antd/es/button';
|
||||
import { RecordActionModel } from '../base/ActionModel';
|
||||
import { secondaryConfirmationAction } from '../../actions/secondaryConfirmationAction';
|
||||
import { MultiRecordResource } from '@nocobase/flow-engine';
|
||||
import { refreshOnCompleteAction } from '../../actions/refreshOnCompleteAction';
|
||||
|
||||
export class DeleteActionModel extends RecordActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
children: 'Delete',
|
||||
type: 'link',
|
||||
title: 'Delete',
|
||||
};
|
||||
}
|
||||
|
||||
DeleteActionModel.registerFlow({
|
||||
key: 'event1',
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
||||
eventName: 'click',
|
||||
},
|
||||
steps: {
|
||||
confirm: {
|
||||
uiSchema: {
|
||||
title: {
|
||||
type: 'string',
|
||||
title: 'Confirm title',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
content: {
|
||||
type: 'string',
|
||||
title: 'Confirm content',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input.TextArea',
|
||||
},
|
||||
},
|
||||
defaultParams: {
|
||||
title: 'Confirm Deletion',
|
||||
content: 'Are you sure you want to delete this record?',
|
||||
},
|
||||
async handler(ctx, params) {
|
||||
const confirmed = await ctx.globals.modal.confirm({
|
||||
title: params.title,
|
||||
content: params.content,
|
||||
});
|
||||
if (!confirmed) {
|
||||
ctx.globals.message.info('Deletion cancelled.');
|
||||
return ctx.exit();
|
||||
}
|
||||
},
|
||||
},
|
||||
step1: {
|
||||
secondaryConfirmation: secondaryConfirmationAction,
|
||||
delete: {
|
||||
async handler(ctx, params) {
|
||||
if (!ctx.shared?.currentBlockModel?.resource) {
|
||||
ctx.globals.message.error('No resource selected for deletion.');
|
||||
@ -69,5 +43,6 @@ DeleteActionModel.registerFlow({
|
||||
ctx.globals.message.success('Record deleted successfully.');
|
||||
},
|
||||
},
|
||||
refresh: refreshOnCompleteAction,
|
||||
},
|
||||
});
|
||||
|
@ -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 type { ButtonProps } from 'antd';
|
||||
import { GlobalActionModel } from '../base/ActionModel';
|
||||
import { openLinkAction } from '../../actions/openLinkAction';
|
||||
|
||||
export class LinkGlobalActionModel extends GlobalActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
title: 'Link',
|
||||
};
|
||||
}
|
||||
|
||||
LinkGlobalActionModel.registerFlow({
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
||||
eventName: 'click',
|
||||
},
|
||||
steps: {
|
||||
navigate: openLinkAction,
|
||||
},
|
||||
});
|
@ -9,22 +9,22 @@
|
||||
|
||||
import type { ButtonProps } from 'antd';
|
||||
import { RecordActionModel } from '../base/ActionModel';
|
||||
import { openLinkAction } from '../../actions/openLinkAction';
|
||||
|
||||
export class LinkActionModel extends RecordActionModel {
|
||||
export class LinkRecordActionModel extends RecordActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
type: 'link',
|
||||
children: 'Link',
|
||||
};
|
||||
}
|
||||
|
||||
LinkActionModel.registerFlow({
|
||||
key: 'event1',
|
||||
LinkRecordActionModel.registerFlow({
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
||||
eventName: 'click',
|
||||
},
|
||||
steps: {
|
||||
step1: {
|
||||
handler(ctx, params) {},
|
||||
},
|
||||
navigate: openLinkAction,
|
||||
},
|
||||
});
|
@ -11,14 +11,13 @@ import type { ButtonProps } from 'antd/es/button';
|
||||
import { openModeAction } from '../../actions/openModeAction';
|
||||
import { RecordActionModel } from '../base/ActionModel';
|
||||
|
||||
export class PopupActionModel extends RecordActionModel {
|
||||
export class PopupRecordActionModel extends RecordActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
type: 'link',
|
||||
title: 'Popup',
|
||||
};
|
||||
}
|
||||
|
||||
PopupActionModel.registerFlow({
|
||||
PopupRecordActionModel.registerFlow({
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
@ -9,20 +9,24 @@
|
||||
|
||||
import { ButtonProps } from 'antd';
|
||||
import { GlobalActionModel } from '../base/ActionModel';
|
||||
import { secondaryConfirmationAction } from '../../actions/secondaryConfirmationAction';
|
||||
|
||||
export class RefreshActionModel extends GlobalActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
children: 'Refresh',
|
||||
title: 'Refresh',
|
||||
icon: 'ReloadOutlined',
|
||||
};
|
||||
}
|
||||
|
||||
RefreshActionModel.registerFlow({
|
||||
key: 'event1',
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
||||
eventName: 'click',
|
||||
},
|
||||
steps: {
|
||||
step1: {
|
||||
secondaryConfirmationAction,
|
||||
refresh: {
|
||||
async handler(ctx, params) {
|
||||
if (!ctx.shared?.currentBlockModel?.resource) {
|
||||
ctx.globals.message.error('No resource selected for refresh.');
|
||||
|
@ -7,50 +7,24 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { ButtonProps } from 'antd';
|
||||
import React from 'react';
|
||||
import { FlowPage } from '../../FlowPage';
|
||||
import type { ButtonProps } from 'antd/es/button';
|
||||
import { RecordActionModel } from '../base/ActionModel';
|
||||
import { openModeAction } from '../../actions/openModeAction';
|
||||
|
||||
export class ViewActionModel extends RecordActionModel {
|
||||
defaultProps: ButtonProps = {
|
||||
children: 'View',
|
||||
type: 'link',
|
||||
title: 'View',
|
||||
};
|
||||
}
|
||||
|
||||
ViewActionModel.registerFlow({
|
||||
key: 'event1',
|
||||
key: 'handleClick',
|
||||
title: '点击事件',
|
||||
on: {
|
||||
eventName: 'click',
|
||||
},
|
||||
steps: {
|
||||
step1: {
|
||||
handler(ctx, params) {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let currentDrawer: any;
|
||||
|
||||
function DrawerContent() {
|
||||
return (
|
||||
<div>
|
||||
<FlowPage
|
||||
parentId={ctx.model.uid}
|
||||
sharedContext={{
|
||||
currentDrawer,
|
||||
parentRecord: ctx.extra.currentRecord,
|
||||
parentBlockModel: ctx.shared.currentBlockModel,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
currentDrawer = ctx.globals.drawer.open({
|
||||
// title: '命令式 Drawer',
|
||||
width: 800,
|
||||
content: <DrawerContent />,
|
||||
});
|
||||
},
|
||||
},
|
||||
open: openModeAction,
|
||||
},
|
||||
});
|
||||
|
@ -9,13 +9,16 @@
|
||||
|
||||
export * from './AddNewActionModel';
|
||||
export * from './BulkDeleteActionModel';
|
||||
export * from './CustomRequestActionModel';
|
||||
export * from './BulkEditActionModel';
|
||||
export * from './CustomRequestRecordActionModel';
|
||||
export * from './CustomRequestGlobalActionModel';
|
||||
export * from './DeleteActionModel';
|
||||
export * from './DuplicateActionModel';
|
||||
export * from './EditActionModel';
|
||||
export * from './FilterActionModel';
|
||||
export * from './LinkActionModel';
|
||||
export * from './PopupActionModel';
|
||||
export * from './LinkRecordActionModel';
|
||||
export * from './LinkGlobalActionModel';
|
||||
export * from './PopupRecordActionModel';
|
||||
export * from './RefreshActionModel';
|
||||
export * from './UpdateRecordActionModel';
|
||||
export * from './ViewActionModel';
|
||||
|
@ -11,44 +11,56 @@ import { FlowModel } from '@nocobase/flow-engine';
|
||||
import { Button } from 'antd';
|
||||
import type { ButtonProps } from 'antd/es/button';
|
||||
import React from 'react';
|
||||
import IconPicker from '../../../schema-component/antd/icon-picker/IconPicker';
|
||||
import { Icon } from '../../../icon/Icon';
|
||||
|
||||
export class ActionModel extends FlowModel {
|
||||
declare props: ButtonProps;
|
||||
|
||||
defaultProps: ButtonProps = {
|
||||
type: 'default',
|
||||
children: 'Action',
|
||||
title: 'Action',
|
||||
};
|
||||
|
||||
render() {
|
||||
return <Button {...this.defaultProps} {...this.props} />;
|
||||
const props = { ...this.defaultProps, ...this.props };
|
||||
const icon = <Icon type={props.icon as any} />;
|
||||
|
||||
return (
|
||||
<Button {...props} icon={icon}>
|
||||
{props.children || props.title}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ActionModel.registerFlow({
|
||||
key: 'default',
|
||||
title: '通用配置',
|
||||
auto: true,
|
||||
title: '基础',
|
||||
sort: 100,
|
||||
steps: {
|
||||
step1: {
|
||||
buttonProps: {
|
||||
title: '编辑按钮',
|
||||
uiSchema: {
|
||||
children: {
|
||||
type: 'string',
|
||||
title: '标题',
|
||||
title: {
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
'x-component-props': {
|
||||
placeholder: '请输入标题',
|
||||
},
|
||||
title: 'Button title',
|
||||
},
|
||||
icon: {
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': IconPicker,
|
||||
title: 'Button icon',
|
||||
},
|
||||
},
|
||||
defaultParams(ctx) {
|
||||
return {
|
||||
type: 'default',
|
||||
...ctx.model.defaultProps,
|
||||
title: ctx.model.defaultProps.title,
|
||||
icon: ctx.model.defaultProps.icon,
|
||||
};
|
||||
},
|
||||
handler(ctx, params) {
|
||||
ctx.model.setProps('children', params.children);
|
||||
ctx.model.setProps(params);
|
||||
ctx.model.setProps('onClick', (event) => {
|
||||
ctx.model.dispatchEvent('click', {
|
||||
...ctx.extra,
|
||||
|
@ -11,7 +11,6 @@ import { SettingOutlined } from '@ant-design/icons';
|
||||
import { css } from '@emotion/css';
|
||||
import {
|
||||
AddActionButton,
|
||||
AddActionModel,
|
||||
AddFieldButton,
|
||||
Collection,
|
||||
FlowModelRenderer,
|
||||
|
Loading…
x
Reference in New Issue
Block a user