* feat: Hubspot write to meeting object * fix: translate hardcoded strings and remove debug console.log Co-Authored-By: amit@cal.com <samit91848@gmail.com> * refactor * fix: improve static value detection for placeholder replacement - Changed condition from startsWith/endsWith to includes('{') to properly detect embedded placeholders - Strings like 'Hello {name}!' are now correctly processed for placeholder replacement - Pure placeholder tokens that can't be resolved return null - Partially resolved values are returned as-is Co-Authored-By: amit@cal.com <samit91848@gmail.com> * refactor: split WriteToObjectSettings into types and utils files - Extract interfaces, enums, and type definitions to WriteToObjectSettings.types.ts - Extract constants and utility functions to WriteToObjectSettings.utils.ts - Update main component to use the new utility functions - Improves code organization and maintainability Co-Authored-By: amit@cal.com <samit91848@gmail.com> * revert: restore original static value detection logic Per user request - the startsWith/endsWith check was intentional Co-Authored-By: amit@cal.com <samit91848@gmail.com> * test: add unit tests for HubSpot CRM service Tests cover: - ensureFieldsExistOnMeeting: field validation against HubSpot properties - getTextValueFromBookingTracking: UTM parameter extraction - getTextValueFromBookingResponse: placeholder replacement - getDateFieldValue: date field resolution for different date types - getFieldValue: main field value resolution for all field types - generateWriteToMeetingBody: write-to-meeting body generation - getContacts: contact search functionality Co-Authored-By: amit@cal.com <samit91848@gmail.com> * fix: correct type errors in HubSpot CRM service tests - Import WhenToWrite enum from crm-enums - Replace string literals with WhenToWrite.EVERY_BOOKING enum values - Add missing whenToWrite property to field config objects Co-Authored-By: amit@cal.com <samit91848@gmail.com> * fix: use type casting for intentional type errors in tests - Cast numeric fieldValue to string for testing non-string handling - Cast invalid field type string to CrmFieldType for testing unsupported types Co-Authored-By: amit@cal.com <samit91848@gmail.com> * fix: prevent unhandled promise rejections in HubSpot CRM tests - Re-apply mockGetAppKeysFromSlug implementation in beforeEach to ensure mock is always set correctly after clearAllMocks - Change vi.resetAllMocks() to vi.clearAllMocks() to preserve mock implementations between tests - Add explicit types to satisfy biome lint rules - This fixes the 'Cannot read properties of undefined (reading client_id)' errors that were causing CI to fail with exit code 1 Co-Authored-By: amit@cal.com <samit91848@gmail.com> * refactor: convert HubSpot tests to black-box testing through public methods Co-Authored-By: amit@cal.com <samit91848@gmail.com> * fix: properly type mock CalendarEvent in HubSpot tests Co-Authored-By: amit@cal.com <samit91848@gmail.com> * fix: properly type TFunction in mock CalendarEvent Co-Authored-By: amit@cal.com <samit91848@gmail.com> * chore: graceful owner fail test * refactor * fix: type check * fix: remove null fields * Update packages/app-store/hubspot/lib/CrmService.ts Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
71 lines
2.7 KiB
TypeScript
71 lines
2.7 KiB
TypeScript
import { CrmFieldType, DateFieldType, WhenToWrite } from "@calcom/app-store/_lib/crm-enums";
|
|
|
|
import type { SelectOption } from "./WriteToObjectSettings.types";
|
|
import { BookingActionEnum } from "./WriteToObjectSettings.types";
|
|
|
|
export const DATE_FIELD_TYPE = CrmFieldType.DATE;
|
|
export const CHECKBOX_FIELD_TYPE = CrmFieldType.CHECKBOX;
|
|
|
|
export const FIELD_TYPE_LABELS: Record<CrmFieldType, string> = {
|
|
[CrmFieldType.TEXT]: "text",
|
|
[CrmFieldType.STRING]: "text",
|
|
[CrmFieldType.DATE]: "date",
|
|
[CrmFieldType.DATETIME]: "datetime",
|
|
[CrmFieldType.PHONE]: "phone",
|
|
[CrmFieldType.CHECKBOX]: "checkbox",
|
|
[CrmFieldType.PICKLIST]: "picklist",
|
|
[CrmFieldType.CUSTOM]: "custom",
|
|
[CrmFieldType.TEXTAREA]: "textarea",
|
|
};
|
|
|
|
export const DATE_FIELD_LABEL_MAP: Record<DateFieldType, string> = {
|
|
[DateFieldType.BOOKING_CANCEL_DATE]: "booking_cancel_date",
|
|
[DateFieldType.BOOKING_START_DATE]: "booking_start_date",
|
|
[DateFieldType.BOOKING_CREATED_DATE]: "booking_created_date",
|
|
};
|
|
|
|
export const getWhenToWriteLabelMap = (
|
|
bookingAction: BookingActionEnum
|
|
): Record<WhenToWrite, string> => ({
|
|
[WhenToWrite.EVERY_BOOKING]:
|
|
bookingAction === BookingActionEnum.ON_CANCEL ? "salesforce_on_every_cancellation" : "on_every_booking",
|
|
[WhenToWrite.FIELD_EMPTY]: "only_if_field_is_empty",
|
|
});
|
|
|
|
export const buildFieldTypeOptions = (
|
|
supportedFieldTypes: readonly CrmFieldType[],
|
|
t: (key: string) => string
|
|
): SelectOption<CrmFieldType>[] =>
|
|
supportedFieldTypes.map((type) => ({
|
|
label: t(FIELD_TYPE_LABELS[type]),
|
|
value: type,
|
|
}));
|
|
|
|
export const buildDateFieldValueOptions = (
|
|
bookingAction: BookingActionEnum,
|
|
supportedDateFields: readonly DateFieldType[] | undefined,
|
|
t: (key: string) => string
|
|
): SelectOption<DateFieldType>[] => {
|
|
const defaultDateFields =
|
|
bookingAction === BookingActionEnum.ON_CANCEL
|
|
? [DateFieldType.BOOKING_CANCEL_DATE, DateFieldType.BOOKING_START_DATE, DateFieldType.BOOKING_CREATED_DATE]
|
|
: [DateFieldType.BOOKING_START_DATE, DateFieldType.BOOKING_CREATED_DATE];
|
|
|
|
const fields = supportedDateFields ?? defaultDateFields;
|
|
return fields.map((type) => ({ label: t(DATE_FIELD_LABEL_MAP[type]), value: type }));
|
|
};
|
|
|
|
export const buildWhenToWriteOptions = (
|
|
supportedWriteTriggers: readonly WhenToWrite[],
|
|
bookingAction: BookingActionEnum,
|
|
t: (key: string) => string
|
|
): SelectOption<WhenToWrite>[] => {
|
|
const labelMap = getWhenToWriteLabelMap(bookingAction);
|
|
return supportedWriteTriggers.map((trigger) => ({ label: t(labelMap[trigger]), value: trigger }));
|
|
};
|
|
|
|
export const buildCheckboxFieldValueOptions = (t: (key: string) => string): SelectOption<boolean>[] => [
|
|
{ label: t("true"), value: true },
|
|
{ label: t("false"), value: false },
|
|
];
|