feat/feat-apiselected (#1132)
Reviewed-on: daoyoucloud/tachybase#1132 Co-authored-by: bai.zixv <bai.zixv@foxmail.com> Co-committed-by: bai.zixv <bai.zixv@foxmail.com>
This commit is contained in:
parent
6df452378f
commit
03a1dfdf1e
@ -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(
|
||||
|
@ -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',
|
||||
|
@ -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;
|
||||
// }
|
||||
}
|
@ -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() {
|
||||
|
@ -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")}}',
|
||||
|
@ -42,6 +42,7 @@ const useStyles = createStyles(({ css, token }) => {
|
||||
}
|
||||
|
||||
.workflow-operator-area {
|
||||
overflow-y: scroll;
|
||||
padding: 8px;
|
||||
background-color: white;
|
||||
width: 800px;
|
||||
|
@ -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")}}',
|
||||
|
@ -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 },
|
||||
);
|
||||
|
@ -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 {}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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<AxiosRequestConfig, 'url' | 'method' | 'params'
|
||||
ignoreFail: boolean;
|
||||
};
|
||||
|
||||
async function request(config) {
|
||||
async function request(config, context) {
|
||||
// default headers
|
||||
const { url, method = 'POST', data, timeout = 5000 } = config;
|
||||
const headers = (config.headers ?? []).reduce((result, header) => {
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user