mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
feat: add support for manual workflow execution arguments in various components
This commit is contained in:
@@ -29,7 +29,10 @@ import WorkspaceUserAuthTokenService from "./WorkspaceUserAuthTokenService";
|
||||
import WorkspaceMessagePayload, {
|
||||
WorkspaceMessageBlock,
|
||||
} from "../../Types/Workspace/WorkspaceMessagePayload";
|
||||
import WorkspaceProjectAuthToken, { MiscData, SlackMiscData } from "../../Models/DatabaseModels/WorkspaceProjectAuthToken";
|
||||
import WorkspaceProjectAuthToken, {
|
||||
MiscData,
|
||||
SlackMiscData,
|
||||
} from "../../Models/DatabaseModels/WorkspaceProjectAuthToken";
|
||||
import WorkspaceProjectAuthTokenService from "./WorkspaceProjectAuthTokenService";
|
||||
import logger from "../Utils/Logger";
|
||||
|
||||
@@ -52,14 +55,16 @@ export class Service extends DatabaseService<Model> {
|
||||
const miscData: MiscData | undefined = data.projectAuthToken.miscData;
|
||||
|
||||
if (!miscData) {
|
||||
throw new BadDataException("Misc data not found in project auth token");
|
||||
throw new BadDataException("Misc data not found in project auth token");
|
||||
}
|
||||
|
||||
if(data.workspaceType === WorkspaceType.Slack) {
|
||||
const userId: string = (miscData as SlackMiscData).botUserId;
|
||||
if (data.workspaceType === WorkspaceType.Slack) {
|
||||
const userId: string = (miscData as SlackMiscData).botUserId;
|
||||
|
||||
if (!userId) {
|
||||
throw new BadDataException("Bot user ID not found in project auth token");
|
||||
throw new BadDataException(
|
||||
"Bot user ID not found in project auth token",
|
||||
);
|
||||
}
|
||||
|
||||
return userId;
|
||||
@@ -68,7 +73,6 @@ export class Service extends DatabaseService<Model> {
|
||||
throw new BadDataException("Workspace type not supported");
|
||||
}
|
||||
|
||||
|
||||
public async createInviteAndPostToChannelsBasedOnRules(data: {
|
||||
projectId: ObjectID;
|
||||
notificationRuleEventType: NotificationRuleEventType;
|
||||
|
||||
@@ -74,7 +74,15 @@ export default class OnTriggerBaseModel<
|
||||
args: JSONObject,
|
||||
options: RunOptions,
|
||||
): Promise<RunReturnType> {
|
||||
const data: JSONObject = args["data"] as JSONObject;
|
||||
let data: JSONObject = args["data"] as JSONObject;
|
||||
|
||||
if (!data) {
|
||||
data = {};
|
||||
}
|
||||
|
||||
if (args["_id"]) {
|
||||
data["_id"] = args["_id"];
|
||||
}
|
||||
|
||||
const miscData: JSONObject = (data?.["miscData"] as JSONObject) || {};
|
||||
|
||||
@@ -106,14 +114,15 @@ export default class OnTriggerBaseModel<
|
||||
|
||||
let select: Select<TBaseModel> = args["select"] as Select<TBaseModel>;
|
||||
|
||||
if (select) {
|
||||
select = JSONFunctions.deserialize(
|
||||
args["select"] as JSONObject,
|
||||
) as Select<TBaseModel>;
|
||||
logger.debug("Select: ");
|
||||
logger.debug(select);
|
||||
|
||||
if (select && typeof select === "string") {
|
||||
select = JSONFunctions.parse(select) as Select<TBaseModel>;
|
||||
}
|
||||
|
||||
const model: TBaseModel | null = await this.service!.findOneById({
|
||||
id: new ObjectID(data["_id"] as string),
|
||||
id: new ObjectID(data["_id"].toString()),
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
@@ -124,8 +133,10 @@ export default class OnTriggerBaseModel<
|
||||
});
|
||||
|
||||
if (!model) {
|
||||
options.log("Model not found with id " + data["_id"].toString());
|
||||
|
||||
throw new BadDataException(
|
||||
("Model not found with id " + args["_id"]) as string,
|
||||
("Model not found with id " + data["_id"].toString()) as string,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import WorkspaceBase, { WorkspaceChannel } from "../WorkspaceBase";
|
||||
import WorkspaceType from "../../../../Types/Workspace/WorkspaceType";
|
||||
|
||||
export default class SlackUtil extends WorkspaceBase {
|
||||
|
||||
public static override async joinChannel(data: {
|
||||
authToken: string;
|
||||
channelId: string;
|
||||
@@ -24,16 +23,17 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
logger.debug(data);
|
||||
|
||||
// Join channel
|
||||
const response = await API.post(
|
||||
URL.fromString("https://slack.com/api/conversations.join"),
|
||||
{
|
||||
channel: data.channelId,
|
||||
},
|
||||
{
|
||||
Authorization: `Bearer ${data.authToken}`,
|
||||
['Content-Type']: "application/x-www-form-urlencoded",
|
||||
},
|
||||
);
|
||||
const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
|
||||
await API.post(
|
||||
URL.fromString("https://slack.com/api/conversations.join"),
|
||||
{
|
||||
channel: data.channelId,
|
||||
},
|
||||
{
|
||||
Authorization: `Bearer ${data.authToken}`,
|
||||
["Content-Type"]: "application/x-www-form-urlencoded",
|
||||
},
|
||||
);
|
||||
|
||||
logger.debug("Response from Slack API for joining channel:");
|
||||
logger.debug(response);
|
||||
@@ -52,7 +52,6 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
|
||||
logger.debug("Channel joined successfully with data:");
|
||||
logger.debug(data);
|
||||
|
||||
}
|
||||
|
||||
public static override async inviteUserToChannelByChannelId(data: {
|
||||
@@ -72,7 +71,7 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
},
|
||||
{
|
||||
Authorization: `Bearer ${data.authToken}`,
|
||||
['Content-Type']: "application/x-www-form-urlencoded",
|
||||
["Content-Type"]: "application/x-www-form-urlencoded",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -99,8 +98,7 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
channelName: string;
|
||||
workspaceUserId: string;
|
||||
}): Promise<void> {
|
||||
|
||||
if(data.channelName && data.channelName.startsWith("#")) {
|
||||
if (data.channelName && data.channelName.startsWith("#")) {
|
||||
// trim # from channel name
|
||||
data.channelName = data.channelName.substring(1);
|
||||
}
|
||||
@@ -139,9 +137,8 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
logger.debug(existingWorkspaceChannels);
|
||||
|
||||
for (let channelName of data.channelNames) {
|
||||
|
||||
// if channel name starts with #, remove it
|
||||
if(channelName && channelName.startsWith("#")) {
|
||||
if (channelName && channelName.startsWith("#")) {
|
||||
channelName = channelName.substring(1);
|
||||
}
|
||||
|
||||
@@ -168,7 +165,6 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
return workspaceChannels;
|
||||
}
|
||||
|
||||
|
||||
public static override async getWorkspaceChannelFromChannelName(data: {
|
||||
authToken: string;
|
||||
channelName: string;
|
||||
@@ -176,9 +172,10 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
logger.debug("Getting workspace channel ID from channel name with data:");
|
||||
logger.debug(data);
|
||||
|
||||
const channels: Dictionary<WorkspaceChannel> = await this.getAllWorkspaceChannels({
|
||||
authToken: data.authToken,
|
||||
});
|
||||
const channels: Dictionary<WorkspaceChannel> =
|
||||
await this.getAllWorkspaceChannels({
|
||||
authToken: data.authToken,
|
||||
});
|
||||
|
||||
logger.debug("All workspace channels:");
|
||||
logger.debug(channels);
|
||||
@@ -191,7 +188,7 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
logger.debug("Workspace channel ID obtained:");
|
||||
logger.debug(channels[data.channelName]!.id);
|
||||
|
||||
return channels[data.channelName]!;
|
||||
return channels[data.channelName]!;
|
||||
}
|
||||
|
||||
public static override async getWorkspaceChannelFromChannelId(data: {
|
||||
@@ -209,7 +206,7 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
},
|
||||
{
|
||||
Authorization: `Bearer ${data.authToken}`,
|
||||
['Content-Type']: "application/x-www-form-urlencoded",
|
||||
["Content-Type"]: "application/x-www-form-urlencoded",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -262,7 +259,7 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
{},
|
||||
{
|
||||
Authorization: `Bearer ${data.authToken}`,
|
||||
['Content-Type']: "application/x-www-form-urlencoded",
|
||||
["Content-Type"]: "application/x-www-form-urlencoded",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -329,8 +326,7 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
const channelIdsToPostTo: Array<string> = [];
|
||||
|
||||
for (let channelName of data.workspaceMessagePayload.channelNames) {
|
||||
|
||||
if(channelName && channelName.startsWith("#")) {
|
||||
if (channelName && channelName.startsWith("#")) {
|
||||
// trim # from channel name
|
||||
channelName = channelName.substring(1);
|
||||
}
|
||||
@@ -353,19 +349,18 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
|
||||
for (const channelId of channelIdsToPostTo) {
|
||||
try {
|
||||
|
||||
// check if the user is in the channel.
|
||||
const isUserInChannel = await this.isUserInChannel({
|
||||
// check if the user is in the channel.
|
||||
const isUserInChannel: boolean = await this.isUserInChannel({
|
||||
authToken: data.authToken,
|
||||
channelId: channelId,
|
||||
userId: data.userId,
|
||||
});
|
||||
|
||||
if(!isUserInChannel) {
|
||||
// add user to the channel
|
||||
if (!isUserInChannel) {
|
||||
// add user to the channel
|
||||
await this.joinChannel({
|
||||
authToken: data.authToken,
|
||||
channelId: channelId
|
||||
channelId: channelId,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -376,7 +371,6 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
});
|
||||
|
||||
logger.debug(`Message sent to channel ID ${channelId} successfully.`);
|
||||
|
||||
} catch (e) {
|
||||
logger.error(`Error sending message to channel ID ${channelId}:`);
|
||||
logger.error(e);
|
||||
@@ -401,7 +395,7 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
},
|
||||
{
|
||||
Authorization: `Bearer ${data.authToken}`,
|
||||
['Content-Type']: "application/json",
|
||||
["Content-Type"]: "application/json",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -438,7 +432,7 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
},
|
||||
{
|
||||
Authorization: `Bearer ${data.authToken}`,
|
||||
['Content-Type']: "application/x-www-form-urlencoded",
|
||||
["Content-Type"]: "application/x-www-form-urlencoded",
|
||||
},
|
||||
);
|
||||
|
||||
@@ -520,15 +514,12 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
return markdownBlock;
|
||||
}
|
||||
|
||||
|
||||
public static override async isUserInChannel(data: {
|
||||
authToken: string;
|
||||
channelId: string;
|
||||
userId: string;
|
||||
}): Promise<boolean> {
|
||||
|
||||
|
||||
const members: Array<string> = [];
|
||||
const members: Array<string> = [];
|
||||
|
||||
logger.debug("Checking if user is in channel with data:");
|
||||
logger.debug(data);
|
||||
@@ -536,63 +527,61 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
let cursor: string | undefined = undefined;
|
||||
|
||||
do {
|
||||
|
||||
// check if the user is in the channel, return true if they are, false if they are not
|
||||
// check if the user is in the channel, return true if they are, false if they are not
|
||||
|
||||
const requestBody: JSONObject = {
|
||||
channel: data.channelId,
|
||||
limit: 1000,
|
||||
};
|
||||
const requestBody: JSONObject = {
|
||||
channel: data.channelId,
|
||||
limit: 1000,
|
||||
};
|
||||
|
||||
if(cursor) {
|
||||
requestBody["cursor"] = cursor;
|
||||
}
|
||||
if (cursor) {
|
||||
requestBody["cursor"] = cursor;
|
||||
}
|
||||
|
||||
const response: HTTPErrorResponse | HTTPResponse<JSONObject> = await API.post<JSONObject>(
|
||||
URL.fromString("https://slack.com/api/conversations.members"),
|
||||
requestBody,
|
||||
{
|
||||
Authorization: `Bearer ${data.authToken}`,
|
||||
['Content-Type']: "application/x-www-form-urlencoded",
|
||||
},
|
||||
);
|
||||
const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
|
||||
await API.post<JSONObject>(
|
||||
URL.fromString("https://slack.com/api/conversations.members"),
|
||||
requestBody,
|
||||
{
|
||||
Authorization: `Bearer ${data.authToken}`,
|
||||
["Content-Type"]: "application/x-www-form-urlencoded",
|
||||
},
|
||||
);
|
||||
|
||||
logger.debug("Response from Slack API for getting channel members:");
|
||||
logger.debug(response);
|
||||
logger.debug("Response from Slack API for getting channel members:");
|
||||
logger.debug(response);
|
||||
|
||||
if (response instanceof HTTPErrorResponse) {
|
||||
logger.error("Error response from Slack API:");
|
||||
logger.error(response);
|
||||
throw response;
|
||||
}
|
||||
if (response instanceof HTTPErrorResponse) {
|
||||
logger.error("Error response from Slack API:");
|
||||
logger.error(response);
|
||||
throw response;
|
||||
}
|
||||
|
||||
// check for ok response
|
||||
|
||||
// check for ok response
|
||||
if ((response.jsonData as JSONObject)?.["ok"] !== true) {
|
||||
logger.error("Invalid response from Slack API:");
|
||||
logger.error(response.jsonData);
|
||||
throw new BadRequestException("Invalid response");
|
||||
}
|
||||
|
||||
if ((response.jsonData as JSONObject)?.["ok"] !== true) {
|
||||
logger.error("Invalid response from Slack API:");
|
||||
logger.error(response.jsonData);
|
||||
throw new BadRequestException("Invalid response");
|
||||
}
|
||||
// check if the user is in the channel
|
||||
const membersOnThisPage: Array<string> = (
|
||||
response.jsonData as JSONObject
|
||||
)["members"] as Array<string>;
|
||||
|
||||
// check if the user is in the channel
|
||||
const membersOnThisPage: Array<string> = (response.jsonData as JSONObject)["members"] as Array<string>;
|
||||
members.push(...membersOnThisPage);
|
||||
|
||||
members.push(...membersOnThisPage);
|
||||
cursor = (
|
||||
(response.jsonData as JSONObject)["response_metadata"] as JSONObject
|
||||
)?.["next_cursor"] as string;
|
||||
} while (cursor);
|
||||
|
||||
cursor = ((response.jsonData as JSONObject)["response_metadata"] as JSONObject)?.["next_cursor"] as string;
|
||||
|
||||
} while(cursor);
|
||||
|
||||
|
||||
|
||||
if(members.includes(data.userId)) {
|
||||
if (members.includes(data.userId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static override getButtonBlock(data: {
|
||||
@@ -623,17 +612,18 @@ export default class SlackUtil extends WorkspaceBase {
|
||||
logger.debug("Sending message to channel via incoming webhook with data:");
|
||||
logger.debug(data);
|
||||
|
||||
const apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse | null = await API.post(data.url, {
|
||||
blocks: [
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: `${data.text}`,
|
||||
const apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse | null =
|
||||
await API.post(data.url, {
|
||||
blocks: [
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: `${data.text}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
],
|
||||
});
|
||||
|
||||
logger.debug("Response from Slack API for sending message via webhook:");
|
||||
logger.debug(apiResult);
|
||||
|
||||
@@ -21,7 +21,6 @@ export interface WorkspaceChannel {
|
||||
}
|
||||
|
||||
export default class WorkspaceBase {
|
||||
|
||||
public static async joinChannel(_data: {
|
||||
authToken: string;
|
||||
channelId: string;
|
||||
@@ -78,8 +77,7 @@ export default class WorkspaceBase {
|
||||
authToken: string;
|
||||
channelId: string;
|
||||
workspaceUserId: string;
|
||||
}): Promise<void> {
|
||||
}
|
||||
}): Promise<void> {}
|
||||
|
||||
public static async createChannelsIfDoesNotExist(_data: {
|
||||
authToken: string;
|
||||
|
||||
@@ -90,6 +90,7 @@ export default interface ComponentMetadata {
|
||||
outPorts: Array<Port>;
|
||||
tableName?: string | undefined;
|
||||
documentationLink?: Route;
|
||||
runWorkflowManuallyArguments?: Array<Argument> | undefined;
|
||||
}
|
||||
|
||||
export interface ComponentCategory {
|
||||
|
||||
@@ -157,6 +157,16 @@ export default class BaseModelComponent {
|
||||
iconProp: IconProp.Bolt,
|
||||
tableName: model.tableName!,
|
||||
componentType: ComponentType.Trigger,
|
||||
runWorkflowManuallyArguments: [
|
||||
{
|
||||
type: ComponentInputType.Text,
|
||||
name: `${model.singularName} ID`,
|
||||
description: `Please provide the ID of the ${model.singularName}, if you wish to run this workflow manually.`,
|
||||
required: true,
|
||||
id: "_id",
|
||||
placeholder: `ID of the ${model.singularName}`,
|
||||
},
|
||||
],
|
||||
arguments: [],
|
||||
returnValues: [
|
||||
{
|
||||
@@ -288,6 +298,16 @@ export default class BaseModelComponent {
|
||||
iconProp: IconProp.Bolt,
|
||||
tableName: model.tableName!,
|
||||
componentType: ComponentType.Trigger,
|
||||
runWorkflowManuallyArguments: [
|
||||
{
|
||||
type: ComponentInputType.Text,
|
||||
name: `${model.singularName} ID`,
|
||||
description: `Please provide the ID of the ${model.singularName}, if you wish to run this workflow manually.`,
|
||||
required: true,
|
||||
id: "_id",
|
||||
placeholder: `ID of the ${model.singularName}`,
|
||||
},
|
||||
],
|
||||
arguments: [
|
||||
{
|
||||
type: ComponentInputType.Select,
|
||||
@@ -430,6 +450,16 @@ export default class BaseModelComponent {
|
||||
iconProp: IconProp.Bolt,
|
||||
tableName: model.tableName!,
|
||||
componentType: ComponentType.Trigger,
|
||||
runWorkflowManuallyArguments: [
|
||||
{
|
||||
type: ComponentInputType.Text,
|
||||
name: `${model.singularName} ID`,
|
||||
description: `Please provide the ID of the ${model.singularName}, if you wish to run this workflow manually.`,
|
||||
required: true,
|
||||
id: "_id",
|
||||
placeholder: `ID of the ${model.singularName}`,
|
||||
},
|
||||
],
|
||||
arguments: [
|
||||
{
|
||||
type: ComponentInputType.Select,
|
||||
|
||||
@@ -13,6 +13,7 @@ const components: Array<ComponentMetadata> = [
|
||||
description: "Run this workflow on particular schedule",
|
||||
iconProp: IconProp.Clock,
|
||||
componentType: ComponentType.Trigger,
|
||||
runWorkflowManuallyArguments: [],
|
||||
arguments: [
|
||||
{
|
||||
type: ComponentInputType.CronTab,
|
||||
|
||||
@@ -17,6 +17,32 @@ const components: Array<ComponentMetadata> = [
|
||||
componentType: ComponentType.Trigger,
|
||||
documentationLink: Route.fromString("/workflow/docs/Webhook.md"),
|
||||
arguments: [],
|
||||
runWorkflowManuallyArguments: [
|
||||
{
|
||||
id: "request-headers",
|
||||
name: "Request Headers",
|
||||
description: "Request Headers for this request",
|
||||
type: ComponentInputType.StringDictionary,
|
||||
required: false,
|
||||
placeholder: '{"header1": "value1", "header2": "value2", ....}',
|
||||
},
|
||||
{
|
||||
id: "request-params",
|
||||
name: "Request Query Params",
|
||||
description: "Request Query Params for this request",
|
||||
type: ComponentInputType.StringDictionary,
|
||||
required: false,
|
||||
placeholder: '{"query1": "value1", "query2": "value2", ....}',
|
||||
},
|
||||
{
|
||||
id: "request-body",
|
||||
name: "Request Body",
|
||||
description: "Request Body",
|
||||
type: ComponentInputType.JSON,
|
||||
required: false,
|
||||
placeholder: '{"key1": "value1", "key2": "value2", ....}',
|
||||
},
|
||||
],
|
||||
returnValues: [
|
||||
{
|
||||
id: "request-headers",
|
||||
|
||||
@@ -3,7 +3,7 @@ import BasicForm, { FormProps } from "../Forms/BasicForm";
|
||||
import FormValues from "../Forms/Types/FormValues";
|
||||
import { componentInputTypeToFormFieldType } from "./Utils";
|
||||
import { JSONObject } from "Common/Types/JSON";
|
||||
import { NodeDataProp, ReturnValue } from "Common/Types/Workflow/Component";
|
||||
import { Argument, NodeDataProp } from "Common/Types/Workflow/Component";
|
||||
import React, {
|
||||
FunctionComponent,
|
||||
ReactElement,
|
||||
@@ -38,34 +38,32 @@ const RunForm: FunctionComponent<ComponentProps> = (
|
||||
<div className="mb-3 mt-3">
|
||||
<div className="mt-5 mb-5">
|
||||
<h2 className="text-base font-medium text-gray-500">
|
||||
Return Values from Trigger
|
||||
Run {component.metadata.title}
|
||||
</h2>
|
||||
<p className="text-sm font-medium text-gray-400 mb-5">
|
||||
This workflow has a trigger to get it to run. Since this trigger
|
||||
returns some values to work. You can pass these return values from
|
||||
trigger manually and test this workflow.
|
||||
{component.metadata.description}
|
||||
</p>
|
||||
{component.metadata.returnValues &&
|
||||
component.metadata.returnValues.length === 0 && (
|
||||
{component.metadata.runWorkflowManuallyArguments &&
|
||||
component.metadata.runWorkflowManuallyArguments.length === 0 && (
|
||||
<ErrorMessage
|
||||
message={
|
||||
'This workflow trigger does not take any return values. You can run it by clicking the "Run" button below.'
|
||||
'This workflow trigger does not take any values. You can run it by clicking the "Run" button below.'
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{component.metadata.returnValues &&
|
||||
component.metadata.returnValues.length > 0 && (
|
||||
{component.metadata.runWorkflowManuallyArguments &&
|
||||
component.metadata.runWorkflowManuallyArguments.length > 0 && (
|
||||
<BasicForm
|
||||
hideSubmitButton={true}
|
||||
ref={formRef}
|
||||
initialValues={{
|
||||
...(component.returnValues || {}),
|
||||
...(component.arguments || {}),
|
||||
}}
|
||||
onChange={(values: FormValues<JSONObject>) => {
|
||||
setComponent({
|
||||
...component,
|
||||
returnValues: {
|
||||
...((component.returnValues as JSONObject) || {}),
|
||||
arguments: {
|
||||
...((component.arguments as JSONObject) || {}),
|
||||
...((values as JSONObject) || {}),
|
||||
},
|
||||
});
|
||||
@@ -74,25 +72,25 @@ const RunForm: FunctionComponent<ComponentProps> = (
|
||||
setHasFormValidationErrors(hasError);
|
||||
}}
|
||||
fields={
|
||||
component.metadata.returnValues &&
|
||||
component.metadata.returnValues.map(
|
||||
(returnValue: ReturnValue) => {
|
||||
component.metadata.runWorkflowManuallyArguments &&
|
||||
component.metadata.runWorkflowManuallyArguments.map(
|
||||
(argument: Argument) => {
|
||||
return {
|
||||
title: `${returnValue.name}`,
|
||||
title: `${argument.name}`,
|
||||
|
||||
description: `${
|
||||
returnValue.required ? "Required" : "Optional"
|
||||
}. ${returnValue.description}`,
|
||||
argument.required ? "Required" : "Optional"
|
||||
}. ${argument.description}`,
|
||||
field: {
|
||||
[returnValue.id]: true,
|
||||
[argument.id]: true,
|
||||
},
|
||||
required: returnValue.required,
|
||||
placeholder: returnValue.placeholder,
|
||||
required: argument.required,
|
||||
placeholder: argument.placeholder,
|
||||
...componentInputTypeToFormFieldType(
|
||||
returnValue.type,
|
||||
argument.type,
|
||||
component.returnValues &&
|
||||
component.returnValues[returnValue.id]
|
||||
? component.returnValues[returnValue.id]
|
||||
component.returnValues[argument.id]
|
||||
? component.returnValues[argument.id]
|
||||
: null,
|
||||
),
|
||||
};
|
||||
|
||||
@@ -312,16 +312,17 @@ const Delete: FunctionComponent<PageComponentProps> = (): ReactElement => {
|
||||
}}
|
||||
onRun={async (component: NodeDataProp) => {
|
||||
try {
|
||||
const result: HTTPErrorResponse | HTTPResponse<JSONObject> = await API.post(
|
||||
URL.fromString(WORKFLOW_URL.toString()).addRoute(
|
||||
"/manual/run/" + modelId.toString(),
|
||||
),
|
||||
{
|
||||
data: component.returnValues,
|
||||
},
|
||||
);
|
||||
const result: HTTPErrorResponse | HTTPResponse<JSONObject> =
|
||||
await API.post(
|
||||
URL.fromString(WORKFLOW_URL.toString()).addRoute(
|
||||
"/manual/run/" + modelId.toString(),
|
||||
),
|
||||
{
|
||||
data: component.arguments,
|
||||
},
|
||||
);
|
||||
|
||||
if(result instanceof HTTPErrorResponse) {
|
||||
if (result instanceof HTTPErrorResponse) {
|
||||
throw result;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,8 @@ export default class ManualAPI {
|
||||
public async manuallyRunWorkflow(
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
next: NextFunction
|
||||
next: NextFunction,
|
||||
): Promise<void> {
|
||||
|
||||
try {
|
||||
// add this workflow to the run queue and return the 200 response.
|
||||
|
||||
@@ -45,7 +44,6 @@ export default class ManualAPI {
|
||||
return Response.sendJsonObjectResponse(req, res, {
|
||||
status: "Scheduled",
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user