2022-07-14 00:10:45 +00:00
|
|
|
import { WorkflowActions, WorkflowTemplates } from "@prisma/client";
|
|
|
|
import { useRouter } from "next/router";
|
2022-07-28 19:58:26 +00:00
|
|
|
import { Dispatch, SetStateAction, useMemo, useState } from "react";
|
2022-07-14 00:10:45 +00:00
|
|
|
import { Controller, UseFormReturn } from "react-hook-form";
|
|
|
|
|
|
|
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
2022-07-22 17:27:06 +00:00
|
|
|
import { trpc } from "@calcom/trpc/react";
|
2022-11-23 02:55:25 +00:00
|
|
|
import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery";
|
|
|
|
import { Icon } from "@calcom/ui";
|
|
|
|
import { Button, Label, TextField } from "@calcom/ui";
|
|
|
|
import { MultiSelectCheckboxes } from "@calcom/ui";
|
|
|
|
import type { MultiSelectCheckboxesOptionType as Option } from "@calcom/ui";
|
2022-07-14 00:10:45 +00:00
|
|
|
|
2022-07-28 19:58:26 +00:00
|
|
|
import type { FormValues } from "../pages/workflow";
|
|
|
|
import { AddActionDialog } from "./AddActionDialog";
|
2022-11-23 02:55:25 +00:00
|
|
|
import { DeleteDialog } from "./DeleteDialog";
|
2022-07-28 19:58:26 +00:00
|
|
|
import WorkflowStepContainer from "./WorkflowStepContainer";
|
2022-07-14 00:10:45 +00:00
|
|
|
|
|
|
|
interface Props {
|
2022-07-20 19:48:40 +00:00
|
|
|
form: UseFormReturn<FormValues>;
|
2022-07-14 00:10:45 +00:00
|
|
|
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();
|
2022-11-23 02:55:25 +00:00
|
|
|
|
|
|
|
const me = useMeQuery();
|
|
|
|
const isFreeUser = me.data?.plan === "FREE";
|
2022-07-14 00:10:45 +00:00
|
|
|
|
|
|
|
const [isAddActionDialogOpen, setIsAddActionDialogOpen] = useState(false);
|
|
|
|
const [reload, setReload] = useState(false);
|
2022-11-23 02:55:25 +00:00
|
|
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
2022-07-14 00:10:45 +00:00
|
|
|
|
2022-11-10 23:40:01 +00:00
|
|
|
const { data, isLoading } = trpc.viewer.eventTypes.getByViewer.useQuery();
|
2022-07-14 00:10:45 +00:00
|
|
|
|
2022-07-20 19:48:40 +00:00
|
|
|
const eventTypeOptions = useMemo(
|
|
|
|
() =>
|
|
|
|
data?.eventTypeGroups.reduce(
|
|
|
|
(options, group) => [
|
|
|
|
...options,
|
|
|
|
...group.eventTypes.map((eventType) => ({
|
|
|
|
value: String(eventType.id),
|
|
|
|
label: eventType.title,
|
|
|
|
})),
|
|
|
|
],
|
|
|
|
[] as Option[]
|
|
|
|
) || [],
|
|
|
|
[data]
|
|
|
|
);
|
2022-07-14 00:10:45 +00:00
|
|
|
|
2022-11-23 02:55:25 +00:00
|
|
|
const addAction = (action: WorkflowActions, sendTo?: string, numberRequired?: boolean, sender?: string) => {
|
2022-07-14 00:10:45 +00:00
|
|
|
const steps = form.getValues("steps");
|
|
|
|
const id =
|
2022-07-20 19:48:40 +00:00
|
|
|
steps?.length > 0
|
2022-07-14 00:10:45 +00:00
|
|
|
? 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,
|
2022-11-23 02:55:25 +00:00
|
|
|
template: WorkflowTemplates.CUSTOM,
|
|
|
|
numberRequired: numberRequired || false,
|
|
|
|
sender: sender || "Cal",
|
2022-07-14 00:10:45 +00:00
|
|
|
};
|
|
|
|
steps?.push(step);
|
|
|
|
form.setValue("steps", steps);
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2022-11-23 02:55:25 +00:00
|
|
|
<>
|
|
|
|
<div className="my-8 sm:my-0 md:flex">
|
|
|
|
<div className="pl-2 pr-3 md:sticky md:top-6 md:h-0 md:pl-0">
|
|
|
|
<div className="mb-5">
|
|
|
|
<TextField label={`${t("workflow_name")}:`} type="text" {...form.register("name")} />
|
|
|
|
</div>
|
|
|
|
<Label>{t("which_event_type_apply")}</Label>
|
2022-07-14 00:10:45 +00:00
|
|
|
<Controller
|
|
|
|
name="activeOn"
|
|
|
|
control={form.control}
|
|
|
|
render={() => {
|
|
|
|
return (
|
|
|
|
<MultiSelectCheckboxes
|
2022-07-20 19:48:40 +00:00
|
|
|
options={eventTypeOptions}
|
2022-07-14 00:10:45 +00:00
|
|
|
isLoading={isLoading}
|
2022-11-23 02:55:25 +00:00
|
|
|
className="w-full md:w-64"
|
2022-07-14 00:10:45 +00:00
|
|
|
setSelected={setSelectedEventTypes}
|
|
|
|
selected={selectedEventTypes}
|
|
|
|
setValue={(s: Option[]) => {
|
|
|
|
form.setValue("activeOn", s);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}}
|
|
|
|
/>
|
2022-11-23 02:55:25 +00:00
|
|
|
<div className="my-7 border-transparent md:border-t md:border-gray-200" />
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
StartIcon={Icon.FiTrash2}
|
|
|
|
color="destructive"
|
|
|
|
className="border"
|
|
|
|
onClick={() => setDeleteDialogOpen(true)}>
|
|
|
|
{t("delete_workflow")}
|
|
|
|
</Button>
|
|
|
|
<div className="my-7 border-t border-gray-200 md:border-none" />
|
2022-07-14 00:10:45 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
{/* Workflow Trigger Event & Steps */}
|
2022-11-23 02:55:25 +00:00
|
|
|
<div className="w-full rounded-md border border-gray-200 bg-gray-50 p-3 py-5 md:ml-3 md:p-8">
|
2022-07-14 00:10:45 +00:00
|
|
|
{form.getValues("trigger") && (
|
|
|
|
<div>
|
2022-11-23 02:55:25 +00:00
|
|
|
<WorkflowStepContainer form={form} isFreeUser={isFreeUser} />
|
2022-07-14 00:10:45 +00:00
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
{form.getValues("steps") && (
|
|
|
|
<>
|
|
|
|
{form.getValues("steps")?.map((step) => {
|
|
|
|
return (
|
|
|
|
<WorkflowStepContainer
|
|
|
|
key={step.id}
|
|
|
|
form={form}
|
|
|
|
step={step}
|
|
|
|
reload={reload}
|
|
|
|
setReload={setReload}
|
2022-11-23 02:55:25 +00:00
|
|
|
isFreeUser={isFreeUser}
|
2022-07-14 00:10:45 +00:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</>
|
|
|
|
)}
|
2022-11-23 02:55:25 +00:00
|
|
|
<div className="my-3 flex justify-center">
|
|
|
|
<Icon.FiArrowDown className="stroke-[1.5px] text-3xl text-gray-500" />
|
2022-07-14 00:10:45 +00:00
|
|
|
</div>
|
|
|
|
<div className="flex justify-center">
|
|
|
|
<Button type="button" onClick={() => setIsAddActionDialogOpen(true)} color="secondary">
|
|
|
|
{t("add_action")}
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
</div>
|
2022-11-23 02:55:25 +00:00
|
|
|
</div>
|
2022-07-14 00:10:45 +00:00
|
|
|
<AddActionDialog
|
|
|
|
isOpenDialog={isAddActionDialogOpen}
|
|
|
|
setIsOpenDialog={setIsAddActionDialogOpen}
|
|
|
|
addAction={addAction}
|
2022-11-23 02:55:25 +00:00
|
|
|
isFreeUser={isFreeUser}
|
|
|
|
/>
|
|
|
|
<DeleteDialog
|
|
|
|
isOpenDialog={deleteDialogOpen}
|
|
|
|
setIsOpenDialog={setDeleteDialogOpen}
|
|
|
|
workflowId={workflowId}
|
|
|
|
additionalFunction={async () => await router.push("/workflows")}
|
2022-07-14 00:10:45 +00:00
|
|
|
/>
|
2022-11-23 02:55:25 +00:00
|
|
|
</>
|
2022-07-14 00:10:45 +00:00
|
|
|
);
|
|
|
|
}
|