refactor: Move integration attribute async components to /web (#27341)

* calendar switch

* wip

* wip

* wip

* fix
This commit is contained in:
Benny Joo
2026-01-28 10:44:18 -03:00
committed by GitHub
parent 8e5a5629a4
commit 1a31f9136b
14 changed files with 40 additions and 42 deletions
@@ -1,11 +1,11 @@
import { _generateMetadata, getTranslate } from "app/_utils";
import IntegrationAttributeSyncView from "@calcom/features/ee/integration-attribute-sync/IntegrationAttributeSyncView";
import { getIntegrationAttributeSyncService } from "@calcom/features/ee/integration-attribute-sync/di/IntegrationAttributeSyncService.container";
import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository";
import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader";
import { PrismaAttributeRepository } from "@calcom/features/attributes/repositories/PrismaAttributeRepository";
import { prisma } from "@calcom/prisma";
import IntegrationAttributeSyncView from "@calcom/web/modules/integration-attribute-sync/components/IntegrationAttributeSyncView";
import { validateUserHasOrgPerms } from "../../../actions/validateUserHasOrgPerms";
@@ -1,4 +1,4 @@
import { UserCalendarSwitch } from "@calcom/features/calendars/CalendarSwitch";
import { UserCalendarSwitch } from "@calcom/web/modules/calendars/components/CalendarSwitch";
interface IConnectedCalendarItem {
name: string;
@@ -9,20 +9,7 @@ import classNames from "@calcom/ui/classNames";
import { Switch } from "@calcom/ui/components/form";
import { Icon } from "@calcom/ui/components/icon";
import { showToast } from "@calcom/ui/components/toast";
export type ICalendarSwitchProps = {
title: string;
externalId: string;
type: string;
isChecked: boolean;
name: string;
isLastItemInList?: boolean;
destination?: boolean;
credentialId: number;
delegationCredentialId: string | null;
eventTypeId: number | null;
disabled?: boolean;
};
import type { ICalendarSwitchProps } from "@calcom/ui/components/calendar-switch";
type UserCalendarSwitchProps = Omit<ICalendarSwitchProps, "eventTypeId">;
@@ -1,6 +1,4 @@
import { SelectedCalendarsSettings } from "@calcom/atoms/selected-calendars/SelectedCalendarsSettings";
import AdditionalCalendarSelector from "@calcom/features/calendars/AdditionalCalendarSelector";
import { CalendarSwitch } from "@calcom/features/calendars/CalendarSwitch";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
@@ -9,6 +7,8 @@ import { Select } from "@calcom/ui/components/form";
import { List } from "@calcom/ui/components/list";
import AppListCard from "@calcom/web/modules/apps/components/AppListCard";
import CredentialActionsDropdown from "@calcom/web/modules/apps/components/CredentialActionsDropdown";
import { CalendarSwitch } from "@calcom/web/modules/calendars/components/CalendarSwitch";
import AdditionalCalendarSelector from "@calcom/web/modules/calendars/components/AdditionalCalendarSelector";
import Link from "next/link";
import React from "react";
@@ -2,7 +2,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { showToast } from "@calcom/ui/components/toast";
import type { IntegrationAttributeSync, ISyncFormData } from "../repositories/IIntegrationAttributeSyncRepository";
import type { IntegrationAttributeSync, ISyncFormData } from "@calcom/features/ee/integration-attribute-sync/repositories/IIntegrationAttributeSyncRepository";
import IntegrationAttributeSyncCard from "./IntegrationAttributeSyncCard";
import type { IIntegrationAttributeSyncCardProps } from "./IntegrationAttributeSyncCard";
@@ -3,11 +3,11 @@ import { Button } from "@calcom/ui/components/button";
import { Input, Select, Switch } from "@calcom/ui/components/form";
import { Icon } from "@calcom/ui/components/icon";
import { getDefaultFieldMapping } from "../lib/fieldMappingHelpers";
import { getDefaultFieldMapping } from "@calcom/features/ee/integration-attribute-sync/lib/fieldMappingHelpers";
import type {
IFieldMappingFormState,
IFieldMappingWithOptionalId,
} from "../repositories/IIntegrationAttributeSyncRepository";
} from "@calcom/features/ee/integration-attribute-sync/repositories/IIntegrationAttributeSyncRepository";
type AttributeOptions = {
label: string;
@@ -115,7 +115,7 @@ export const FieldMappingBuilder = ({
// Find indices of rows with duplicate attribute mappings
const duplicateIndices = new Set<number>();
const seenAttributes = new Map<string, number>(); // attributeId -> first index
value.mappings.forEach((mapping, index) => {
value.mappings.forEach((mapping: IFieldMappingWithOptionalId, index: number) => {
if (mapping.attributeId) {
const firstIndex = seenAttributes.get(mapping.attributeId);
if (firstIndex !== undefined) {
@@ -147,7 +147,7 @@ export const FieldMappingBuilder = ({
const handleRemoveMapping = (index: number) => {
onChange({
...value,
mappings: value.mappings.filter((_, i) => i !== index),
mappings: value.mappings.filter((_: IFieldMappingWithOptionalId, i: number) => i !== index),
});
};
@@ -164,7 +164,7 @@ export const FieldMappingBuilder = ({
{value.mappings.length === 0 ? (
<div className="text-subtle py-6 text-center text-sm">{t("attribute_sync_no_mappings")}</div>
) : (
value.mappings.map((mapping, index) => (
value.mappings.map((mapping: IFieldMappingWithOptionalId, index: number) => (
<MappingRow
key={mapping.id || `new-${index}`}
mapping={mapping}
@@ -14,7 +14,7 @@ import {
type IntegrationAttributeSync,
type ISyncFormData,
RuleOperatorEnum,
} from "../repositories/IIntegrationAttributeSyncRepository";
} from "@calcom/features/ee/integration-attribute-sync/repositories/IIntegrationAttributeSyncRepository";
import { FieldMappingBuilder } from "./FieldMappingBuilder";
import { RuleBuilder } from "./RuleBuilder";
@@ -7,9 +7,9 @@ import type { Attribute } from "@calcom/app-store/routing-forms/types/types";
import { trpc } from "@calcom/trpc/react";
import { Button } from "@calcom/ui/components/button";
import EditIntegrationAttributeSyncCard from "./components/EditIntegrationAttributeSyncCard";
import NewIntegrationAttributeSyncCard from "./components/NewIntegrationAttributeSyncCard";
import type { IntegrationAttributeSync } from "./repositories/IIntegrationAttributeSyncRepository";
import EditIntegrationAttributeSyncCard from "./EditIntegrationAttributeSyncCard";
import NewIntegrationAttributeSyncCard from "./NewIntegrationAttributeSyncCard";
import type { IntegrationAttributeSync } from "@calcom/features/ee/integration-attribute-sync/repositories/IIntegrationAttributeSyncRepository";
interface IIntegrationAttributeSyncViewProps {
credentialsData: {
@@ -2,7 +2,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { showToast } from "@calcom/ui/components/toast";
import type { ISyncFormData } from "../repositories/IIntegrationAttributeSyncRepository";
import type { ISyncFormData } from "@calcom/features/ee/integration-attribute-sync/repositories/IIntegrationAttributeSyncRepository";
import IntegrationAttributeSyncCard from "./IntegrationAttributeSyncCard";
import type { IIntegrationAttributeSyncCardProps } from "./IntegrationAttributeSyncCard";
@@ -18,7 +18,7 @@ import {
isArrayOperator,
isTeamCondition,
type TAttributeSyncRuleConditionWithId,
} from "../lib/ruleHelpers";
} from "@calcom/features/ee/integration-attribute-sync/lib/ruleHelpers";
import {
ConditionIdentifierEnum,
type ConditionOperatorEnum,
@@ -27,7 +27,7 @@ import {
type ITeamCondition,
type RuleOperatorEnum,
type TAttributeSyncRuleCondition,
} from "../repositories/IIntegrationAttributeSyncRepository";
} from "@calcom/features/ee/integration-attribute-sync/repositories/IIntegrationAttributeSyncRepository";
const ensureConditionHasId = (condition: TAttributeSyncRuleCondition): TAttributeSyncRuleConditionWithId => {
if ("_id" in condition && condition._id) {
@@ -64,7 +64,7 @@ const ConditionComponent = ({
}: ConditionComponentProps) => {
const { t } = useLocale();
const conditionTypeOptions = getConditionTypeOptions(t);
const conditionTypeOption = conditionTypeOptions.find((opt) => opt.value === condition.identifier);
const conditionTypeOption = conditionTypeOptions.find((opt: { value: ConditionIdentifierEnum; label: string }) => opt.value === condition.identifier);
const handleTypeChange = (newType: { value: ConditionIdentifierEnum; label: string } | null) => {
if (!newType) return;
@@ -127,7 +127,7 @@ interface TeamConditionFieldsProps {
const TeamConditionFields = ({ condition, onChange, teamOptions, isLoading }: TeamConditionFieldsProps) => {
const { t } = useLocale();
const teamOperatorOptions = getTeamOperatorOptions(t);
const operatorOption = teamOperatorOptions.find((opt) => opt.value === condition.operator);
const operatorOption = teamOperatorOptions.find((opt: { value: ConditionOperatorEnum; label: string }) => opt.value === condition.operator);
const isMulti = isArrayOperator(condition.operator);
const selectedTeams = isMulti
@@ -222,7 +222,7 @@ const AttributeConditionFields = ({
? getOperatorOptionsForAttributeType(selectedAttribute.type, t)
: [];
const operatorOption = operatorOptions.find((opt) => opt.value === condition.operator);
const operatorOption = operatorOptions.find((opt: { value: ConditionOperatorEnum; label: string }) => opt.value === condition.operator);
const handleAttributeChange = (selected: { value: string; label: string } | null) => {
if (!selected) return;
@@ -402,7 +402,7 @@ export const RuleBuilder = ({
}: RuleBuilderProps) => {
const { t } = useLocale();
const parentOperatorOptions = getParentOperatorOptions(t);
const parentOperatorOption = parentOperatorOptions.find((opt) => opt.value === value.operator);
const parentOperatorOption = parentOperatorOptions.find((opt: { value: RuleOperatorEnum; label: string }) => opt.value === value.operator);
const isLoading = isLoadingTeams || isLoadingAttributes;
const handleOperatorChange = (newOperator: { value: RuleOperatorEnum; label: string } | null) => {
@@ -432,7 +432,7 @@ export const RuleBuilder = ({
const handleRemoveCondition = (index: number) => {
onChange({
...value,
conditions: value.conditions.filter((_, i) => i !== index),
conditions: value.conditions.filter((_: TAttributeSyncRuleCondition, i: number) => i !== index),
});
};
@@ -464,7 +464,7 @@ export const RuleBuilder = ({
{t("attribute_sync_no_conditions")}
</div>
) : (
value.conditions.map((condition, index) => {
value.conditions.map((condition: TAttributeSyncRuleCondition, index: number) => {
const conditionWithId = ensureConditionHasId(condition);
return (
<ConditionComponent
@@ -1,6 +1,5 @@
import { useState } from "react";
import type { ICalendarSwitchProps } from "@calcom/features/calendars/CalendarSwitch";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { CALENDARS } from "@calcom/platform-constants";
import { QueryCell } from "@calcom/trpc/components/QueryCell";
@@ -9,7 +8,7 @@ import { Alert } from "@calcom/ui/components/alert";
import { AppListCard } from "@calcom/ui/components/app-list-card";
import type { ButtonProps } from "@calcom/ui/components/button";
import { Button } from "@calcom/ui/components/button";
import { CalendarSwitchComponent } from "@calcom/ui/components/calendar-switch";
import { CalendarSwitchComponent, type ICalendarSwitchProps } from "@calcom/ui/components/calendar-switch";
import { DisconnectIntegrationComponent } from "@calcom/ui/components/disconnect-calendar-integration";
import { Dropdown, DropdownMenuContent, DropdownMenuTrigger } from "@calcom/ui/components/dropdown";
import { Switch } from "@calcom/ui/components/form";
@@ -1,12 +1,24 @@
"use client";
import type { ReactNode } from "react";
import { type ICalendarSwitchProps } from "@calcom/features/calendars/CalendarSwitch";
import classNames from "@calcom/ui/classNames";
import { Icon } from "../icon";
export type ICalendarSwitchProps = {
title: string;
externalId: string;
type: string;
isChecked: boolean;
name: string;
isLastItemInList?: boolean;
destination?: boolean;
credentialId: number;
delegationCredentialId: string | null;
eventTypeId: number | null;
disabled?: boolean;
};
export function CalendarSwitchComponent(
props: ICalendarSwitchProps & {
isLoading: boolean;
@@ -1 +1 @@
export { CalendarSwitchComponent } from "./CalendarSwitch";
export { CalendarSwitchComponent, type ICalendarSwitchProps } from "./CalendarSwitch";