refactor: webhooks rename to dispatchers (#1385)
Co-authored-by: sealday <sealday@gmail.com> Reviewed-on: daoyoucloud/tachybase#1385
This commit is contained in:
parent
f717663d9e
commit
730c7aef5b
@ -107,6 +107,12 @@ export class PluginWorkflow extends Plugin {
|
|||||||
this.addComponents();
|
this.addComponents();
|
||||||
|
|
||||||
this.app.pluginSettingsManager.add(NAMESPACE, {
|
this.app.pluginSettingsManager.add(NAMESPACE, {
|
||||||
|
icon: 'PartitionOutlined',
|
||||||
|
title: `{{t("Workflow", { ns: "${NAMESPACE}" })}}`,
|
||||||
|
aclSnippet: 'pm.workflow.workflows',
|
||||||
|
});
|
||||||
|
|
||||||
|
this.app.pluginSettingsManager.add(NAMESPACE + '.list', {
|
||||||
icon: 'PartitionOutlined',
|
icon: 'PartitionOutlined',
|
||||||
title: `{{t("Workflow", { ns: "${NAMESPACE}" })}}`,
|
title: `{{t("Workflow", { ns: "${NAMESPACE}" })}}`,
|
||||||
Component: WorkflowPane,
|
Component: WorkflowPane,
|
||||||
|
@ -1,168 +0,0 @@
|
|||||||
import {
|
|
||||||
SchemaInitializerItemType,
|
|
||||||
useCollectionDataSource,
|
|
||||||
useCollectionManager_deprecated,
|
|
||||||
useCompile,
|
|
||||||
} from '@tachybase/client';
|
|
||||||
|
|
||||||
import {
|
|
||||||
CheckboxGroupWithTooltip,
|
|
||||||
CollectionBlockInitializer,
|
|
||||||
FieldsSelect,
|
|
||||||
getCollectionFieldOptions,
|
|
||||||
RadioWithTooltip,
|
|
||||||
} from '../../..';
|
|
||||||
import { lang, tval } from '../../../locale';
|
|
||||||
import { Trigger } from '../../../triggers';
|
|
||||||
|
|
||||||
const enum ACTION_TYPES {
|
|
||||||
CREATE = 'create',
|
|
||||||
UPDATE = 'update',
|
|
||||||
UPSERT = 'updateOrCreate',
|
|
||||||
DESTROY = 'destroy',
|
|
||||||
}
|
|
||||||
export class APIRegularTrigger extends Trigger {
|
|
||||||
title = lang('API Regular(deprecated)');
|
|
||||||
description = lang('Trigger when an API call is made.');
|
|
||||||
fieldset = {
|
|
||||||
collection: {
|
|
||||||
type: 'string',
|
|
||||||
title: tval('Collection'),
|
|
||||||
required: true,
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'DataSourceCollectionCascader',
|
|
||||||
'x-reactions': [
|
|
||||||
{
|
|
||||||
target: 'changed',
|
|
||||||
effects: ['onFieldValueChange'],
|
|
||||||
fulfill: {
|
|
||||||
state: {
|
|
||||||
value: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
global: {
|
|
||||||
type: 'boolean',
|
|
||||||
title: tval('Trigger mode'),
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'RadioWithTooltip',
|
|
||||||
'x-component-props': {
|
|
||||||
direction: 'vertical',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: tval('Local mode, triggered before executing the actions bound to this workflow'),
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: tval('Global mode, triggered before executing the following actions'),
|
|
||||||
value: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
type: 'number',
|
|
||||||
title: tval('Select actions'),
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'CheckboxGroupWithTooltip',
|
|
||||||
'x-component-props': {
|
|
||||||
direction: 'vertical',
|
|
||||||
options: [
|
|
||||||
{ label: tval('Create record action'), value: ACTION_TYPES.CREATE },
|
|
||||||
{ label: tval('Update record action'), value: ACTION_TYPES.UPDATE },
|
|
||||||
{ label: tval('Delete record action'), value: ACTION_TYPES.DESTROY },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
required: true,
|
|
||||||
'x-reactions': [
|
|
||||||
{
|
|
||||||
dependencies: ['collection', 'global'],
|
|
||||||
fulfill: {
|
|
||||||
state: {
|
|
||||||
visible: '{{!!$deps[0] && !!$deps[1]}}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
scope = { useCollectionDataSource };
|
|
||||||
|
|
||||||
components = {
|
|
||||||
FieldsSelect: FieldsSelect,
|
|
||||||
RadioWithTooltip: RadioWithTooltip,
|
|
||||||
CheckboxGroupWithTooltip: CheckboxGroupWithTooltip,
|
|
||||||
};
|
|
||||||
|
|
||||||
isActionTriggerable = (config, context) => {
|
|
||||||
const { global } = config;
|
|
||||||
return !global && !context.direct;
|
|
||||||
};
|
|
||||||
|
|
||||||
useVariables(config, options) {
|
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
||||||
const compile = useCompile();
|
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
||||||
const { getCollectionFields } = useCollectionManager_deprecated();
|
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
||||||
const langTriggerData = lang('Trigger data');
|
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
||||||
const langUserSubmittedForm = lang('User submitted action');
|
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
||||||
const langRoleSubmittedForm = lang('Role of user submitted action');
|
|
||||||
const rootFields = [
|
|
||||||
{
|
|
||||||
collectionName: config.collection,
|
|
||||||
name: 'data',
|
|
||||||
type: 'hasOne',
|
|
||||||
target: config.collection,
|
|
||||||
uiSchema: {
|
|
||||||
title: langTriggerData,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
collectionName: 'users',
|
|
||||||
name: 'user',
|
|
||||||
type: 'hasOne',
|
|
||||||
target: 'users',
|
|
||||||
uiSchema: {
|
|
||||||
title: langUserSubmittedForm,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'roleName',
|
|
||||||
uiSchema: {
|
|
||||||
title: langRoleSubmittedForm,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const result = getCollectionFieldOptions({
|
|
||||||
// depth,
|
|
||||||
appends: ['data', 'user', ...(config.appends?.map((item) => `data.${item}`) || [])],
|
|
||||||
...options,
|
|
||||||
fields: rootFields,
|
|
||||||
compile,
|
|
||||||
getCollectionFields,
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
useInitializers(config): SchemaInitializerItemType | null {
|
|
||||||
if (!config.collection) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: 'triggerData',
|
|
||||||
type: 'item',
|
|
||||||
key: 'triggerData',
|
|
||||||
title: tval('Trigger data'),
|
|
||||||
Component: CollectionBlockInitializer,
|
|
||||||
collection: config.collection,
|
|
||||||
dataPath: '$context.data',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +1,3 @@
|
|||||||
import { Plugin } from '@tachybase/client';
|
import { Plugin } from '@tachybase/client';
|
||||||
|
|
||||||
import PluginWorkflow from '../../..';
|
export class KitAPIRegularConfiguration extends Plugin {}
|
||||||
import { NAMESPACE_TRIGGER_API_REGULAR } from '../../../../common/constants';
|
|
||||||
import { APIRegularTrigger } from './APIRegular.trigger';
|
|
||||||
|
|
||||||
export class KitAPIRegularConfiguration extends Plugin {
|
|
||||||
async load() {
|
|
||||||
const pluginWorkflow = this.app.pm.get(PluginWorkflow);
|
|
||||||
pluginWorkflow.registerTrigger(NAMESPACE_TRIGGER_API_REGULAR, APIRegularTrigger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
SchemaSettings,
|
SchemaSettings,
|
||||||
SchemaSettingsItemType,
|
SchemaSettingsItemType,
|
||||||
useDesignable,
|
useDesignable,
|
||||||
useRequest,
|
|
||||||
useSchemaToolbar,
|
useSchemaToolbar,
|
||||||
WorkflowConfig,
|
WorkflowConfig,
|
||||||
} from '@tachybase/client';
|
} from '@tachybase/client';
|
||||||
@ -11,8 +10,6 @@ import { isValid, useFieldSchema } from '@tachybase/schema';
|
|||||||
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { NAMESPACE_TRIGGER_API_REGULAR } from '../../../../common/constants';
|
|
||||||
|
|
||||||
const schemaSettingsItems: SchemaSettingsItemType[] = [
|
const schemaSettingsItems: SchemaSettingsItemType[] = [
|
||||||
{
|
{
|
||||||
name: 'editButton',
|
name: 'editButton',
|
||||||
@ -56,47 +53,6 @@ const schemaSettingsItems: SchemaSettingsItemType[] = [
|
|||||||
return isValid(fieldSchema?.['x-action-settings']?.triggerWorkflows);
|
return isValid(fieldSchema?.['x-action-settings']?.triggerWorkflows);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'Bind workflow',
|
|
||||||
type: 'select',
|
|
||||||
useComponentProps() {
|
|
||||||
const { dn } = useDesignable();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const fieldSchema = useFieldSchema();
|
|
||||||
const { data } = useRequest<any>({
|
|
||||||
resource: 'workflows',
|
|
||||||
action: 'list',
|
|
||||||
params: {
|
|
||||||
filter: {
|
|
||||||
type: NAMESPACE_TRIGGER_API_REGULAR,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// FIXME 不会实时生效
|
|
||||||
const options =
|
|
||||||
data?.data?.map((workflow) => ({
|
|
||||||
label: workflow.title,
|
|
||||||
value: workflow.id,
|
|
||||||
})) ?? [];
|
|
||||||
return {
|
|
||||||
title: t('Bind workflow'),
|
|
||||||
value: fieldSchema['x-action-settings'].bindWorkflow,
|
|
||||||
options: options.concat({
|
|
||||||
label: t('disabled'),
|
|
||||||
value: false,
|
|
||||||
}),
|
|
||||||
onChange(value) {
|
|
||||||
fieldSchema['x-action-settings'].bindWorkflow = value;
|
|
||||||
dn.emit('patch', {
|
|
||||||
schema: {
|
|
||||||
'x-uid': fieldSchema['x-uid'],
|
|
||||||
'x-action-settings': fieldSchema['x-action-settings'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'remove',
|
name: 'remove',
|
||||||
sort: 100,
|
sort: 100,
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
CollectionOptions,
|
|
||||||
ExtendCollectionsProvider,
|
ExtendCollectionsProvider,
|
||||||
ResourceActionProvider,
|
ResourceActionProvider,
|
||||||
SchemaComponent,
|
SchemaComponent,
|
||||||
|
useAPIClient,
|
||||||
useRecord,
|
useRecord,
|
||||||
WorkflowSelect,
|
WorkflowSelect,
|
||||||
} from '@tachybase/client';
|
} from '@tachybase/client';
|
||||||
import { CodeMirror } from '@tachybase/components';
|
import { CodeMirror } from '@tachybase/components';
|
||||||
import { ISchema } from '@tachybase/schema';
|
import { ISchema, useForm } from '@tachybase/schema';
|
||||||
|
|
||||||
import { Button, Space } from 'antd';
|
import { Button, Space } from 'antd';
|
||||||
|
|
||||||
import { ExecutionStatusColumn } from '../../components/ExecutionStatus';
|
import { ExecutionStatusColumn } from '../../components/ExecutionStatus';
|
||||||
import OpenDrawer from '../../components/OpenDrawer';
|
import OpenDrawer from '../../components/OpenDrawer';
|
||||||
import { ExecutionLink } from '../../ExecutionLink';
|
import { ExecutionLink } from '../../ExecutionLink';
|
||||||
import { lang, tval } from '../../locale';
|
import { lang } from '../../locale';
|
||||||
import { executionSchema } from '../../schemas/executions';
|
import { executionSchema } from '../../schemas/executions';
|
||||||
|
import { dispatchers } from './collections/dispatchers';
|
||||||
|
|
||||||
export const ExecutionResourceProvider = ({ request, filter = {}, ...others }) => {
|
export const ExecutionResourceProvider = ({ request, filter = {}, ...others }) => {
|
||||||
const webhook = useRecord();
|
const webhook = useRecord();
|
||||||
@ -37,84 +38,22 @@ export const ExecutionResourceProvider = ({ request, filter = {}, ...others }) =
|
|||||||
return <ResourceActionProvider {...props} />;
|
return <ResourceActionProvider {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const collection: CollectionOptions = {
|
export const useTestActionProps = () => {
|
||||||
name: 'webhooks',
|
const form = useForm();
|
||||||
title: 'webhooks',
|
const webhook = useRecord();
|
||||||
fields: [
|
const api = useAPIClient();
|
||||||
{
|
return {
|
||||||
type: 'string',
|
async onClick() {
|
||||||
name: 'name',
|
const res = await api.resource('webhooks').test({
|
||||||
interface: 'input',
|
values: {
|
||||||
uiSchema: {
|
body: JSON.parse(form.values.body),
|
||||||
title: tval('Name'),
|
params: JSON.parse(form.values.params),
|
||||||
type: 'string',
|
name: webhook.name,
|
||||||
'x-component': 'Input',
|
|
||||||
required: true,
|
|
||||||
} as ISchema,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'boolean',
|
|
||||||
name: 'enabled',
|
|
||||||
interface: 'radioGroup',
|
|
||||||
uiSchema: {
|
|
||||||
title: tval('Enabled'),
|
|
||||||
type: 'string',
|
|
||||||
required: true,
|
|
||||||
enum: [
|
|
||||||
{ label: tval('On'), value: true },
|
|
||||||
{ label: tval('Off'), value: false },
|
|
||||||
],
|
|
||||||
'x-component': 'Radio.Group',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
default: false,
|
|
||||||
} as ISchema,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'string',
|
|
||||||
name: 'workflowKey',
|
|
||||||
interface: 'select',
|
|
||||||
uiSchema: {
|
|
||||||
title: tval('Workflow'),
|
|
||||||
type: 'string',
|
|
||||||
'x-component': 'WorkflowSelect',
|
|
||||||
'x-component-props': {
|
|
||||||
buttonAction: 'customize:triggerWorkflows',
|
|
||||||
noCollection: true,
|
|
||||||
label: 'title',
|
|
||||||
value: 'key',
|
|
||||||
},
|
},
|
||||||
} as ISchema,
|
});
|
||||||
|
alert(JSON.stringify(res.data));
|
||||||
},
|
},
|
||||||
{
|
};
|
||||||
type: 'string',
|
|
||||||
name: 'type',
|
|
||||||
interface: 'radioGroup',
|
|
||||||
uiSchema: {
|
|
||||||
title: tval('Type'),
|
|
||||||
type: 'string',
|
|
||||||
required: true,
|
|
||||||
enum: [
|
|
||||||
{ label: tval('Code'), value: 'code' },
|
|
||||||
{ label: tval('Plugin'), value: 'plugin', disabled: true },
|
|
||||||
],
|
|
||||||
'x-component': 'Radio.Group',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
default: 'code',
|
|
||||||
} as ISchema,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'text',
|
|
||||||
name: 'code',
|
|
||||||
interface: 'textarea',
|
|
||||||
uiSchema: {
|
|
||||||
title: tval('Code'),
|
|
||||||
type: 'string',
|
|
||||||
'x-component': 'CodeMirror',
|
|
||||||
default:
|
|
||||||
'// ctx.query can get user query\n// ctx.body to pass your data to workflow or to client who trigger this webhook.',
|
|
||||||
} as ISchema,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const schema: ISchema = {
|
const schema: ISchema = {
|
||||||
@ -126,7 +65,7 @@ const schema: ISchema = {
|
|||||||
'x-acl-action': 'webhooks:list',
|
'x-acl-action': 'webhooks:list',
|
||||||
'x-use-decorator-props': 'useTableBlockDecoratorProps',
|
'x-use-decorator-props': 'useTableBlockDecoratorProps',
|
||||||
'x-decorator-props': {
|
'x-decorator-props': {
|
||||||
collection,
|
collection: dispatchers,
|
||||||
dataSource: 'main',
|
dataSource: 'main',
|
||||||
action: 'list',
|
action: 'list',
|
||||||
params: {
|
params: {
|
||||||
@ -207,7 +146,7 @@ const schema: ISchema = {
|
|||||||
'x-use-decorator-props': 'useCreateFormBlockDecoratorProps',
|
'x-use-decorator-props': 'useCreateFormBlockDecoratorProps',
|
||||||
'x-decorator-props': {
|
'x-decorator-props': {
|
||||||
dataSource: 'main',
|
dataSource: 'main',
|
||||||
collection,
|
collection: dispatchers,
|
||||||
},
|
},
|
||||||
'x-component': 'CardItem',
|
'x-component': 'CardItem',
|
||||||
properties: {
|
properties: {
|
||||||
@ -382,6 +321,9 @@ const schema: ISchema = {
|
|||||||
type: 'void',
|
type: 'void',
|
||||||
'x-decorator': 'TableV2.Column.Decorator',
|
'x-decorator': 'TableV2.Column.Decorator',
|
||||||
'x-component': 'TableV2.Column',
|
'x-component': 'TableV2.Column',
|
||||||
|
'x-component-props': {
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
properties: {
|
properties: {
|
||||||
name: {
|
name: {
|
||||||
'x-collection-field': 'webhooks.name',
|
'x-collection-field': 'webhooks.name',
|
||||||
@ -403,6 +345,9 @@ const schema: ISchema = {
|
|||||||
type: 'void',
|
type: 'void',
|
||||||
'x-decorator': 'TableV2.Column.Decorator',
|
'x-decorator': 'TableV2.Column.Decorator',
|
||||||
'x-component': 'TableV2.Column',
|
'x-component': 'TableV2.Column',
|
||||||
|
'x-component-props': {
|
||||||
|
width: 20,
|
||||||
|
},
|
||||||
properties: {
|
properties: {
|
||||||
enabled: {
|
enabled: {
|
||||||
'x-collection-field': 'webhooks.enabled',
|
'x-collection-field': 'webhooks.enabled',
|
||||||
@ -424,6 +369,9 @@ const schema: ISchema = {
|
|||||||
type: 'void',
|
type: 'void',
|
||||||
'x-decorator': 'TableV2.Column.Decorator',
|
'x-decorator': 'TableV2.Column.Decorator',
|
||||||
'x-component': 'TableV2.Column',
|
'x-component': 'TableV2.Column',
|
||||||
|
'x-component-props': {
|
||||||
|
width: 20,
|
||||||
|
},
|
||||||
properties: {
|
properties: {
|
||||||
workflowKey: {
|
workflowKey: {
|
||||||
'x-collection-field': 'webhooks.workflowKey',
|
'x-collection-field': 'webhooks.workflowKey',
|
||||||
@ -455,6 +403,9 @@ const schema: ISchema = {
|
|||||||
type: 'void',
|
type: 'void',
|
||||||
'x-decorator': 'TableV2.Column.Decorator',
|
'x-decorator': 'TableV2.Column.Decorator',
|
||||||
'x-component': 'TableV2.Column',
|
'x-component': 'TableV2.Column',
|
||||||
|
'x-component-props': {
|
||||||
|
width: 20,
|
||||||
|
},
|
||||||
properties: {
|
properties: {
|
||||||
type: {
|
type: {
|
||||||
'x-collection-field': 'webhooks.type',
|
'x-collection-field': 'webhooks.type',
|
||||||
@ -542,7 +493,7 @@ const schema: ISchema = {
|
|||||||
'x-decorator-props': {
|
'x-decorator-props': {
|
||||||
action: 'get',
|
action: 'get',
|
||||||
dataSource: 'main',
|
dataSource: 'main',
|
||||||
collection,
|
collection: dispatchers,
|
||||||
},
|
},
|
||||||
'x-component': 'CardItem',
|
'x-component': 'CardItem',
|
||||||
properties: {
|
properties: {
|
||||||
@ -722,6 +673,153 @@ const schema: ISchema = {
|
|||||||
'x-decorator': 'ACLActionProvider',
|
'x-decorator': 'ACLActionProvider',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
},
|
},
|
||||||
|
test: {
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Test") }}',
|
||||||
|
'x-action': 'update',
|
||||||
|
'x-component': 'Action.Link',
|
||||||
|
'x-component-props': {
|
||||||
|
openMode: 'drawer',
|
||||||
|
icon: 'EditOutlined',
|
||||||
|
},
|
||||||
|
'x-decorator': 'ACLActionProvider',
|
||||||
|
properties: {
|
||||||
|
drawer: {
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Edit record") }}',
|
||||||
|
'x-component': 'Action.Container',
|
||||||
|
'x-component-props': {
|
||||||
|
className: 'nb-action-popup',
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
tabs: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Tabs',
|
||||||
|
'x-component-props': {},
|
||||||
|
properties: {
|
||||||
|
tab1: {
|
||||||
|
type: 'void',
|
||||||
|
title: '{{t("Edit")}}',
|
||||||
|
'x-component': 'Tabs.TabPane',
|
||||||
|
'x-component-props': {},
|
||||||
|
properties: {
|
||||||
|
grid: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
properties: {
|
||||||
|
to6mk4v552h: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
properties: {
|
||||||
|
sqvdrzdbr7r: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
'8uym9fty5oy': {
|
||||||
|
type: 'void',
|
||||||
|
'x-acl-action-props': {
|
||||||
|
skipScopeCheck: false,
|
||||||
|
},
|
||||||
|
'x-acl-action': 'webhooks:update',
|
||||||
|
'x-decorator': 'FormBlockProvider',
|
||||||
|
'x-use-decorator-props': 'useEditFormBlockDecoratorProps',
|
||||||
|
'x-decorator-props': {
|
||||||
|
action: 'get',
|
||||||
|
dataSource: 'main',
|
||||||
|
collection: dispatchers,
|
||||||
|
},
|
||||||
|
'x-component': 'CardItem',
|
||||||
|
properties: {
|
||||||
|
je28rbthifp: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'FormV2',
|
||||||
|
'x-use-component-props': 'useEditFormBlockProps',
|
||||||
|
properties: {
|
||||||
|
yviwt5e73dx: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'ActionBar',
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
marginBottom: 'var(--tb-spacing)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
unkmoqgvtvr: {
|
||||||
|
title: '{{ t("Submit") }}',
|
||||||
|
'x-action': 'submit',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-use-component-props': 'useTestActionProps',
|
||||||
|
'x-component-props': {
|
||||||
|
type: 'primary',
|
||||||
|
htmlType: 'submit',
|
||||||
|
},
|
||||||
|
'x-action-settings': {
|
||||||
|
triggerWorkflows: [],
|
||||||
|
onSuccess: {
|
||||||
|
manualClose: false,
|
||||||
|
redirecting: false,
|
||||||
|
successMessage: '{{t("Updated successfully")}}',
|
||||||
|
},
|
||||||
|
isDeltaChanged: false,
|
||||||
|
},
|
||||||
|
type: 'void',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
properties: {
|
||||||
|
'38fm61ehxvn': {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
properties: {
|
||||||
|
arovreokda8: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
params: {
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'CodeMirror',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-decorator-props': {
|
||||||
|
label: 'query',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'CodeMirror',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-decorator-props': {
|
||||||
|
label: 'body',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -735,10 +833,11 @@ const schema: ISchema = {
|
|||||||
|
|
||||||
export const WebhookManager = () => {
|
export const WebhookManager = () => {
|
||||||
return (
|
return (
|
||||||
<ExtendCollectionsProvider collections={[collection]}>
|
<ExtendCollectionsProvider collections={[dispatchers]}>
|
||||||
<SchemaComponent
|
<SchemaComponent
|
||||||
memoized
|
memoized
|
||||||
schema={schema}
|
schema={schema}
|
||||||
|
scope={{ useTestActionProps }}
|
||||||
components={{
|
components={{
|
||||||
ExecutionStatusColumn,
|
ExecutionStatusColumn,
|
||||||
ExecutionResourceProvider,
|
ExecutionResourceProvider,
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
import { CollectionOptions } from '@tachybase/client';
|
||||||
|
import { ISchema } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { tval } from '../../../locale';
|
||||||
|
|
||||||
|
export const dispatchers: CollectionOptions = {
|
||||||
|
name: 'webhooks',
|
||||||
|
title: 'webhooks',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
name: 'name',
|
||||||
|
interface: 'input',
|
||||||
|
uiSchema: {
|
||||||
|
title: tval('Name'),
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'Input',
|
||||||
|
required: true,
|
||||||
|
} as ISchema,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'boolean',
|
||||||
|
name: 'enabled',
|
||||||
|
interface: 'radioGroup',
|
||||||
|
uiSchema: {
|
||||||
|
title: tval('Enabled'),
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
enum: [
|
||||||
|
{ label: tval('On'), value: true },
|
||||||
|
{ label: tval('Off'), value: false },
|
||||||
|
],
|
||||||
|
'x-component': 'Radio.Group',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
default: false,
|
||||||
|
} as ISchema,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
name: 'workflowKey',
|
||||||
|
interface: 'select',
|
||||||
|
uiSchema: {
|
||||||
|
title: tval('Workflow'),
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'WorkflowSelect',
|
||||||
|
'x-component-props': {
|
||||||
|
buttonAction: 'customize:triggerWorkflows',
|
||||||
|
noCollection: true,
|
||||||
|
label: 'title',
|
||||||
|
value: 'key',
|
||||||
|
},
|
||||||
|
} as ISchema,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
name: 'type',
|
||||||
|
interface: 'radioGroup',
|
||||||
|
uiSchema: {
|
||||||
|
title: tval('Type'),
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
enum: [
|
||||||
|
{ label: tval('HTTP endpoint'), value: 'code' },
|
||||||
|
{ label: tval('Scheduler'), value: 'cron' },
|
||||||
|
],
|
||||||
|
'x-component': 'Radio.Group',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
default: 'code',
|
||||||
|
} as ISchema,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
name: 'code',
|
||||||
|
interface: 'textarea',
|
||||||
|
uiSchema: {
|
||||||
|
title: tval('Code'),
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'CodeMirror',
|
||||||
|
default:
|
||||||
|
'// ctx.query can get user query\n// ctx.body to pass your data to workflow or to client who trigger this webhook.',
|
||||||
|
} as ISchema,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
@ -1,13 +1,28 @@
|
|||||||
import { Plugin } from '@tachybase/client';
|
import React from 'react';
|
||||||
|
import { Icon, Plugin } from '@tachybase/client';
|
||||||
|
|
||||||
import { tval } from '../../locale';
|
import { tval } from '../../locale';
|
||||||
import { WebhookManager } from './WebhookManager';
|
import { WebhookManager } from './WebhookManager';
|
||||||
|
|
||||||
|
const DispatcherSvg = () => (
|
||||||
|
<svg viewBox="0 0 1024 1024" width="1em" height="1em">
|
||||||
|
<path
|
||||||
|
d="M979.689326 108.982857H356.219611A144.530286 144.530286 0 0 0 217.028754 0c-64.804571 0.731429-121.124571 45.348571-137.654857 108.982857H44.045897a36.571429 36.571429 0 0 0-37.814857 15.798857 37.741714 37.741714 0 0 0 0 41.545143 36.571429 36.571429 0 0 0 37.814857 15.798857h35.328c15.945143 64.219429 72.411429 109.494857 137.654857 110.445715a144.530286 144.530286 0 0 0 139.117715-108.982858h623.542857a37.156571 37.156571 0 0 0 29.549714-36.571428 37.156571 37.156571 0 0 0-29.549714-36.571429v-1.462857zM144.909897 146.285714c0-40.374857 32.329143-73.142857 72.118857-73.142857s72.118857 32.768 72.118857 73.142857c0 19.382857-7.606857 38.034286-21.211428 51.712A71.533714 71.533714 0 0 1 217.101897 219.428571a72.630857 72.630857 0 0 1-72.118857-73.142857z m834.779429 694.125715H356.219611A144.530286 144.530286 0 0 0 217.028754 731.428571c-64.804571 0.731429-121.124571 45.348571-137.654857 108.982858H44.045897a36.571429 36.571429 0 0 0-37.814857 15.798857 37.741714 37.741714 0 0 0 0 41.545143 36.571429 36.571429 0 0 0 37.814857 15.798857h35.328c15.945143 64.219429 72.411429 109.494857 137.654857 110.445714a144.530286 144.530286 0 0 0 139.117715-108.982857h623.542857a36.571429 36.571429 0 0 0 37.814857-15.798857 37.741714 37.741714 0 0 0 0-41.545143 36.571429 36.571429 0 0 0-37.814857-15.798857v-1.462857zM144.909897 877.714286c0-40.374857 32.329143-73.142857 72.118857-73.142857s72.118857 32.768 72.118857 73.142857c0 19.382857-7.606857 38.034286-21.211428 51.712a71.533714 71.533714 0 0 1-50.907429 21.430857 72.630857 72.630857 0 0 1-72.118857-73.142857zM43.972754 474.697143h623.616A144.530286 144.530286 0 0 1 806.706469 365.714286c64.804571 0.731429 121.124571 45.348571 137.654857 108.982857h34.596571a36.571429 36.571429 0 0 1 37.814857 15.798857 37.741714 37.741714 0 0 1 0 41.545143 36.571429 36.571429 0 0 1-37.814857 15.798857h-34.596571A144.603429 144.603429 0 0 1 806.779611 658.285714a144.530286 144.530286 0 0 1-139.117714-108.982857H44.045897a36.571429 36.571429 0 0 1-37.814857-15.798857 37.741714 37.741714 0 0 1 0-41.545143 36.571429 36.571429 0 0 1 37.814857-15.798857v-1.462857zM807.803611 585.142857a73.142857 73.142857 0 1 0 0-146.285714 73.142857 73.142857 0 0 0 0 146.285714z"
|
||||||
|
fill="#4A4A4A"
|
||||||
|
opacity=".65"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Dispatcher = (props) => <Icon component={DispatcherSvg} {...props} />;
|
||||||
|
|
||||||
|
Icon.register({ Dispatcher });
|
||||||
|
|
||||||
export class PluginWebhook extends Plugin {
|
export class PluginWebhook extends Plugin {
|
||||||
async load() {
|
async load() {
|
||||||
this.app.pluginSettingsManager.add('webhook', {
|
this.app.pluginSettingsManager.add('workflow.webhook', {
|
||||||
title: tval('Webhook manager'),
|
title: tval('Dispatcher'),
|
||||||
icon: 'ShareAltOutlined',
|
icon: 'Dispatcher',
|
||||||
Component: WebhookManager,
|
Component: WebhookManager,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,7 @@
|
|||||||
"Delete record": "删除数据",
|
"Delete record": "删除数据",
|
||||||
"Delete records of a collection. Could use variables in workflow context as filter. All records match the filter will be deleted.": "删除一个数据表中的数据。可以使用上游节点里的变量作为过滤条件。所有满足条件的数据都将被删除。",
|
"Delete records of a collection. Could use variables in workflow context as filter. All records match the filter will be deleted.": "删除一个数据表中的数据。可以使用上游节点里的变量作为过滤条件。所有满足条件的数据都将被删除。",
|
||||||
"Disabled": "已失效",
|
"Disabled": "已失效",
|
||||||
|
"Dispatcher": "调度器",
|
||||||
"Distinct": "去重",
|
"Distinct": "去重",
|
||||||
"Draft": "草稿",
|
"Draft": "草稿",
|
||||||
"Duplicate to new workflow": "复制为新工作流",
|
"Duplicate to new workflow": "复制为新工作流",
|
||||||
|
@ -12,8 +12,9 @@ export class PluginWebhook extends Plugin {
|
|||||||
name: 'webhooks',
|
name: 'webhooks',
|
||||||
actions: {
|
actions: {
|
||||||
trigger: new WebhookController().getLink,
|
trigger: new WebhookController().getLink,
|
||||||
|
test: new WebhookController().test,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.app.acl.allow('webhooks', 'trigger', 'loggedIn');
|
this.app.acl.allow('webhooks', ['trigger', 'test'], 'loggedIn');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ export class WebhookController {
|
|||||||
if (name) {
|
if (name) {
|
||||||
where['filter'] = {
|
where['filter'] = {
|
||||||
name: name,
|
name: name,
|
||||||
|
type: 'code',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -52,6 +53,14 @@ export class WebhookController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async test(ctx: Context) {
|
||||||
|
const { name, params, body } = ctx.action.params.values;
|
||||||
|
ctx.request.query = params;
|
||||||
|
ctx.action.params = params || {};
|
||||||
|
ctx.action.params.name = name;
|
||||||
|
ctx.action.params.values = body;
|
||||||
|
await new WebhookController().getLink(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function run(jsCode: string, { ctx, lib }) {
|
function run(jsCode: string, { ctx, lib }) {
|
||||||
|
Loading…
Reference in New Issue
Block a user