Merge branch 'main' into feat/calcom-auth
This commit is contained in:
commit
f5580a44ac
|
@ -7,6 +7,7 @@ import { z } from "zod";
|
||||||
|
|
||||||
import { SENDER_ID } from "@calcom/lib/constants";
|
import { SENDER_ID } from "@calcom/lib/constants";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
|
import { trpc } from "@calcom/trpc/react";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
@ -23,7 +24,6 @@ import {
|
||||||
} from "@calcom/ui";
|
} from "@calcom/ui";
|
||||||
|
|
||||||
import { WORKFLOW_ACTIONS } from "../lib/constants";
|
import { WORKFLOW_ACTIONS } from "../lib/constants";
|
||||||
import { getWorkflowActionOptions } from "../lib/getOptions";
|
|
||||||
import { onlyLettersNumbersSpaces } from "../pages/workflow";
|
import { onlyLettersNumbersSpaces } from "../pages/workflow";
|
||||||
|
|
||||||
interface IAddActionDialog {
|
interface IAddActionDialog {
|
||||||
|
@ -50,7 +50,7 @@ export const AddActionDialog = (props: IAddActionDialog) => {
|
||||||
const [isPhoneNumberNeeded, setIsPhoneNumberNeeded] = useState(false);
|
const [isPhoneNumberNeeded, setIsPhoneNumberNeeded] = useState(false);
|
||||||
const [isSenderIdNeeded, setIsSenderIdNeeded] = useState(false);
|
const [isSenderIdNeeded, setIsSenderIdNeeded] = useState(false);
|
||||||
const [isEmailAddressNeeded, setIsEmailAddressNeeded] = useState(false);
|
const [isEmailAddressNeeded, setIsEmailAddressNeeded] = useState(false);
|
||||||
const actionOptions = getWorkflowActionOptions(t);
|
const { data: actionOptions } = trpc.viewer.workflows.getWorkflowActionOptions.useQuery();
|
||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
action: z.enum(WORKFLOW_ACTIONS),
|
action: z.enum(WORKFLOW_ACTIONS),
|
||||||
|
@ -101,6 +101,8 @@ export const AddActionDialog = (props: IAddActionDialog) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!actionOptions) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={isOpenDialog} onOpenChange={setIsOpenDialog}>
|
<Dialog open={isOpenDialog} onOpenChange={setIsOpenDialog}>
|
||||||
<DialogContent type="creation" title={t("add_action")}>
|
<DialogContent type="creation" title={t("add_action")}>
|
||||||
|
@ -131,6 +133,11 @@ export const AddActionDialog = (props: IAddActionDialog) => {
|
||||||
defaultValue={actionOptions[0]}
|
defaultValue={actionOptions[0]}
|
||||||
onChange={handleSelectAction}
|
onChange={handleSelectAction}
|
||||||
options={actionOptions}
|
options={actionOptions}
|
||||||
|
isOptionDisabled={(option: {
|
||||||
|
label: string;
|
||||||
|
value: WorkflowActions;
|
||||||
|
disabled: boolean;
|
||||||
|
}) => option.disabled}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { Controller, UseFormReturn } from "react-hook-form";
|
||||||
import { SENDER_ID } from "@calcom/lib/constants";
|
import { SENDER_ID } from "@calcom/lib/constants";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import { trpc } from "@calcom/trpc/react";
|
import { trpc } from "@calcom/trpc/react";
|
||||||
import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery";
|
|
||||||
import { Icon } from "@calcom/ui";
|
import { Icon } from "@calcom/ui";
|
||||||
import { Button, Label, TextField } from "@calcom/ui";
|
import { Button, Label, TextField } from "@calcom/ui";
|
||||||
import { MultiSelectCheckboxes } from "@calcom/ui";
|
import { MultiSelectCheckboxes } from "@calcom/ui";
|
||||||
|
|
|
@ -92,8 +92,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||||
const [showTimeSectionAfter, setShowTimeSectionAfter] = useState(
|
const [showTimeSectionAfter, setShowTimeSectionAfter] = useState(
|
||||||
form.getValues("trigger") === WorkflowTriggerEvents.AFTER_EVENT
|
form.getValues("trigger") === WorkflowTriggerEvents.AFTER_EVENT
|
||||||
);
|
);
|
||||||
|
const { data: actionOptions } = trpc.viewer.workflows.getWorkflowActionOptions.useQuery();
|
||||||
const actionOptions = getWorkflowActionOptions(t);
|
|
||||||
const triggerOptions = getWorkflowTriggerOptions(t);
|
const triggerOptions = getWorkflowTriggerOptions(t);
|
||||||
const templateOptions = getWorkflowTemplateOptions(t);
|
const templateOptions = getWorkflowTemplateOptions(t);
|
||||||
|
|
||||||
|
@ -227,6 +226,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||||
const selectedAction = {
|
const selectedAction = {
|
||||||
label: actionString.charAt(0).toUpperCase() + actionString.slice(1),
|
label: actionString.charAt(0).toUpperCase() + actionString.slice(1),
|
||||||
value: step.action,
|
value: step.action,
|
||||||
|
disabled: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectedTemplate = { label: t(`${step.template.toLowerCase()}`), value: step.template };
|
const selectedTemplate = { label: t(`${step.template.toLowerCase()}`), value: step.template };
|
||||||
|
@ -341,6 +341,11 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
|
||||||
}}
|
}}
|
||||||
defaultValue={selectedAction}
|
defaultValue={selectedAction}
|
||||||
options={actionOptions}
|
options={actionOptions}
|
||||||
|
isOptionDisabled={(option: {
|
||||||
|
label: string;
|
||||||
|
value: WorkflowActions;
|
||||||
|
disabled: boolean;
|
||||||
|
}) => option.disabled}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
|
import { WorkflowActions } from "@prisma/client";
|
||||||
import { TFunction } from "next-i18next";
|
import { TFunction } from "next-i18next";
|
||||||
|
|
||||||
import { TIME_UNIT, WORKFLOW_ACTIONS, WORKFLOW_TEMPLATES, WORKFLOW_TRIGGER_EVENTS } from "./constants";
|
import { TIME_UNIT, WORKFLOW_ACTIONS, WORKFLOW_TEMPLATES, WORKFLOW_TRIGGER_EVENTS } from "./constants";
|
||||||
|
|
||||||
export function getWorkflowActionOptions(t: TFunction) {
|
export function getWorkflowActionOptions(t: TFunction, isTeamsPlan?: boolean) {
|
||||||
return WORKFLOW_ACTIONS.map((action) => {
|
return WORKFLOW_ACTIONS.map((action) => {
|
||||||
const actionString = t(`${action.toLowerCase()}_action`);
|
const actionString = t(`${action.toLowerCase()}_action`);
|
||||||
|
|
||||||
return { label: actionString.charAt(0).toUpperCase() + actionString.slice(1), value: action };
|
const isSMSAction = action === WorkflowActions.SMS_ATTENDEE || action === WorkflowActions.SMS_NUMBER;
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: actionString.charAt(0).toUpperCase() + actionString.slice(1),
|
||||||
|
value: action,
|
||||||
|
disabled: isSMSAction && !isTeamsPlan,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import {
|
||||||
WORKFLOW_ACTIONS,
|
WORKFLOW_ACTIONS,
|
||||||
TIME_UNIT,
|
TIME_UNIT,
|
||||||
} from "@calcom/features/ee/workflows/lib/constants";
|
} from "@calcom/features/ee/workflows/lib/constants";
|
||||||
|
import { getWorkflowActionOptions } from "@calcom/features/ee/workflows/lib/getOptions";
|
||||||
import {
|
import {
|
||||||
deleteScheduledEmailReminder,
|
deleteScheduledEmailReminder,
|
||||||
scheduleEmailReminder,
|
scheduleEmailReminder,
|
||||||
|
@ -28,11 +29,16 @@ import {
|
||||||
} from "@calcom/features/ee/workflows/lib/reminders/smsReminderManager";
|
} from "@calcom/features/ee/workflows/lib/reminders/smsReminderManager";
|
||||||
import { SENDER_ID } from "@calcom/lib/constants";
|
import { SENDER_ID } from "@calcom/lib/constants";
|
||||||
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||||
|
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||||
|
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
|
|
||||||
import { router, authedProcedure, authedRateLimitedProcedure } from "../../trpc";
|
import { router, authedProcedure, authedRateLimitedProcedure } from "../../trpc";
|
||||||
|
|
||||||
|
function isSMSAction(action: WorkflowActions) {
|
||||||
|
return action === WorkflowActions.SMS_ATTENDEE || action === WorkflowActions.SMS_NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
export const workflowsRouter = router({
|
export const workflowsRouter = router({
|
||||||
list: authedProcedure.query(async ({ ctx }) => {
|
list: authedProcedure.query(async ({ ctx }) => {
|
||||||
const workflows = await ctx.prisma.workflow.findMany({
|
const workflows = await ctx.prisma.workflow.findMany({
|
||||||
|
@ -249,6 +255,11 @@ export const workflowsRouter = router({
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
userId: true,
|
userId: true,
|
||||||
|
user: {
|
||||||
|
select: {
|
||||||
|
teams: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
steps: true,
|
steps: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -519,6 +530,13 @@ export const workflowsRouter = router({
|
||||||
});
|
});
|
||||||
//step was edited
|
//step was edited
|
||||||
} else if (JSON.stringify(oldStep) !== JSON.stringify(newStep)) {
|
} else if (JSON.stringify(oldStep) !== JSON.stringify(newStep)) {
|
||||||
|
if (
|
||||||
|
!userWorkflow.user.teams.length &&
|
||||||
|
!isSMSAction(oldStep.action) &&
|
||||||
|
isSMSAction(newStep.action)
|
||||||
|
) {
|
||||||
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||||
|
}
|
||||||
await ctx.prisma.workflowStep.update({
|
await ctx.prisma.workflowStep.update({
|
||||||
where: {
|
where: {
|
||||||
id: oldStep.id,
|
id: oldStep.id,
|
||||||
|
@ -658,6 +676,9 @@ export const workflowsRouter = router({
|
||||||
//added steps
|
//added steps
|
||||||
const addedSteps = steps.map((s) => {
|
const addedSteps = steps.map((s) => {
|
||||||
if (s.id <= 0) {
|
if (s.id <= 0) {
|
||||||
|
if (!userWorkflow.user.teams.length && isSMSAction(s.action)) {
|
||||||
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||||
|
}
|
||||||
const { id: stepId, ...stepToAdd } = s;
|
const { id: stepId, ...stepToAdd } = s;
|
||||||
return stepToAdd;
|
return stepToAdd;
|
||||||
}
|
}
|
||||||
|
@ -984,4 +1005,10 @@ export const workflowsRouter = router({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
getWorkflowActionOptions: authedProcedure.query(async ({ ctx }) => {
|
||||||
|
const userId = ctx.user.id;
|
||||||
|
const hasTeamPlan = (await ctx.prisma.membership.count({ where: { userId } })) > 0;
|
||||||
|
const t = await getTranslation(ctx.user.locale, "common");
|
||||||
|
return getWorkflowActionOptions(t, hasTeamPlan);
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user