* update to display availability page as per weekstart setting * update to accomodate any day * update for AvailabilityTab * reusable and tests added * update test description --------- Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import type { AvailabilityOption, FormValues } from "@calcom/features/eventtypes
|
||||
import classNames from "@calcom/lib/classNames";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { weekdayNames } from "@calcom/lib/weekday";
|
||||
import { weekStartNum } from "@calcom/lib/weekstart";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery";
|
||||
@@ -87,14 +88,16 @@ const EventTypeScheduleDetails = memo(
|
||||
{ enabled: !!scheduleId || !!loggedInUser?.defaultScheduleId || !!selectedScheduleValue }
|
||||
);
|
||||
|
||||
const weekStart = weekStartNum(loggedInUser?.weekStart);
|
||||
|
||||
const filterDays = (dayNum: number) =>
|
||||
schedule?.schedule.filter((item) => item.days.includes((dayNum + 1) % 7)) || [];
|
||||
schedule?.schedule.filter((item) => item.days.includes((dayNum + weekStart) % 7)) || [];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="border-subtle space-y-4 border-x p-6">
|
||||
<ol className="table border-collapse text-sm">
|
||||
{weekdayNames(i18n.language, 1, "long").map((day, index) => {
|
||||
{weekdayNames(i18n.language, weekStart, "long").map((day, index) => {
|
||||
const isAvailable = !!filterDays(index).length;
|
||||
return (
|
||||
<li key={day} className="my-6 flex border-transparent last:mb-2">
|
||||
|
||||
@@ -125,6 +125,7 @@ export function AvailabilityList({ schedules }: RouterOutputs["viewer"]["availab
|
||||
displayOptions={{
|
||||
hour12: meQuery.data?.timeFormat ? meQuery.data.timeFormat === 12 : undefined,
|
||||
timeZone: meQuery.data?.timeZone,
|
||||
weekStart: meQuery.data?.weekStart || "Sunday",
|
||||
}}
|
||||
key={schedule.id}
|
||||
schedule={schedule}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Fragment } from "react";
|
||||
|
||||
import { availabilityAsString } from "@calcom/lib/availability";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { sortAvailabilityStrings } from "@calcom/lib/weekstart";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import {
|
||||
@@ -30,6 +31,7 @@ export function ScheduleListItem({
|
||||
displayOptions?: {
|
||||
timeZone?: string;
|
||||
hour12?: boolean;
|
||||
weekStart?: string;
|
||||
};
|
||||
isDeletable: boolean;
|
||||
updateDefault: ({ scheduleId, isDefault }: { scheduleId: number; isDefault: boolean }) => void;
|
||||
@@ -58,12 +60,17 @@ export function ScheduleListItem({
|
||||
<p className="text-subtle mt-1">
|
||||
{schedule.availability
|
||||
.filter((availability) => !!availability.days.length)
|
||||
.map((availability) => (
|
||||
<Fragment key={availability.id}>
|
||||
{availabilityAsString(availability, {
|
||||
locale: i18n.language,
|
||||
hour12: displayOptions?.hour12,
|
||||
})}
|
||||
.map((availability) =>
|
||||
availabilityAsString(availability, {
|
||||
locale: i18n.language,
|
||||
hour12: displayOptions?.hour12,
|
||||
})
|
||||
)
|
||||
// sort the availability strings as per user's weekstart (settings)
|
||||
.sort(sortAvailabilityStrings(i18n.language, displayOptions?.weekStart))
|
||||
.map((availabilityString, index) => (
|
||||
<Fragment key={index}>
|
||||
{availabilityString}
|
||||
<br />
|
||||
</Fragment>
|
||||
))}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { sortAvailabilityStrings } from "./weekstart";
|
||||
|
||||
describe("Weekstart tests", () => {
|
||||
describe("fn: sortAvailabilityStrings", () => {
|
||||
it("should sort the availability strings when changing weekstart from Sunday to Monday", () => {
|
||||
const input = [
|
||||
"Sun, 11:45 AM - 5:00 PM",
|
||||
"Mon, 7:45 AM - 4:15 PM",
|
||||
"Tue, 9:30 AM - 5:00 PM",
|
||||
"Wed, 9:15 AM - 5:00 PM",
|
||||
"Thu, 9:00 AM - 5:00 PM",
|
||||
"Fri, 7:45 AM - 5:00 PM",
|
||||
"Sat, 10:00 AM - 5:00 PM",
|
||||
];
|
||||
|
||||
const expected = [
|
||||
"Mon, 7:45 AM - 4:15 PM",
|
||||
"Tue, 9:30 AM - 5:00 PM",
|
||||
"Wed, 9:15 AM - 5:00 PM",
|
||||
"Thu, 9:00 AM - 5:00 PM",
|
||||
"Fri, 7:45 AM - 5:00 PM",
|
||||
"Sat, 10:00 AM - 5:00 PM",
|
||||
"Sun, 11:45 AM - 5:00 PM",
|
||||
];
|
||||
|
||||
const result = input.sort(sortAvailabilityStrings("en-US", "Monday"));
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it("should sort the availability strings when changing weekstart from Monday to Sunday", () => {
|
||||
const input = [
|
||||
"Mon - Tue, Thu 7:45 AM - 4:15 PM",
|
||||
"Tue, 5:00 PM - 8:00 PM",
|
||||
"Wed, 9:15 AM - 5:00 PM",
|
||||
"Fri, 7:45 AM - 5:00 PM",
|
||||
"Sat, 10:00 AM - 5:00 PM",
|
||||
"Sun, 11:45 AM - 5:00 PM",
|
||||
];
|
||||
|
||||
const expected = [
|
||||
"Sun, 11:45 AM - 5:00 PM",
|
||||
"Mon - Tue, Thu 7:45 AM - 4:15 PM",
|
||||
"Tue, 5:00 PM - 8:00 PM",
|
||||
"Wed, 9:15 AM - 5:00 PM",
|
||||
"Fri, 7:45 AM - 5:00 PM",
|
||||
"Sat, 10:00 AM - 5:00 PM",
|
||||
];
|
||||
|
||||
const result = input.sort(sortAvailabilityStrings("en-US", "Sunday"));
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it("should sort the availability strings as per the weekstart (random to tuesday)", () => {
|
||||
// this input scenario is not possible to occur, as regardless of any day as start of week,
|
||||
// the weekdays always occur consecutively. But, this to test the sorting function in any case.
|
||||
const input = [
|
||||
"Thu, Mon 7:45 AM - 8:45 AM",
|
||||
"Sat, 10:00 AM - 10:30 AM",
|
||||
"Tue, Fri 4:00 PM - 4:30 PM",
|
||||
"Tue, 5:00 PM - 8:00 PM",
|
||||
"Tue, Sun 9:00 AM - 9:30 AM",
|
||||
"Wed - Thu, Sat 11:00 AM - 11:30 AM",
|
||||
];
|
||||
|
||||
const expected = [
|
||||
"Tue, Fri 4:00 PM - 4:30 PM",
|
||||
"Tue, 5:00 PM - 8:00 PM",
|
||||
"Tue, Sun 9:00 AM - 9:30 AM",
|
||||
"Wed - Thu, Sat 11:00 AM - 11:30 AM",
|
||||
"Thu, Mon 7:45 AM - 8:45 AM",
|
||||
"Sat, 10:00 AM - 10:30 AM",
|
||||
];
|
||||
|
||||
const result = input.sort(sortAvailabilityStrings("en-US", "Tuesday"));
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { weekdayNames } from "./weekday";
|
||||
|
||||
// returns index of input weekName(long) from array starting from Sunday
|
||||
// as fall back returns 0 i.e. Sunday
|
||||
export function weekStartNum(weekName = "Sunday") {
|
||||
const weekDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
||||
const idx = weekDays.indexOf(weekName);
|
||||
return (idx !== -1 ? idx : 0) as 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
||||
}
|
||||
|
||||
// sorts the availability strings based on the weekStart
|
||||
export function sortAvailabilityStrings(language: string, weekStart = "Sunday") {
|
||||
return (a: string, b: string) => {
|
||||
const weekNames = weekdayNames(language, weekStartNum(weekStart), "short");
|
||||
const weekIndex = (day: string) => {
|
||||
for (let i = 0; i < weekNames.length; i++) {
|
||||
if (day.includes(weekNames[i])) return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
return weekIndex(a) - weekIndex(b);
|
||||
};
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import WebShell from "@calcom/features/shell/Shell";
|
||||
import { availabilityAsString } from "@calcom/lib/availability";
|
||||
import classNames from "@calcom/lib/classNames";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { sortAvailabilityStrings } from "@calcom/lib/weekstart";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import type { TimeRange, WorkingHours } from "@calcom/types/schedule";
|
||||
import {
|
||||
@@ -291,11 +292,17 @@ export function AvailabilitySettings({
|
||||
schedule ? (
|
||||
schedule.schedule
|
||||
.filter((availability) => !!availability.days.length)
|
||||
.map((availability) => (
|
||||
<span
|
||||
key={availability.startTime.valueOf().toString()}
|
||||
className={cn(customClassNames?.subtitlesClassName)}>
|
||||
{availabilityAsString(availability, { locale: i18n.language, hour12: timeFormat === 12 })}
|
||||
.map((availability) =>
|
||||
availabilityAsString(availability, {
|
||||
locale: i18n.language,
|
||||
hour12: timeFormat === 12,
|
||||
})
|
||||
)
|
||||
// sort the availability strings as per user's weekstart (settings)
|
||||
.sort(sortAvailabilityStrings(i18n.language, weekStart))
|
||||
.map((availabilityString, index) => (
|
||||
<span key={index} className={cn(customClassNames?.subtitlesClassName)}>
|
||||
{availabilityString}
|
||||
<br />
|
||||
</span>
|
||||
))
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ export const AvailabilitySettingsPlatformWrapper = ({
|
||||
handleSubmit={async (data) => {
|
||||
atomSchedule.id && handleUpdate(atomSchedule.id, data);
|
||||
}}
|
||||
weekStart="Sunday"
|
||||
weekStart={me?.data?.weekStart || "Sunday"}
|
||||
timeFormat={timeFormat}
|
||||
enableOverrides={enableOverrides}
|
||||
isLoading={isLoading}
|
||||
|
||||
Reference in New Issue
Block a user