* refactor: apply biome formatting to apps/web (batch 1) Formats apps/web non-modules directories: - apps/web/app - apps/web/lib - apps/web/pages - apps/web/styles - apps/web/server - apps/web/test - Root-level .ts and .mjs files Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: apply biome formatting to apps/web/modules (batch 2) Formats smaller apps/web/modules directories: - onboarding, data-table, users, apps, auth - integration-attribute-sync, shell, availability - feature-flags, team, webhooks, getting-started - feature-opt-in, troubleshooter, schedules, notifications - signup-view.tsx Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: apply biome formatting to apps/web/modules (batch 3) Formats medium apps/web/modules directories: - bookings - event-types - insights - embed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: apply biome formatting to apps/web/modules/ee (batch 4) Formats apps/web/modules/ee directory. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: apply biome formatting to apps/web (batch 5) Formats remaining apps/web directories: - apps/web/modules/settings - apps/web/modules/booking-audit - apps/web/playwright Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: apply biome formatting to apps/web/components (batch 6) Formats remaining apps/web/components files. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: apply biome formatting to new apps/web files from main Formats newly added/modified files from main merge: - WorkflowStepContainer.tsx (resolved merge conflicts) - Newly moved files (blocklist, form-builder, schedules, etc.) - Other files modified in main Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: apply biome formatting to new apps/web files from main Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
104 lines
3.7 KiB
TypeScript
104 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { useForm } from "react-hook-form";
|
|
|
|
import { checkAdminOrOwner } from "@calcom/features/auth/lib/checkAdminOrOwner";
|
|
import SectionBottomActions from "@calcom/features/settings/SectionBottomActions";
|
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
|
import { RRResetInterval, RRTimestampBasis } from "@calcom/prisma/enums";
|
|
import type { RouterOutputs } from "@calcom/trpc/react";
|
|
import { trpc } from "@calcom/trpc/react";
|
|
import { Button } from "@calcom/ui/components/button";
|
|
import { Form } from "@calcom/ui/components/form";
|
|
import { showToast } from "@calcom/ui/components/toast";
|
|
import { revalidateTeamDataCache } from "@calcom/web/app/(booking-page-wrapper)/team/[slug]/[type]/actions";
|
|
|
|
import RoundRobinResetInterval from "./RoundRobinResetInterval";
|
|
import RoundRobinTimestampBasis from "./RoundRobinTimestampBasis";
|
|
|
|
interface RoundRobinSettingsProps {
|
|
team: RouterOutputs["viewer"]["teams"]["get"];
|
|
}
|
|
|
|
const RoundRobinSettings = ({ team }: RoundRobinSettingsProps) => {
|
|
const { t } = useLocale();
|
|
const isAdmin = team && checkAdminOrOwner(team.membership.role);
|
|
const rrResetInterval = team?.rrResetInterval ?? undefined;
|
|
const utils = trpc.useUtils();
|
|
|
|
const initialResetInterval = rrResetInterval ?? RRResetInterval.MONTH;
|
|
const initialTimestampBasis = team?.rrTimestampBasis ?? RRTimestampBasis.CREATED_AT;
|
|
|
|
const form = useForm<{ rrResetInterval: RRResetInterval; rrTimestampBasis: RRTimestampBasis }>({
|
|
defaultValues: {
|
|
rrResetInterval: initialResetInterval,
|
|
rrTimestampBasis: initialTimestampBasis,
|
|
},
|
|
});
|
|
|
|
const [watchedResetInterval, watchedTimestampBasis] = form.watch(["rrResetInterval", "rrTimestampBasis"]);
|
|
const hasChanges =
|
|
watchedResetInterval !== initialResetInterval || watchedTimestampBasis !== initialTimestampBasis;
|
|
|
|
const mutation = trpc.viewer.teams.update.useMutation({
|
|
onError: (err) => {
|
|
showToast(err.message, "error");
|
|
},
|
|
async onSuccess() {
|
|
await utils.viewer.teams.get.invalidate();
|
|
if (team?.slug) {
|
|
// Rounb robin reset interval / basis governs host selection logic on the booking page.
|
|
revalidateTeamDataCache({
|
|
teamSlug: team.slug,
|
|
orgSlug: team.parent?.slug ?? null,
|
|
});
|
|
}
|
|
showToast(t("round_robin_settings_updated_successfully"), "success");
|
|
},
|
|
});
|
|
|
|
if (!isAdmin) {
|
|
return (
|
|
<div className="border-subtle rounded-md border p-5">
|
|
<span className="text-default text-sm">{t("only_owner_change")}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Form
|
|
form={form}
|
|
handleSubmit={(values) => {
|
|
mutation.mutate({
|
|
id: team.id,
|
|
rrResetInterval: values.rrResetInterval,
|
|
rrTimestampBasis: values.rrTimestampBasis,
|
|
});
|
|
}}>
|
|
<div className="border-subtle mt-6 space-x-3 rounded-t-lg border border-b-0 px-4 py-6 pb-0 sm:px-6">
|
|
{" "}
|
|
<div>
|
|
<h4 className="text-emphasis text-sm font-semibold leading-5">{t("round_robin")}</h4>
|
|
<p className="text-default text-sm leading-tight">{t("round_robin_settings_description")}</p>
|
|
<div className="-mx-4 mt-4 sm:-mx-6">
|
|
<div className="border-subtle border-t px-6 py-6">
|
|
<RoundRobinResetInterval />
|
|
</div>
|
|
<div className="border-subtle border-t" />
|
|
<div className="border-subtle px-6 py-6">
|
|
<RoundRobinTimestampBasis />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<SectionBottomActions align="end">
|
|
<Button type="submit" disabled={!hasChanges} color="primary" loading={mutation.isPending}>
|
|
{t("update")}
|
|
</Button>
|
|
</SectionBottomActions>
|
|
</Form>
|
|
);
|
|
};
|
|
|
|
export default RoundRobinSettings;
|