Skip to content

Commit 1d25265

Browse files
PeerRichAmit91848Udit-takkarCarinaWolli
authored
feat: workflows v3 UI (calcom#22772)
* early UI refresher of workflows using v3 designs. needs tons of testing, might have broken * Delete .claude/settings.local.json * fix: bunch of design fixes, merge conflict fixes * fix: e2e and type-check * fix: await button click * review fixes * code rabbit fixes * fix styles in variables dropdown * fix text truncate * fix: unit tests * fix: unit tests * chore: add missing i18n * review fixes * review fixes * fix testing info message * move timeSectionText up * fix which team does this apply to info message * disable set up agent button with read only * fix: cal.ai breaking on mobile screen --------- Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com> Co-authored-by: Udit Takkar <udit222001@gmail.com> Co-authored-by: CarinaWolli <wollencarina@gmail.com>
1 parent 65f6689 commit 1d25265

20 files changed

Lines changed: 5585 additions & 1069 deletions

File tree

apps/web/app/(use-page-wrapper)/settings/(admin-layout)/AdminLayoutAppDirClient.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export type AdminLayoutProps = {
1212
children: React.ReactNode;
1313
userRole: UserPermissionRole | "INACTIVE_ADMIN" | undefined;
1414
} & ComponentProps<typeof Shell>;
15-
export default function AdminLayoutAppDirClient({ userRole, children }: AdminLayoutProps) {
15+
export default function AdminLayoutAppDirClient({ children }: AdminLayoutProps) {
1616
const pathname = usePathname();
1717

1818
const isAppsPage = pathname?.startsWith("/settings/admin/apps");

apps/web/playwright/fixtures/workflows.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ export function createWorkflowPageFixture(page: Page) {
4646

4747
const saveWorkflow = async () => {
4848
const submitPromise = page.waitForResponse("/api/trpc/workflows/update?batch=1");
49-
await page.getByTestId("save-workflow").click();
49+
const saveButton = await page.getByTestId("save-workflow");
50+
await saveButton.click();
5051
const response = await submitPromise;
5152
expect(response.status()).toBe(200);
5253
const responseData = await response.json();
@@ -61,7 +62,9 @@ export function createWorkflowPageFixture(page: Page) {
6162
};
6263

6364
const fillNameInput = async (name: string) => {
65+
await page.getByTestId("edit-workflow-name-button").click();
6466
await page.getByTestId("workflow-name").fill(name);
67+
await page.keyboard.press("Enter");
6568
};
6669

6770
const editSelectedWorkflow = async (name: string) => {

apps/web/public/static/locales/en/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,7 @@
846846
"phone_number_subscription_cancelled_successfully": "Phone number subscription canceled successfully",
847847
"updating": "Updating",
848848
"round_robin": "Round Robin",
849+
"hi_how_are_you_doing": "Hi, how are you doing?",
849850
"round_robin_description": "Cycle meetings between multiple team members.",
850851
"managed_event": "Managed Event",
851852
"username_placeholder": "username",
@@ -2341,7 +2342,6 @@
23412342
"could_not_charge_card": "Could not charge card for payment.",
23422343
"insights": "Insights",
23432344
"routing_forms": "Routing Forms",
2344-
"testing_workflow_info_message": "When testing this workflow, be aware that Emails and SMS can only be scheduled at least 1 hour in advance",
23452345
"insights_no_data_found_for_filter": "No data found for the selected filter or selected dates.",
23462346
"acknowledge_booking_no_show_fee": "I acknowledge that if I do not attend this event that a {{amount, currency}} no show fee will be applied to my card.",
23472347
"days": "days",
@@ -3594,6 +3594,7 @@
35943594
"webhook_trigger_event": "The name of the trigger event (e.g., BOOKING_CREATED, BOOKING_CANCELLED)",
35953595
"webhook_created_at": "The time of the webhook",
35963596
"webhook_type": "The event type slug",
3597+
"set_up_agent": "Set up Agent",
35973598
"webhook_title": "The event type name",
35983599
"webhook_start_time": "The event's start time",
35993600
"webhook_end_time": "The event's end time",
@@ -3652,5 +3653,6 @@
36523653
"before_scheduled_start_time": "Before scheduled start time",
36533654
"cancel_booking_acknowledge_no_show_fee": "I acknowledge that by cancelling the booking within {{timeValue}} {{timeUnit}} of the start time I will be charged the no show fee of {{amount, currency}}",
36543655
"contact_organizer": "If you have any questions, please contact the organizer.",
3656+
"testing_sms_workflow_info_message": "When testing this workflow, be aware that SMS need to be scheduled at least 15 minutes in advance",
36553657
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
36563658
}

apps/web/test/lib/confirm.handler.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { describe, it, beforeEach, vi, expect } from "vitest";
1010

1111
import * as handleConfirmationModule from "@calcom/features/bookings/lib/handleConfirmation";
1212
import { BookingStatus } from "@calcom/prisma/enums";
13-
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
1413
import { confirmHandler } from "@calcom/trpc/server/routers/viewer/bookings/confirm.handler";
14+
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
1515

1616
describe("confirmHandler", () => {
1717
beforeEach(() => {

packages/app-store/routing-forms/pages/form-edit/[...appPages].tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { v4 as uuidv4 } from "uuid";
99
import { useLocale } from "@calcom/lib/hooks/useLocale";
1010
import classNames from "@calcom/ui/classNames";
1111
import { Button } from "@calcom/ui/components/button";
12-
import { FormCard } from "@calcom/ui/components/card";
12+
import { FormCard, FormCardBody } from "@calcom/ui/components/card";
1313
import {
1414
BooleanToggleGroupField,
1515
Label,
@@ -90,7 +90,7 @@ function Field({
9090
router ? { text: router.name, variant: "gray", href: `${appUrl}/form-edit/${router.id}` } : null
9191
}
9292
deleteField={router ? null : deleteField}>
93-
<div className="bg-default border-default w-full gap-3 rounded-2xl border p-3">
93+
<FormCardBody>
9494
<div className="mb-3 w-full">
9595
<TextField
9696
data-testid={`${hookFieldNamespace}.label`}
@@ -211,7 +211,7 @@ function Field({
211211
}}
212212
/>
213213
</div>
214-
</div>
214+
</FormCardBody>
215215
</FormCard>
216216
</div>
217217
);

packages/features/components/phone-input/PhoneInput.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import { isSupportedCountry } from "libphonenumber-js";
4+
import type { CSSProperties } from "react";
45
import { useState, useEffect } from "react";
56
import PhoneInput from "react-phone-input-2";
67
import "react-phone-input-2/lib/style.css";
@@ -19,6 +20,8 @@ export type PhoneInputProps = {
1920
disabled?: boolean;
2021
onChange: (value: string) => void;
2122
defaultCountry?: string;
23+
inputStyle?: CSSProperties;
24+
flagButtonStyle?: CSSProperties;
2225
};
2326

2427
function BasePhoneInput({
@@ -45,6 +48,7 @@ function BasePhoneInput({
4548
if (value !== sanitized) {
4649
onChange(sanitized);
4750
}
51+
// eslint-disable-next-line react-hooks/exhaustive-deps
4852
}, []);
4953

5054
if (!isPlatform) {
@@ -97,6 +101,8 @@ function BasePhoneInputWeb({
97101
className = "",
98102
onChange,
99103
value,
104+
inputStyle,
105+
flagButtonStyle,
100106
...rest
101107
}: Omit<PhoneInputProps, "defaultCountry">) {
102108
const defaultCountry = useDefaultCountry();
@@ -122,9 +128,10 @@ function BasePhoneInputWeb({
122128
)}
123129
inputClass="text-sm focus:ring-0 !bg-default text-default placeholder:text-muted"
124130
buttonClass="text-emphasis !bg-default hover:!bg-emphasis"
131+
buttonStyle={{ ...flagButtonStyle }}
125132
searchClass="!text-default !bg-default hover:!bg-emphasis"
126133
dropdownClass="!text-default !bg-default"
127-
inputStyle={{ width: "inherit", border: 0 }}
134+
inputStyle={{ width: "inherit", border: 0, ...inputStyle }}
128135
searchStyle={{
129136
display: "flex",
130137
flexDirection: "row",

packages/features/ee/workflows/api/scheduleEmailReminders.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export async function handler(req: NextRequest) {
7171
//cancel reminders for cancelled/rescheduled bookings that are scheduled within the next hour
7272
const remindersToCancel: { referenceId: string | null; id: number }[] = await getAllRemindersToCancel();
7373

74+
//eslint-disable-next-line @typescript-eslint/no-explicit-any
7475
const cancelUpdatePromises: Promise<any>[] = [];
7576

7677
for (const reminder of remindersToCancel) {
@@ -98,6 +99,7 @@ export async function handler(req: NextRequest) {
9899
}
99100

100101
// schedule all unscheduled reminders within the next 72 hours
102+
//eslint-disable-next-line @typescript-eslint/no-explicit-any
101103
const sendEmailPromises: Promise<any>[] = [];
102104

103105
const unscheduledReminders = await getAllUnscheduledReminders();

packages/features/ee/workflows/components/SkeletonLoaderEdit.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,8 @@ import { SkeletonText, SkeletonContainer } from "@calcom/ui/components/skeleton"
33
function SkeletonLoader() {
44
return (
55
<SkeletonContainer>
6-
<div className="ml-2 mt-10 md:flex">
7-
<div className="mr-6 flex flex-col md:flex-none">
8-
<SkeletonText className="h-4 w-28" />
9-
<SkeletonText className="mb-6 mt-2 h-8 w-full md:w-64" />
10-
<SkeletonText className="h-4 w-28" />
11-
<SkeletonText className="mt-2 h-8 w-full md:w-64" />
12-
<SkeletonText className="mt-8 hidden h-0.5 w-full md:block" />
13-
<SkeletonText className="mb-6 mt-8 h-8 w-40" />
14-
</div>
15-
<div className="hidden flex-grow md:flex">
16-
<SkeletonText className="h-64 w-full" />
17-
</div>
18-
</div>
6+
<SkeletonText className="mx-auto my-8 h-48 w-full max-w-4xl" />
7+
<SkeletonText className="mx-auto my-8 h-80 w-full max-w-4xl" />
198
</SkeletonContainer>
209
);
2110
}

0 commit comments

Comments
 (0)