fix: save workflow button not visible on dev env (#14910)

* fix: save workflow button not visible on dev env

* refactor: use the CALCOM_ENV constant

* fix: ui fix for header on workspace pages

* refactor: remove unused variable

---------

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
This commit is contained in:
Ayush Mhetre
2024-05-09 17:46:39 +00:00
committed by GitHub
co-authored by Carina Wollendorfer
parent c2a07e221d
commit 097a69d7d7
2 changed files with 166 additions and 157 deletions
+44 -43
View File
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
import type { Dispatch, SetStateAction } from "react";
import { useState } from "react";
import Shell from "@calcom/features/shell/Shell";
import Shell, { ShellMain } from "@calcom/features/shell/Shell";
import { classNames } from "@calcom/lib";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -51,50 +51,51 @@ function WorkflowsPage() {
});
return (
<Shell
withoutMain={false}
heading={t("workflows")}
subtitle={t("workflows_to_automate_notifications")}
title="Workflows"
description="Create workflows to automate notifications and reminders."
hideHeadingOnMobile
CTA={
session.data?.hasValidLicense ? (
<CreateButtonWithTeamsList
subtitle={t("new_workflow_subtitle").toUpperCase()}
createFunction={(teamId?: number) => {
createMutation.mutate({ teamId });
}}
isPending={createMutation.isPending}
disableMobileButton={true}
onlyShowWithNoTeams={true}
/>
) : null
}>
<Shell withoutMain>
<LicenseRequired>
<>
{queryRes.data?.totalCount ? (
<div className="flex">
<TeamsFilter />
<div className="ml-auto">
<CreateButtonWithTeamsList
subtitle={t("new_workflow_subtitle").toUpperCase()}
createFunction={(teamId?: number) => createMutation.mutate({ teamId })}
isPending={createMutation.isPending}
disableMobileButton={true}
onlyShowWithTeams={true}
/>
<ShellMain
heading={t("workflows")}
subtitle={t("workflows_to_automate_notifications")}
title="Workflows"
description="Create workflows to automate notifications and reminders."
hideHeadingOnMobile
CTA={
session.data?.hasValidLicense ? (
<CreateButtonWithTeamsList
subtitle={t("new_workflow_subtitle").toUpperCase()}
createFunction={(teamId?: number) => {
createMutation.mutate({ teamId });
}}
isPending={createMutation.isPending}
disableMobileButton={true}
onlyShowWithNoTeams={true}
/>
) : null
}>
<>
{queryRes.data?.totalCount ? (
<div className="flex">
<TeamsFilter />
<div className="ml-auto">
<CreateButtonWithTeamsList
subtitle={t("new_workflow_subtitle").toUpperCase()}
createFunction={(teamId?: number) => createMutation.mutate({ teamId })}
isPending={createMutation.isPending}
disableMobileButton={true}
onlyShowWithTeams={true}
/>
</div>
</div>
</div>
) : null}
<FilterResults
queryRes={queryRes}
emptyScreen={<EmptyScreen isFilteredView={false} />}
noResultsScreen={<EmptyScreen isFilteredView={true} />}
SkeletonLoader={SkeletonLoader}>
<WorkflowList workflows={queryRes.data?.filtered} />
</FilterResults>
</>
) : null}
<FilterResults
queryRes={queryRes}
emptyScreen={<EmptyScreen isFilteredView={false} />}
noResultsScreen={<EmptyScreen isFilteredView={true} />}
SkeletonLoader={SkeletonLoader}>
<WorkflowList workflows={queryRes.data?.filtered} />
</FilterResults>
</>
</ShellMain>
</LicenseRequired>
</Shell>
);
+122 -114
View File
@@ -7,7 +7,7 @@ import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import Shell from "@calcom/features/shell/Shell";
import Shell, { ShellMain } from "@calcom/features/shell/Shell";
import { classNames } from "@calcom/lib";
import { SENDER_ID } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -204,124 +204,132 @@ function WorkflowPage() {
});
return session.data ? (
<Form
form={form}
handleSubmit={async (values) => {
let activeOnEventTypeIds: number[] = [];
let isEmpty = false;
let isVerified = true;
<Shell withoutMain backPath="/workflows">
<LicenseRequired>
<Form
form={form}
handleSubmit={async (values) => {
let activeOnEventTypeIds: number[] = [];
let isEmpty = false;
let isVerified = true;
values.steps.forEach((step) => {
const strippedHtml = step.reminderBody?.replace(/<[^>]+>/g, "") || "";
values.steps.forEach((step) => {
const strippedHtml = step.reminderBody?.replace(/<[^>]+>/g, "") || "";
const isBodyEmpty = !isSMSOrWhatsappAction(step.action) && strippedHtml.length <= 1;
const isBodyEmpty = !isSMSOrWhatsappAction(step.action) && strippedHtml.length <= 1;
if (isBodyEmpty) {
form.setError(`steps.${step.stepNumber - 1}.reminderBody`, {
type: "custom",
message: t("fill_this_field"),
if (isBodyEmpty) {
form.setError(`steps.${step.stepNumber - 1}.reminderBody`, {
type: "custom",
message: t("fill_this_field"),
});
}
if (step.reminderBody) {
step.reminderBody = translateVariablesToEnglish(step.reminderBody, {
locale: i18n.language,
t,
});
}
if (step.emailSubject) {
step.emailSubject = translateVariablesToEnglish(step.emailSubject, {
locale: i18n.language,
t,
});
}
isEmpty = !isEmpty ? isBodyEmpty : isEmpty;
//check if phone number is verified
if (
(step.action === WorkflowActions.SMS_NUMBER ||
step.action === WorkflowActions.WHATSAPP_NUMBER) &&
!verifiedNumbers?.find((verifiedNumber) => verifiedNumber.phoneNumber === step.sendTo)
) {
isVerified = false;
form.setError(`steps.${step.stepNumber - 1}.sendTo`, {
type: "custom",
message: t("not_verified"),
});
}
});
}
if (step.reminderBody) {
step.reminderBody = translateVariablesToEnglish(step.reminderBody, { locale: i18n.language, t });
}
if (step.emailSubject) {
step.emailSubject = translateVariablesToEnglish(step.emailSubject, { locale: i18n.language, t });
}
isEmpty = !isEmpty ? isBodyEmpty : isEmpty;
//check if phone number is verified
if (
(step.action === WorkflowActions.SMS_NUMBER || step.action === WorkflowActions.WHATSAPP_NUMBER) &&
!verifiedNumbers?.find((verifiedNumber) => verifiedNumber.phoneNumber === step.sendTo)
) {
isVerified = false;
form.setError(`steps.${step.stepNumber - 1}.sendTo`, {
type: "custom",
message: t("not_verified"),
});
}
});
if (!isEmpty && isVerified) {
if (values.activeOn) {
activeOnEventTypeIds = values.activeOn.map((option) => {
return parseInt(option.value, 10);
});
}
updateMutation.mutate({
id: workflowId,
name: values.name,
activeOn: activeOnEventTypeIds,
steps: values.steps,
trigger: values.trigger,
time: values.time || null,
timeUnit: values.timeUnit || null,
});
utils.viewer.workflows.getVerifiedNumbers.invalidate();
}
}}>
<Shell
backPath="/workflows"
title={workflow && workflow.name ? workflow.name : "Untitled"}
CTA={
!readOnly && (
<div>
<Button data-testid="save-workflow" type="submit" loading={updateMutation.isPending}>
{t("save")}
</Button>
</div>
)
}
hideHeadingOnMobile
heading={
session.data?.hasValidLicense &&
isAllDataLoaded && (
<div className="flex">
<div className={classNames(workflow && !workflow.name ? "text-muted" : "")}>
{workflow && workflow.name ? workflow.name : "untitled"}
</div>
{workflow && workflow.team && (
<Badge className="ml-4 mt-1" variant="gray">
{workflow.team.name}
</Badge>
)}
{readOnly && (
<Badge className="ml-4 mt-1" variant="gray">
{t("readonly")}
</Badge>
)}
</div>
)
}>
<LicenseRequired>
{!isError ? (
<>
{isAllDataLoaded && user ? (
<>
<WorkflowDetailsPage
form={form}
workflowId={+workflowId}
user={user}
selectedEventTypes={selectedEventTypes}
setSelectedEventTypes={setSelectedEventTypes}
teamId={workflow ? workflow.teamId || undefined : undefined}
isMixedEventType={isMixedEventType}
readOnly={readOnly}
/>
</>
) : (
<SkeletonLoader />
)}
</>
) : (
<Alert severity="error" title="Something went wrong" message={error.message} />
)}
</LicenseRequired>
</Shell>
</Form>
if (!isEmpty && isVerified) {
if (values.activeOn) {
activeOnEventTypeIds = values.activeOn.map((option) => {
return parseInt(option.value, 10);
});
}
updateMutation.mutate({
id: workflowId,
name: values.name,
activeOn: activeOnEventTypeIds,
steps: values.steps,
trigger: values.trigger,
time: values.time || null,
timeUnit: values.timeUnit || null,
});
utils.viewer.workflows.getVerifiedNumbers.invalidate();
}
}}>
<ShellMain
backPath="/workflows"
title={workflow && workflow.name ? workflow.name : "Untitled"}
CTA={
!readOnly && (
<div>
<Button data-testid="save-workflow" type="submit" loading={updateMutation.isPending}>
{t("save")}
</Button>
</div>
)
}
hideHeadingOnMobile
heading={
isAllDataLoaded && (
<div className="flex">
<div className={classNames(workflow && !workflow.name ? "text-muted" : "")}>
{workflow && workflow.name ? workflow.name : "untitled"}
</div>
{workflow && workflow.team && (
<Badge className="ml-4 mt-1" variant="gray">
{workflow.team.name}
</Badge>
)}
{readOnly && (
<Badge className="ml-4 mt-1" variant="gray">
{t("readonly")}
</Badge>
)}
</div>
)
}>
{!isError ? (
<>
{isAllDataLoaded && user ? (
<>
<WorkflowDetailsPage
form={form}
workflowId={+workflowId}
user={user}
selectedEventTypes={selectedEventTypes}
setSelectedEventTypes={setSelectedEventTypes}
teamId={workflow ? workflow.teamId || undefined : undefined}
isMixedEventType={isMixedEventType}
readOnly={readOnly}
/>
</>
) : (
<SkeletonLoader />
)}
</>
) : (
<Alert severity="error" title="Something went wrong" message={error.message} />
)}
</ShellMain>
</Form>
</LicenseRequired>
</Shell>
) : (
<></>
);