* removed reduntand check on assignedusers * update for managed eventtype * formatted * comments * Updated comments * extracted checkForEmptyAssignment and added tests * updated comments * updated to show dialog also when not yet saved * update translations * updated comments * updated translation * updated types * chore: update naming and comments * Delete apps/web/lib/checkForEmptyAssignment.ts deleted since file was renamed * Delete apps/web/test/lib/checkForEmptyAssignment.test.ts deleted as the file is renamed to be more descriptive * update to do teamcheck before * chore: revert name to CheckForEmptyAssignment * updated check conditions * updated useEffect dependencies --------- Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
This commit is contained in:
1 parent
db03e9db20
commit
8508a6f1a0
3 files changed
+171
-41
No files matched your search
@@ -0,0 +1,29 @@
|
||||
import type { EventTypeAssignedUsers, EventTypeHosts } from "~/event-types/views/event-types-single-view";
|
||||
|
||||
// This function checks if EventType requires assignment.
|
||||
// returns true: if EventType requires assignment but there is no assignment yet done by the user.
|
||||
// returns false: for all other scenarios.
|
||||
export function checkForEmptyAssignment({
|
||||
assignedUsers,
|
||||
hosts,
|
||||
isManagedEventType,
|
||||
assignAllTeamMembers,
|
||||
}: {
|
||||
assignedUsers: EventTypeAssignedUsers;
|
||||
hosts: EventTypeHosts;
|
||||
isManagedEventType: boolean;
|
||||
assignAllTeamMembers: boolean;
|
||||
}): boolean {
|
||||
// If Team-events have assignAllTeamMembers checked, return false as assignemnt is complete.
|
||||
if (assignAllTeamMembers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For managed eventtype check if assigned users are empty.
|
||||
// For non-managed eventtype check if hosts are empty.
|
||||
if (isManagedEventType ? assignedUsers.length === 0 : hosts.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import { HttpError } from "@calcom/lib/http-error";
|
||||
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
|
||||
import { validateBookerLayouts } from "@calcom/lib/validateBookerLayouts";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
import type { customInputSchema, EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
||||
import { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
@@ -33,6 +34,7 @@ import { trpc } from "@calcom/trpc/react";
|
||||
import { Form, showToast } from "@calcom/ui";
|
||||
|
||||
import type { AppProps } from "@lib/app-providers";
|
||||
import { checkForEmptyAssignment } from "@lib/checkForEmptyAssignment";
|
||||
|
||||
import { EventTypeSingleLayout } from "@components/eventtype/EventTypeSingleLayout";
|
||||
|
||||
@@ -144,6 +146,8 @@ const querySchema = z.object({
|
||||
|
||||
export type EventTypeSetupProps = RouterOutputs["viewer"]["eventTypes"]["get"];
|
||||
export type EventTypeSetup = RouterOutputs["viewer"]["eventTypes"]["get"]["eventType"];
|
||||
export type EventTypeAssignedUsers = RouterOutputs["viewer"]["eventTypes"]["get"]["eventType"]["children"];
|
||||
export type EventTypeHosts = RouterOutputs["viewer"]["eventTypes"]["get"]["eventType"]["hosts"];
|
||||
|
||||
export const locationsResolver = (t: TFunction) => {
|
||||
return z
|
||||
@@ -400,40 +404,35 @@ const EventTypePage = (props: EventTypeSetupProps & { allActiveWorkflows?: Workf
|
||||
formState: { isDirty: isFormDirty, dirtyFields },
|
||||
} = formMethods;
|
||||
|
||||
// useEffect(() => {
|
||||
// const handleRouteChange = (url: string) => {
|
||||
// const paths = url.split("/");
|
||||
//
|
||||
// // Check if event is managed event type - skip if there is assigned users
|
||||
// const assignedUsers = eventType.children;
|
||||
// const isManagedEventType = eventType.schedulingType === SchedulingType.MANAGED;
|
||||
// if (eventType.assignAllTeamMembers) {
|
||||
// return;
|
||||
// } else if (isManagedEventType && assignedUsers.length > 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// const hosts = eventType.hosts;
|
||||
// if (
|
||||
// !leaveWithoutAssigningHosts.current &&
|
||||
// !!team &&
|
||||
// (hosts.length === 0 || assignedUsers.length === 0) &&
|
||||
// (url === "/event-types" || paths[1] !== "event-types")
|
||||
// ) {
|
||||
// setIsOpenAssignmentWarnDialog(true);
|
||||
// setPendingRoute(url);
|
||||
// router.events.emit(
|
||||
// "routeChangeError",
|
||||
// new Error(`Aborted route change to ${url} because none was assigned to team event`)
|
||||
// );
|
||||
// throw "Aborted";
|
||||
// }
|
||||
// };
|
||||
// router.events.on("routeChangeStart", handleRouteChange);
|
||||
// return () => {
|
||||
// router.events.off("routeChangeStart", handleRouteChange);
|
||||
// };
|
||||
// }, [router]);
|
||||
useEffect(() => {
|
||||
const handleRouteChange = (url: string) => {
|
||||
const paths = url.split("/");
|
||||
|
||||
if (
|
||||
!!team &&
|
||||
!leaveWithoutAssigningHosts.current &&
|
||||
(url === "/event-types" || paths[1] !== "event-types") &&
|
||||
checkForEmptyAssignment({
|
||||
assignedUsers: eventType.children,
|
||||
hosts: eventType.hosts,
|
||||
assignAllTeamMembers: eventType.assignAllTeamMembers,
|
||||
isManagedEventType: eventType.schedulingType === SchedulingType.MANAGED,
|
||||
})
|
||||
) {
|
||||
setIsOpenAssignmentWarnDialog(true);
|
||||
setPendingRoute(url);
|
||||
router.events.emit(
|
||||
"routeChangeError",
|
||||
new Error(`Aborted route change to ${url} because none was assigned to team event`)
|
||||
);
|
||||
throw "Aborted";
|
||||
}
|
||||
};
|
||||
router.events.on("routeChangeStart", handleRouteChange);
|
||||
return () => {
|
||||
router.events.off("routeChangeStart", handleRouteChange);
|
||||
};
|
||||
}, [router, eventType.hosts, eventType.children, eventType.assignAllTeamMembers]);
|
||||
|
||||
const appsMetadata = formMethods.getValues("metadata")?.apps;
|
||||
const availability = formMethods.watch("availability");
|
||||
@@ -837,13 +836,13 @@ const EventTypePage = (props: EventTypeSetupProps & { allActiveWorkflows?: Workf
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
{/*<AssignmentWarningDialog*/}
|
||||
{/* isOpenAssignmentWarnDialog={isOpenAssignmentWarnDialog}*/}
|
||||
{/* setIsOpenAssignmentWarnDialog={setIsOpenAssignmentWarnDialog}*/}
|
||||
{/* pendingRoute={pendingRoute}*/}
|
||||
{/* leaveWithoutAssigningHosts={leaveWithoutAssigningHosts}*/}
|
||||
{/* id={eventType.id}*/}
|
||||
{/*/>*/}
|
||||
<AssignmentWarningDialog
|
||||
isOpenAssignmentWarnDialog={isOpenAssignmentWarnDialog}
|
||||
setIsOpenAssignmentWarnDialog={setIsOpenAssignmentWarnDialog}
|
||||
pendingRoute={pendingRoute}
|
||||
leaveWithoutAssigningHosts={leaveWithoutAssigningHosts}
|
||||
id={eventType.id}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { checkForEmptyAssignment } from "../../lib/checkForEmptyAssignment";
|
||||
|
||||
describe("Tests to Check if Event Types have empty Assignment", () => {
|
||||
it("should return true if managed event type has no assigned users", () => {
|
||||
expect(
|
||||
checkForEmptyAssignment({
|
||||
assignedUsers: [],
|
||||
assignAllTeamMembers: false,
|
||||
hosts: [{ userId: 101, isFixed: false, priority: 2 }],
|
||||
isManagedEventType: true,
|
||||
})
|
||||
).toBe(true);
|
||||
});
|
||||
it("should return true if non-managed event type has no hosts assigned", () => {
|
||||
expect(
|
||||
checkForEmptyAssignment({
|
||||
assignedUsers: [
|
||||
{
|
||||
created: true,
|
||||
owner: {
|
||||
id: 101,
|
||||
avatar: "avatar.svg",
|
||||
email: "firstuser@cal.com",
|
||||
membership: "OWNER",
|
||||
name: "First user",
|
||||
username: "firstuser",
|
||||
profile: {
|
||||
username: "firstuser",
|
||||
upId: "usr-101",
|
||||
id: null,
|
||||
organization: null,
|
||||
organizationId: null,
|
||||
},
|
||||
avatarUrl: null,
|
||||
nonProfileUsername: null,
|
||||
},
|
||||
slug: "managedevent",
|
||||
hidden: false,
|
||||
},
|
||||
],
|
||||
assignAllTeamMembers: false,
|
||||
hosts: [],
|
||||
isManagedEventType: false,
|
||||
})
|
||||
).toBe(true);
|
||||
});
|
||||
it("should return false if assignAllTeamMembers is selected", () => {
|
||||
expect(
|
||||
checkForEmptyAssignment({
|
||||
assignedUsers: [],
|
||||
assignAllTeamMembers: true,
|
||||
hosts: [],
|
||||
isManagedEventType: false,
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
it("should return false if non-managed event type has hosts assigned", () => {
|
||||
expect(
|
||||
checkForEmptyAssignment({
|
||||
assignedUsers: [],
|
||||
assignAllTeamMembers: false,
|
||||
hosts: [{ userId: 101, isFixed: false, priority: 2 }],
|
||||
isManagedEventType: false,
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
it("should return false if managed event type has assigned users", () => {
|
||||
expect(
|
||||
checkForEmptyAssignment({
|
||||
assignedUsers: [
|
||||
{
|
||||
created: true,
|
||||
owner: {
|
||||
id: 101,
|
||||
avatar: "avatar.svg",
|
||||
email: "firstuser@cal.com",
|
||||
membership: "OWNER",
|
||||
name: "First user",
|
||||
username: "firstuser",
|
||||
profile: {
|
||||
username: "firstuser",
|
||||
upId: "usr-101",
|
||||
id: null,
|
||||
organization: null,
|
||||
organizationId: null,
|
||||
},
|
||||
avatarUrl: null,
|
||||
nonProfileUsername: null,
|
||||
},
|
||||
slug: "managedevent",
|
||||
hidden: false,
|
||||
},
|
||||
],
|
||||
assignAllTeamMembers: false,
|
||||
hosts: [],
|
||||
isManagedEventType: true,
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user