Compare commits

...

3 Commits

Author SHA1 Message Date
Aashish Upadhyay 199ebdefa4
fix Former time in wrong time zone (Rescheduling) (#9039)
* fix Former time in wrong time zone (Rescheduling)

* eslint fixed

* yarn.lock push

* little bit of code formatting

* [eslint: fix] missing semi-colon

* linting errors fixed

* Update packages/lib/parse-dates.ts

* returning yarn lock to main

* Refactor constant and functions

* Consider time format in new function

* Fix 24 time format with am/pm

---------

Co-authored-by: alannnc <alannnc@gmail.com>
2023-05-23 07:50:47 +00:00
Shubham kumar 76c286b795
fixes:keyboard-navigation-8887' (#9006) 2023-05-23 07:39:56 +00:00
Rama Krishna Reddy c5bde759e4
remove isPro check (#8967)
* remove isPro check

* remove isPro check

* checkout yarn.lock from main

* checkout yarn.lock from main

* Update _getAdd.ts

* Update common.json

* Revert the revert that got merged in main already

---------

Co-authored-by: rkreddy99 <rreddy@e2clouds.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-05-23 07:32:48 +00:00
9 changed files with 105 additions and 16 deletions

View File

@ -35,7 +35,6 @@ const Component = ({
email,
tos,
privacy,
isProOnly,
teamsPlanRequired,
descriptionItems,
isTemplate,
@ -151,7 +150,6 @@ const Component = ({
{!isGlobal && (
<InstallAppButton
type={type}
isProOnly={isProOnly}
disableInstall={disableInstall}
teamsPlanRequired={teamsPlanRequired}
render={({ useDefaultComponent, ...props }) => {
@ -192,7 +190,6 @@ const Component = ({
) : (
<InstallAppButton
type={type}
isProOnly={isProOnly}
disableInstall={disableInstall}
teamsPlanRequired={teamsPlanRequired}
render={({ useDefaultComponent, ...props }) => {
@ -362,7 +359,6 @@ export default function App(props: {
tos?: string;
privacy?: string;
licenseRequired: AppType["licenseRequired"];
isProOnly: AppType["isProOnly"];
teamsPlanRequired: AppType["teamsPlanRequired"];
descriptionItems?: Array<string | { iframe: IframeHTMLAttributes<HTMLIFrameElement> }>;
isTemplate?: boolean;

View File

@ -22,6 +22,7 @@ import {
useIsEmbed,
} from "@calcom/embed-core/embed-iframe";
import { createBooking, createRecurringBooking } from "@calcom/features/bookings/lib";
import { useTimePreferences } from "@calcom/features/bookings/lib";
import {
getBookingFieldsWithSystemFields,
SystemField,
@ -39,7 +40,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
import { HttpError } from "@calcom/lib/http-error";
import { parseDate, parseRecurringDates } from "@calcom/lib/parse-dates";
import { parseDate, parseDateTimeWithTimeZone, parseRecurringDates } from "@calcom/lib/parse-dates";
import { getEveryFreqFor } from "@calcom/lib/recurringStrings";
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import { TimeFormat } from "@calcom/lib/timeFormat";
@ -231,6 +232,8 @@ const BookingPage = ({
{}
);
const { timezone } = useTimePreferences();
const reserveSlot = () => {
if (queryDuration) {
reserveSlotMutation.mutate({
@ -602,7 +605,7 @@ const BookingPage = ({
<Calendar className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
{isClientTimezoneAvailable &&
typeof booking.startTime === "string" &&
parseDate(dayjs(booking.startTime), i18n.language, {
parseDateTimeWithTimeZone(booking.startTime, i18n.language, timezone, {
selectedTimeFormat: timeFormat,
})}
</p>

View File

@ -73,7 +73,6 @@ function SingleAppPage(props: inferSSRProps<typeof getStaticProps>) {
email={data.email}
licenseRequired={data.licenseRequired}
teamsPlanRequired={data.teamsPlanRequired}
isProOnly={data.isProOnly}
descriptionItems={source.data?.items as string[] | undefined}
isTemplate={data.isTemplate}
dependencies={data.dependencies}

View File

@ -46,7 +46,6 @@ export default function OmniInstallAppButton({
return (
<InstallAppButton
type={app.type}
isProOnly={app.isProOnly}
teamsPlanRequired={app.teamsPlanRequired}
wrapperClassName={classNames("[@media(max-width:260px)]:w-full", className)}
render={({ useDefaultComponent, ...props }) => {

View File

@ -49,7 +49,6 @@ export const InstallAppButtonWithoutPlanCheck = (
export const InstallAppButton = (
props: {
isProOnly?: App["isProOnly"];
teamsPlanRequired?: App["teamsPlanRequired"];
type: App["type"];
wrapperClassName?: string;
@ -86,7 +85,7 @@ export const InstallAppButton = (
},
true
);
}, [isUserLoading, user, router, props.isProOnly, hasTeamPlan, props.teamsPlanRequired]);
}, [isUserLoading, user, router, hasTeamPlan, props.teamsPlanRequired]);
if (isUserLoading || isTeamPlanStatusLoading) {
return null;

View File

@ -1,4 +1,4 @@
import { Fragment, useCallback, useEffect, useMemo, useState } from "react";
import { Fragment, useCallback, useEffect, useMemo, useState, useRef } from "react";
import type {
ArrayPath,
Control,
@ -382,6 +382,38 @@ const CopyTimes = ({
}) => {
const [selected, setSelected] = useState<number[]>([]);
const { i18n, t } = useLocale();
const itteratablesByKeyRef = useRef<(HTMLInputElement | HTMLButtonElement)[]>([]);
useEffect(() => {
document.addEventListener("keydown", handleKeyDown);
return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}, []);
const handleKeyDown = (event: KeyboardEvent) => {
const itteratables = itteratablesByKeyRef.current;
const isActionRequired =
event.key === "Tab" || event.key === "ArrowUp" || event.key === "ArrowDown" || event.key === "Enter";
if (!isActionRequired || !itteratables.length) return;
event.preventDefault();
const currentFocused = document.activeElement as HTMLInputElement | HTMLButtonElement;
let currentIndex = itteratables.findIndex((checkbox) => checkbox === currentFocused);
if (event.key === "Enter") {
if (currentIndex === -1) return;
currentFocused.click();
return;
}
if (currentIndex === -1) {
itteratables[0].focus();
} else {
// Move focus based on the arrow key pressed
if (event.key === "ArrowUp") {
currentIndex = (currentIndex - 1 + itteratables.length) % itteratables.length;
} else if (event.key === "ArrowDown" || event.key === "Tab") {
currentIndex = (currentIndex + 1) % itteratables.length;
}
itteratables[currentIndex].focus();
}
};
return (
<div className="space-y-2 py-2">
@ -402,6 +434,11 @@ const CopyTimes = ({
setSelected([]);
}
}}
ref={(ref) => {
if (ref) {
itteratablesByKeyRef.current.push(ref as HTMLInputElement);
}
}}
/>
</label>
</li>
@ -423,6 +460,12 @@ const CopyTimes = ({
setSelected(selected.filter((item) => item !== weekdayIndex));
}
}}
ref={(ref) => {
if (ref && disabled !== weekdayIndex) {
//we don't need to iterate over disabled elements
itteratablesByKeyRef.current.push(ref as HTMLInputElement);
}
}}
/>
</label>
</li>
@ -432,10 +475,24 @@ const CopyTimes = ({
</div>
<hr className="border-subtle" />
<div className="space-x-2 px-2 rtl:space-x-reverse">
<Button color="minimal" onClick={() => onCancel()}>
<Button
color="minimal"
onClick={() => onCancel()}
ref={(ref) => {
if (ref) {
itteratablesByKeyRef.current.push(ref as HTMLButtonElement);
}
}}>
{t("cancel")}
</Button>
<Button color="primary" onClick={() => onClick(selected)}>
<Button
color="primary"
onClick={() => onClick(selected)}
ref={(ref) => {
if (ref) {
itteratablesByKeyRef.current.push(ref as HTMLButtonElement);
}
}}>
{t("apply")}
</Button>
</div>

View File

@ -25,6 +25,45 @@ export const parseDate = (date: string | null | Dayjs, language: string, options
return processDate(date, language, options);
};
const timeOptions: Intl.DateTimeFormatOptions = {
hour12: true,
hourCycle: "h12",
hour: "numeric",
minute: "numeric",
};
const dateOptions: Intl.DateTimeFormatOptions = {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
};
export const parseDateTimeWithTimeZone = (
date: Date,
language: string,
timezone: string,
options?: ExtraOptions
): string => {
timeOptions.timeZone = timezone;
dateOptions.timeZone = timezone;
if (options?.withDefaultTimeFormat) {
timeOptions.hourCycle = "h12";
} else if (options?.selectedTimeFormat) {
timeOptions.hourCycle = options.selectedTimeFormat === TimeFormat.TWELVE_HOUR ? "h12" : "h24";
if (timeOptions.hourCycle === "h24") {
delete timeOptions.hour12;
}
}
const formattedDate = new Date(date).toLocaleDateString(language, dateOptions);
const formattedTime = new Date(date)
.toLocaleTimeString(language, timeOptions)
.replace(" ", "")
.toLowerCase();
return `${formattedTime}, ${formattedDate}`;
};
export const parseRecurringDates = (
{
startDate,

View File

@ -129,7 +129,6 @@ export interface App {
teamsPlanRequired?: {
upgradeUrl: string;
};
isProOnly?: boolean;
appData?: AppData;
/**
* @deprecated

View File

@ -96,7 +96,6 @@ export function AppCard({ app, credentials, searchText }: AppCardProps) {
? !app.isGlobal && (
<InstallAppButton
type={app.type}
isProOnly={app.isProOnly}
teamsPlanRequired={app.teamsPlanRequired}
disableInstall={!!app.dependencies && !app.dependencyData?.some((data) => !data.installed)}
wrapperClassName="[@media(max-width:260px)]:w-full"
@ -125,7 +124,6 @@ export function AppCard({ app, credentials, searchText }: AppCardProps) {
credentials.length === 0 && (
<InstallAppButton
type={app.type}
isProOnly={app.isProOnly}
wrapperClassName="[@media(max-width:260px)]:w-full"
disableInstall={!!app.dependencies && app.dependencyData?.some((data) => !data.installed)}
teamsPlanRequired={app.teamsPlanRequired}