cal.pub0.org/apps/web/ee/components/workflows/WorkflowDetailsPage.tsx

193 lines
6.2 KiB
TypeScript

import { WorkflowActions, WorkflowTemplates } from "@prisma/client";
import { useRouter } from "next/router";
import { useState, useEffect, Dispatch, SetStateAction } from "react";
import { Controller, UseFormReturn } from "react-hook-form";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HttpError } from "@calcom/lib/http-error";
import showToast from "@calcom/lib/notification";
import { Button } from "@calcom/ui";
import { Form } from "@calcom/ui/form/fields";
import { AddActionDialog } from "@ee/components/workflows/AddActionDialog";
import WorkflowStepContainer from "@ee/components/workflows/WorkflowStepContainer";
import { Option, FormValues } from "@ee/pages/workflows/[workflow]";
import { trpc } from "@lib/trpc";
import MultiSelectCheckboxes from "@components/ui/form/MultiSelectCheckboxes";
interface Props {
form: UseFormReturn<FormValues, any>;
workflowId: number;
selectedEventTypes: Option[];
setSelectedEventTypes: Dispatch<SetStateAction<Option[]>>;
}
export default function WorkflowDetailsPage(props: Props) {
const { form, workflowId, selectedEventTypes, setSelectedEventTypes } = props;
const { t } = useLocale();
const router = useRouter();
const utils = trpc.useContext();
const [evenTypeOptions, setEventTypeOptions] = useState<Option[]>([]);
const [isAddActionDialogOpen, setIsAddActionDialogOpen] = useState(false);
const [reload, setReload] = useState(false);
const [editCounter, setEditCounter] = useState(0);
const { data, isLoading } = trpc.useQuery(["viewer.eventTypes"]);
useEffect(() => {
if (data) {
let options: Option[] = [];
data.eventTypeGroups.forEach((group) => {
const eventTypeOptions = group.eventTypes.map((eventType) => {
return { value: String(eventType.id), label: eventType.title };
});
options = [...options, ...eventTypeOptions];
});
setEventTypeOptions(options);
}
}, [isLoading]);
const updateMutation = trpc.useMutation("viewer.workflows.update", {
onSuccess: async ({ workflow }) => {
if (workflow) {
await utils.setQueryData(["viewer.workflows.get", { id: +workflow.id }], workflow);
showToast(
t("workflow_updated_successfully", {
workflowName: workflow.name,
}),
"success"
);
}
await router.push("/workflows");
},
onError: (err) => {
if (err instanceof HttpError) {
const message = `${err.statusCode}: ${err.message}`;
showToast(message, "error");
}
},
});
const addAction = (action: WorkflowActions, sendTo?: string) => {
const steps = form.getValues("steps");
const id =
steps && steps.length > 0
? steps.sort((a, b) => {
return a.id - b.id;
})[0].id - 1
: 0;
const step = {
id: id > 0 ? 0 : id, //id of new steps always <= 0
action,
stepNumber:
steps && steps.length > 0
? steps.sort((a, b) => {
return a.stepNumber - b.stepNumber;
})[steps.length - 1].stepNumber + 1
: 1,
sendTo: sendTo || null,
workflowId: workflowId,
reminderBody: null,
emailSubject: null,
template: WorkflowTemplates.REMINDER,
};
steps?.push(step);
form.setValue("steps", steps);
};
return (
<div>
<Form
form={form}
handleSubmit={async (values) => {
let activeOnEventTypeIds: number[] = [];
if (values.activeOn) {
activeOnEventTypeIds = values.activeOn.map((option) => {
return parseInt(option.value, 10);
});
}
updateMutation.mutate({
id: parseInt(router.query.workflow as string, 10),
name: values.name,
activeOn: activeOnEventTypeIds,
steps: values.steps,
trigger: values.trigger,
time: values.time || null,
timeUnit: values.timeUnit || null,
});
}}>
<div className="-mt-7 space-y-1">
<label htmlFor="label" className="blocktext-sm mb-2 font-medium text-gray-700">
{t("active_on")}:
</label>
<Controller
name="activeOn"
control={form.control}
render={() => {
return (
<MultiSelectCheckboxes
options={evenTypeOptions}
isLoading={isLoading}
setSelected={setSelectedEventTypes}
selected={selectedEventTypes}
setValue={(s: Option[]) => {
form.setValue("activeOn", s);
}}
/>
);
}}
/>
</div>
{/* Workflow Trigger Event & Steps */}
<div className="mt-5 px-5 pt-10 pb-5">
{form.getValues("trigger") && (
<div>
<WorkflowStepContainer form={form} setEditCounter={setEditCounter} editCounter={editCounter} />
</div>
)}
{form.getValues("steps") && (
<>
{form.getValues("steps")?.map((step) => {
return (
<WorkflowStepContainer
key={step.id}
form={form}
step={step}
reload={reload}
setReload={setReload}
setEditCounter={setEditCounter}
editCounter={editCounter}
/>
);
})}
</>
)}
<div className="flex justify-center">
<div className="h-10 border-l-2 border-gray-400" />
</div>
<div className="flex justify-center">
<Button type="button" onClick={() => setIsAddActionDialogOpen(true)} color="secondary">
{t("add_action")}
</Button>
</div>
<div className="rtl:space-x-reverse; mt-10 flex justify-end space-x-2">
<Button type="submit" disabled={updateMutation.isLoading || editCounter > 0}>
{t("save")}
</Button>
</div>
</div>
</Form>
<AddActionDialog
isOpenDialog={isAddActionDialogOpen}
setIsOpenDialog={setIsAddActionDialogOpen}
addAction={addAction}
/>
</div>
);
}