From 03a1dfdf1ed9b9bcf191d94328404c5e7755e62c Mon Sep 17 00:00:00 2001 From: "bai.zixv" Date: Thu, 6 Jun 2024 11:48:27 +0800 Subject: [PATCH] feat/feat-apiselected (#1132) Reviewed-on: https://git.daoyoucloud.com/daoyoucloud/tachybase/pulls/1132 Co-authored-by: bai.zixv Co-committed-by: bai.zixv --- .../antd/action/Action.Area.tsx | 6 +-- .../api-regular/usage/APIRegular.schema.tsx | 2 +- ...on.Settings.tsx => APIRegular.setting.tsx} | 0 .../usage/{utils.tsx => hooks.tsx} | 37 ++++++------------- .../client/features/api-regular/usage/kit.ts | 4 +- .../src/client/nodes/index.tsx | 5 ++- .../plugin-workflow/src/client/style.tsx | 1 + .../src/client/triggers/index.tsx | 5 ++- .../src/server/actions/workflows.ts | 9 ++++- .../features/action-trigger/ActionTrigger.ts | 11 +++--- .../api-regular/APIRegular.trigger.ts | 2 +- .../features/request/RequestInstruction.ts | 26 ++++++++++--- 12 files changed, 61 insertions(+), 47 deletions(-) rename packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/{BulkUpdateAction.Settings.tsx => APIRegular.setting.tsx} (100%) rename packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/{utils.tsx => hooks.tsx} (78%) diff --git a/packages/core/client/src/schema-component/antd/action/Action.Area.tsx b/packages/core/client/src/schema-component/antd/action/Action.Area.tsx index 940a2015b..50c59251b 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.Area.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.Area.tsx @@ -32,17 +32,17 @@ export const ActionAreaStub = () => { export const ActionAreaPlayer = ({ children }) => { const { visible, setVisible } = useActionContext(); - const { prevSetVisible, setPrevSetVisible, ref } = useContext(ActionAreaContext); + const { prevSetVisible, setPrevSetVisible, ref = { current: null } } = useContext(ActionAreaContext); useEffect(() => { if (visible) { - setPrevSetVisible(() => { + setPrevSetVisible?.(() => { prevSetVisible?.(false); return setVisible; }); } }, [visible]); - return visible ? createPortal(children, ref.current) : null; + return visible && ref.current ? createPortal(children, ref.current) : null; }; export const ActionArea: ComposedActionDrawer = observer( diff --git a/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/APIRegular.schema.tsx b/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/APIRegular.schema.tsx index 148200cfb..12ae9233d 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/APIRegular.schema.tsx +++ b/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/APIRegular.schema.tsx @@ -19,9 +19,9 @@ const schema = { 'x-acl-action-props': { skipScopeCheck: true, }, - 'x-action': 'customize:APIRegular', 'x-toolbar': 'ActionSchemaToolbar', 'x-settings': 'actionSettings:APIRegular', + 'x-action': 'customize:APIRegular', 'x-action-settings': { bindWorkflow: false, updateMode: 'selected', diff --git a/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/BulkUpdateAction.Settings.tsx b/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/APIRegular.setting.tsx similarity index 100% rename from packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/BulkUpdateAction.Settings.tsx rename to packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/APIRegular.setting.tsx diff --git a/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/utils.tsx b/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/hooks.tsx similarity index 78% rename from packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/utils.tsx rename to packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/hooks.tsx index 8117db644..d603f5ac5 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/utils.tsx +++ b/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/hooks.tsx @@ -54,6 +54,12 @@ export const usePropsAPIRegular = () => { updateMode, } = actionSchema?.['x-action-settings'] ?? {}; + const isUpdateSelected = updateMode === 'selected'; + const updateData = { + primaryKey: rowKey || 'id', + targetKeys: selectedRecordKeys, + }; + actionField.data = field.data || {}; actionField.data.loading = true; @@ -86,15 +92,14 @@ export const usePropsAPIRegular = () => { await Promise.all(waitList); modal.confirm({ - title: lang('Bulk update', { ns: 'client' }), - content: - updateMode === 'selected' - ? lang('Update selected data?', { ns: 'client' }) - : lang('Update all data?', { ns: 'client' }), + title: lang('Confirm', { ns: 'client' }), + content: lang('Trigger workflow?', { ns: 'client' }), async onOk() { - run({ + const params = { filterByTk: bindWorkflow, - }); + updateData: encodeURIComponent(JSON.stringify(updateData)), + }; + run(params); actionField.data.loading = false; }, async onCancel() { @@ -104,21 +109,3 @@ export const usePropsAPIRegular = () => { }, }; }; - -function updateData() { - // const updateData: { filter?: any; values: any; forceUpdate: boolean } = { - // values, - // filter, - // forceUpdate: false, - // }; - // if (updateMode === 'selected') { - // if (!selectedRecordKeys?.length) { - // message.error(t('Please select the records to be updated')); - // return; - // } - // updateData.filter = { $and: [{ [rowKey || 'id']: { $in: selectedRecordKeys } }] }; - // } - // if (!updateData.filter) { - // updateData.forceUpdate = true; - // } -} diff --git a/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/kit.ts b/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/kit.ts index 810a2fcc3..b14ddc7a6 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/kit.ts +++ b/packages/plugins/@tachybase/plugin-workflow/src/client/features/api-regular/usage/kit.ts @@ -2,8 +2,8 @@ import { Plugin, useCollection } from '@tachybase/client'; import { tval } from '../../../locale'; import { APIRegularInitializer } from './APIRegular.schema'; -import { APIRegularActionSettings } from './BulkUpdateAction.Settings'; -import { usePropsAPIRegular } from './utils'; +import { APIRegularActionSettings } from './APIRegular.setting'; +import { usePropsAPIRegular } from './hooks'; export class KitAPIRegularUsage extends Plugin { async load() { diff --git a/packages/plugins/@tachybase/plugin-workflow/src/client/nodes/index.tsx b/packages/plugins/@tachybase/plugin-workflow/src/client/nodes/index.tsx index 5e34cff63..dae0c93d9 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/client/nodes/index.tsx +++ b/packages/plugins/@tachybase/plugin-workflow/src/client/nodes/index.tsx @@ -77,7 +77,8 @@ function useUpdateAction() { }, }); ctx.setFormValueChanged(false); - ctx.setVisible(false); + // ctx.setVisible(false); + message.success('success'); refresh(); }, }; @@ -410,7 +411,7 @@ export function NodeDefaultView(props) { ? null : { type: 'void', - 'x-component': 'Action.Drawer.Footer', + 'x-component': 'ActionArea.Footer', properties: { cancel: { title: '{{t("Cancel")}}', diff --git a/packages/plugins/@tachybase/plugin-workflow/src/client/style.tsx b/packages/plugins/@tachybase/plugin-workflow/src/client/style.tsx index 5a14fb16e..d247ee1d5 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/client/style.tsx +++ b/packages/plugins/@tachybase/plugin-workflow/src/client/style.tsx @@ -42,6 +42,7 @@ const useStyles = createStyles(({ css, token }) => { } .workflow-operator-area { + overflow-y: scroll; padding: 8px; background-color: white; width: 800px; diff --git a/packages/plugins/@tachybase/plugin-workflow/src/client/triggers/index.tsx b/packages/plugins/@tachybase/plugin-workflow/src/client/triggers/index.tsx index 0ad758490..9891253f8 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/client/triggers/index.tsx +++ b/packages/plugins/@tachybase/plugin-workflow/src/client/triggers/index.tsx @@ -46,7 +46,8 @@ function useUpdateConfigAction() { }, }); ctx.setFormValueChanged(false); - ctx.setVisible(false); + // ctx.setVisible(false); + message.success('success'); refresh(); }, }; @@ -298,7 +299,7 @@ export const TriggerConfig = () => { ? {} : { type: 'void', - 'x-component': 'Action.Drawer.Footer', + 'x-component': 'ActionArea.Footer', properties: { cancel: { title: '{{t("Cancel")}}', diff --git a/packages/plugins/@tachybase/plugin-workflow/src/server/actions/workflows.ts b/packages/plugins/@tachybase/plugin-workflow/src/server/actions/workflows.ts index 32ef25a97..924b28817 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/server/actions/workflows.ts +++ b/packages/plugins/@tachybase/plugin-workflow/src/server/actions/workflows.ts @@ -164,10 +164,17 @@ export async function sync(context: Context, next) { export async function trigger(ctx: Context) { const plugin = ctx.app.getPlugin(Plugin) as Plugin; const workflow = (await ctx.db.getRepository('workflows').findById(ctx.action.params.filterByTk)) as WorkflowModel; + // NOTE: 这里的updateData是通过前端传过来的,需要 decodeURIComponent, + // updateData 的约定结构是形如: updateData: { primaryKey: "id", targetKeys: []} + const updateData = JSON.parse(decodeURIComponent(ctx.action.params?.updateData || '')); plugin.trigger( workflow, { - data: {}, + data: { + updateData, + httpContext: ctx, + user: ctx?.auth?.user, + }, }, { httpContext: ctx }, ); diff --git a/packages/plugins/@tachybase/plugin-workflow/src/server/features/action-trigger/ActionTrigger.ts b/packages/plugins/@tachybase/plugin-workflow/src/server/features/action-trigger/ActionTrigger.ts index dbea9a9fb..246014c4c 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/server/features/action-trigger/ActionTrigger.ts +++ b/packages/plugins/@tachybase/plugin-workflow/src/server/features/action-trigger/ActionTrigger.ts @@ -1,11 +1,12 @@ -import { get } from 'lodash'; -import { BelongsTo, HasOne } from 'sequelize'; +import { Context as ActionContext, Next } from '@tachybase/actions'; +import { parseCollectionName } from '@tachybase/data-source-manager'; import { Model, modelAssociationByKey } from '@tachybase/database'; import Application, { DefaultContext } from '@tachybase/server'; -import { Context as ActionContext, Next } from '@tachybase/actions'; -import WorkflowPlugin, { Trigger, WorkflowModel, toJSON } from '../..'; -import { parseCollectionName } from '@tachybase/data-source-manager'; +import { get } from 'lodash'; +import { BelongsTo, HasOne } from 'sequelize'; + +import WorkflowPlugin, { toJSON, Trigger, WorkflowModel } from '../..'; interface Context extends ActionContext, DefaultContext {} diff --git a/packages/plugins/@tachybase/plugin-workflow/src/server/features/api-regular/APIRegular.trigger.ts b/packages/plugins/@tachybase/plugin-workflow/src/server/features/api-regular/APIRegular.trigger.ts index c58bf55d7..5e59abcb8 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/server/features/api-regular/APIRegular.trigger.ts +++ b/packages/plugins/@tachybase/plugin-workflow/src/server/features/api-regular/APIRegular.trigger.ts @@ -15,7 +15,7 @@ interface Context extends ActionContext, DefaultContext {} export class APIRegularTrigger extends Trigger { constructor(workflow: WorkflowPlugin) { super(workflow); - workflow.app.use(this.middleware, { after: 'dataSource' }); + // workflow.app.use(this.middleware, { after: 'dataSource' }); } async middleware(context: Context, next: Next) { diff --git a/packages/plugins/@tachybase/plugin-workflow/src/server/features/request/RequestInstruction.ts b/packages/plugins/@tachybase/plugin-workflow/src/server/features/request/RequestInstruction.ts index a10ee2892..dbf914563 100644 --- a/packages/plugins/@tachybase/plugin-workflow/src/server/features/request/RequestInstruction.ts +++ b/packages/plugins/@tachybase/plugin-workflow/src/server/features/request/RequestInstruction.ts @@ -1,4 +1,5 @@ import axios, { AxiosRequestConfig } from 'axios'; +import _ from 'lodash'; import { FlowNodeModel, Instruction, JOB_STATUS, Processor } from '../..'; @@ -12,10 +13,14 @@ export type RequestConfig = Pick { + const { token, origin } = context; + const { url: originUrl, method = 'POST', data, timeout = 5000 } = config; + + const url = originUrl.startsWith('http') ? originUrl : `${origin}${originUrl}`; + + let headers = (config.headers ?? []).reduce((result, header) => { if (header.name.toLowerCase() === 'content-type') { return result; } @@ -29,6 +34,11 @@ async function request(config) { // TODO(feat): only support JSON type for now, should support others in future headers['Content-Type'] = 'application/json'; + // let temp = context.get('headers'); + headers = { + Authorization: 'Bearer ' + token, + ...headers, + }; return axios.request({ url, method, @@ -41,13 +51,19 @@ async function request(config) { export default class extends Instruction { async run(node: FlowNodeModel, prevJob, processor: Processor) { + const httpContext = _.get(processor, 'execution.dataValues.context.data.httpContext', {}); + const userId = _.get(processor, 'execution.dataValues.context.data.user.id', 1); + const origin = _.get(httpContext, 'request.header.origin', ''); + const token = this.workflow.app.authManager.jwt.sign({ userId }); + const context = { token, origin }; + const config = processor.getParsedValue(node.config, node.id) as RequestConfig; const { workflow } = processor.execution; const sync = this.workflow.isWorkflowSync(workflow); if (sync) { try { - const response = await request(config); + const response = await request(config, context); return { status: JOB_STATUS.RESOLVED, @@ -69,7 +85,7 @@ export default class extends Instruction { }); // eslint-disable-next-line promise/catch-or-return - request(config) + request(config, context) .then((response) => { job.set({ status: JOB_STATUS.RESOLVED,