Skip to content

Commit

Permalink
Button to test a workflow action (#3873)
Browse files Browse the repository at this point in the history
* add Test action button + UI improvements

* add test action functionality

* add confirmation dialog before sending SMS

* code clean up

* show error message if test action fails

* disable test action button in edit mode

* fixes SMS testing

* use updated values

* fix wrongly updated data in useEffect

* fix typo

* code clean up

* fix UI issue in mobile view

* small design fix

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Aug 26, 2022
1 parent 6c86317 commit b00402f
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 14 deletions.
8 changes: 8 additions & 0 deletions apps/web/public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,14 @@
"using_additional_inputs_as_variables": "How to use additional inputs as variables?",
"download_desktop_app": "Download desktop app",
"set_ping_link": "Set Ping link",
"when_something_happens": "When something happens",
"action_is_performed": "An action is performed",
"test_action": "Test action",
"notification_sent": "Notification sent",
"no_input": "No input",
"test_workflow_action": "Test workflow action",
"send_sms": "Send SMS",
"send_sms_to_number": "Are you sure you want to send a SMS to {{number}}?",
"missing_connected_calendar": "No default calendar connected",
"connect_your_calendar_and_link": "You can connect your calendar from <1>here</1>.",
"default_calendar_selected": "Default calendar",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ArrowDownIcon } from "@heroicons/react/outline";
import { WorkflowActions, WorkflowTemplates } from "@prisma/client";
import { useRouter } from "next/router";
import { Dispatch, SetStateAction, useMemo, useState } from "react";
Expand Down Expand Up @@ -168,7 +169,7 @@ export default function WorkflowDetailsPage(props: Props) {
</>
)}
<div className="flex justify-center">
<div className="h-10 border-l-2 border-gray-400" />
<ArrowDownIcon className="my-4 h-7 stroke-1 text-gray-500" />
</div>
<div className="flex justify-center">
<Button type="button" onClick={() => setIsAddActionDialogOpen(true)} color="secondary">
Expand Down
102 changes: 90 additions & 12 deletions packages/features/ee/workflows/components/WorkflowStepContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ArrowDownIcon } from "@heroicons/react/outline";
import {
TimeUnit,
WorkflowActions,
Expand All @@ -13,7 +14,12 @@ import "react-phone-number-input/style.css";

import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HttpError } from "@calcom/lib/http-error";
import showToast from "@calcom/lib/notification";
import { trpc } from "@calcom/trpc/react";
import { Button } from "@calcom/ui";
import ConfirmationDialogContent from "@calcom/ui/ConfirmationDialogContent";
import { Dialog } from "@calcom/ui/Dialog";
import Dropdown, { DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@calcom/ui/Dropdown";
import { Icon } from "@calcom/ui/Icon";
import Select from "@calcom/ui/form/Select";
Expand Down Expand Up @@ -49,6 +55,8 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
const [errorMessageNumber, setErrorMessageNumber] = useState("");
const [errorMessageCustomInput, setErrorMessageCustomInput] = useState("");
const [isInfoParagraphOpen, setIsInfoParagraphOpen] = useState(false);
const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);
const [isTestActionDisabled, setIsTestActionDisabled] = useState(false);

const [translatedReminderBody, setTranslatedReminderBody] = useState(
getTranslatedText((step ? form.getValues(`steps.${step.stepNumber - 1}.reminderBody`) : "") || "", {
Expand Down Expand Up @@ -114,6 +122,18 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
}
};

const testActionMutation = trpc.useMutation("viewer.workflows.testAction", {
onSuccess: async () => {
showToast(t("notification_sent"), "success");
},
onError: (err) => {
if (err instanceof HttpError) {
const message = `${err.statusCode}: ${err.message}`;
showToast(message, "error");
}
},
});

//trigger
if (!step) {
const trigger = form.getValues("trigger");
Expand All @@ -127,8 +147,10 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
return (
<>
<div className="flex justify-center">
<div className=" min-w-80 w-[50rem] rounded border-2 border-gray-400 bg-gray-50 px-10 pb-9 pt-5">
<div className="font-bold">{t("triggers")}:</div>
<div className=" min-w-80 w-[50rem] rounded border border-gray-200 bg-white pl-10 pr-12 pb-9 pt-5">
<div className="text-base font-bold">{t("trigger")}</div>
<div className="text-sm text-gray-600">{t("when_something_happens")}</div>
<div className="my-7 border-t border-gray-200" />
<Controller
name="trigger"
control={form.control}
Expand Down Expand Up @@ -206,13 +228,15 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {

return (
<>
<div className="flex justify-center">
<div className="h-10 border-l-2 border-gray-400" />
<div className="flex justify-center ">
<ArrowDownIcon className="my-4 h-7 stroke-1 text-gray-500" />
</div>
<div className="flex justify-center">
<div className="min-w-80 flex w-[50rem] rounded border-2 border-gray-400 bg-gray-50 pl-10 pb-9 ">
<div className=" min-w-80 flex w-[50rem] rounded border border-gray-200 bg-white px-6 pb-9 pt-5 pr-3 sm:px-10">
<div className="w-full pt-5">
<div className="font-bold">{t("action")}:</div>
<div className="text-base font-bold">{t("action")}</div>
<div className="text-sm text-gray-600">{t("action_is_performed")}</div>
<div className="my-7 border-t border-gray-200" />
<div>
<Controller
name={`steps.${step.stepNumber - 1}.action`}
Expand All @@ -229,19 +253,19 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
setIsPhoneNumberNeeded(true);
setEditNumberMode(true);
counter = counter + 1;
setIsTestActionDisabled(true);
} else {
setIsPhoneNumberNeeded(false);
setEditNumberMode(false);
}

if (
form.getValues(`steps.${step.stepNumber - 1}.template`) ===
WorkflowTemplates.CUSTOM
) {
setEditEmailBodyMode(true);
counter = counter + 1;
setIsTestActionDisabled(true);
}

if (
val.value === WorkflowActions.EMAIL_ATTENDEE ||
val.value === WorkflowActions.EMAIL_HOST
Expand Down Expand Up @@ -281,8 +305,10 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
onChange={(newValue) => {
if (newValue) {
setSendTo(newValue);
setErrorMessageNumber("");
} else {
setSendTo("");
}
setErrorMessageNumber("");
}}
placeholder={t("enter_phone_number")}
id="sendTo"
Expand All @@ -300,25 +326,33 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
<Button
type="button"
color="secondary"
className="-ml-3"
onClick={() => {
setEditNumberMode(true);
setEditCounter(editCounter + 1);
setIsTestActionDisabled(true);
}}>
{t("edit")}
</Button>
) : (
<Button
type="button"
color="primary"
className="-ml-3"
onClick={async () => {
if (sendTo) {
form.setValue(`steps.${step.stepNumber - 1}.sendTo`, sendTo);
if (isValidPhoneNumber(sendTo)) {
form.setValue(`steps.${step.stepNumber - 1}.sendTo`, sendTo);
setEditNumberMode(false);
setEditCounter(editCounter - 1);
if (!editEmailBodyMode) {
setIsTestActionDisabled(false);
}
} else {
setErrorMessageNumber(t("invalid_input"));
}
} else {
setErrorMessageNumber(t("no_input"));
}
}}>
{t("save")}
Expand Down Expand Up @@ -474,6 +508,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
onClick={() => {
setEditEmailBodyMode(true);
setEditCounter(editCounter + 1);
setIsTestActionDisabled(true);
}}>
{t("edit")}
</Button>
Expand All @@ -482,8 +517,6 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
type="button"
color="primary"
onClick={async () => {
const reminderBody = form.getValues(`steps.${step.stepNumber - 1}.reminderBody`);
const emailSubject = form.getValues(`steps.${step.stepNumber - 1}.emailSubject`);
let isEmpty = false;
let errorMessage = "";

Expand All @@ -507,6 +540,9 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
if (!isEmpty) {
setEditEmailBodyMode(false);
setEditCounter(editCounter - 1);
if (!editNumberMode) {
setIsTestActionDisabled(false);
}
}
setErrorMessageCustomInput(errorMessage);
}}>
Expand All @@ -515,6 +551,29 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
)}
</>
)}
{form.getValues(`steps.${step.stepNumber - 1}.action`) !== WorkflowActions.SMS_ATTENDEE && (
<Button
type="button"
className="mt-7 w-full"
disabled={isTestActionDisabled}
onClick={() => {
if (
form.getValues(`steps.${step.stepNumber - 1}.action`) !== WorkflowActions.SMS_NUMBER
) {
testActionMutation.mutate({
action: step.action,
emailSubject: step.emailSubject || "",
reminderBody: step.reminderBody || "",
template: step.template,
});
} else {
setConfirmationDialogOpen(true);
}
}}
color="secondary">
<div className="w-full">{t("test_action")}</div>
</Button>
)}
</div>
<div>
<Dropdown>
Expand Down Expand Up @@ -552,6 +611,25 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
</div>
</div>
</div>
<Dialog open={confirmationDialogOpen} onOpenChange={setConfirmationDialogOpen}>
<ConfirmationDialogContent
variety="warning"
title={t("test_workflow_action")}
confirmBtnText={t("send_sms")}
onConfirm={(e) => {
e.preventDefault();
testActionMutation.mutate({
action: step.action,
emailSubject: step.emailSubject || "",
reminderBody: step.reminderBody || "",
template: step.template,
sendTo: step.sendTo || "",
});
setConfirmationDialogOpen(false);
}}>
{t("send_sms_to_number", { number: sendTo })}
</ConfirmationDialogContent>
</Dialog>
</>
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/features/ee/workflows/pages/workflow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ function WorkflowPage() {
});

useEffect(() => {
if (workflow) {
if (workflow && !form.getValues("name")) {
setSelectedEventTypes(
workflow.activeOn.map((active) => ({
value: String(active.eventType.id),
Expand Down
Loading

0 comments on commit b00402f

Please sign in to comment.