"use client"; import { useCallback, useState } from "react"; import { Query, Builder, Utils as QbUtils } from "react-awesome-query-builder"; import type { ImmutableTree, BuilderProps } from "react-awesome-query-builder"; import type { JsonTree } from "react-awesome-query-builder"; import { withRaqbSettingsAndWidgets, ConfigFor, } from "@calcom/app-store/routing-forms/components/react-awesome-query-builder/config/uiConfig"; import { getQueryBuilderConfigForAttributes } from "@calcom/app-store/routing-forms/lib/getQueryBuilderConfig"; import { classNames as cn } from "@calcom/lib"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { isEqual } from "@calcom/lib/isEqual"; import { buildStateFromQueryValue } from "@calcom/lib/raqb/raqbUtils"; import type { AttributesQueryValue } from "@calcom/lib/raqb/types"; import { trpc, type RouterOutputs } from "@calcom/trpc"; export type Attributes = RouterOutputs["viewer"]["appRoutingForms"]["getAttributesForTeam"]; export function useAttributes(teamId: number) { const { data: attributes, isPending } = trpc.viewer.appRoutingForms.getAttributesForTeam.useQuery({ teamId, }); return { attributes, isPending, }; } function SegmentWithAttributes({ attributes, teamId, queryValue: initialQueryValue, onQueryValueChange, className, }: { attributes: Attributes; teamId: number; queryValue: AttributesQueryValue | null; onQueryValueChange: ({ queryValue }: { queryValue: AttributesQueryValue }) => void; className?: string; }) { const attributesQueryBuilderConfig = getQueryBuilderConfigForAttributes({ attributes, }); const [queryValue, setQueryValue] = useState(initialQueryValue); const attributesQueryBuilderConfigWithRaqbSettingsAndWidgets = withRaqbSettingsAndWidgets({ config: attributesQueryBuilderConfig, configFor: ConfigFor.Attributes, }); const queryBuilderData = buildStateFromQueryValue({ queryValue: queryValue as JsonTree, config: attributesQueryBuilderConfigWithRaqbSettingsAndWidgets, }); const renderBuilder = useCallback( (props: BuilderProps) => (
), [] ); function onChange(immutableTree: ImmutableTree) { const jsonTree = QbUtils.getTree(immutableTree) as AttributesQueryValue; // IMPORTANT: RAQB calls onChange even without explicit user action. It just identifies if the props have changed or not. isEqual ensures that we don't end up having infinite re-renders. if (!isEqual(jsonTree, queryValue)) { setQueryValue(jsonTree); onQueryValueChange({ queryValue: jsonTree, }); } } return ( // cal-query-builder class has special styling through global CSS, allowing us to customize RAQB
); } function MatchingTeamMembers({ teamId, queryValue, }: { teamId: number; queryValue: AttributesQueryValue | null; }) { const { t } = useLocale(); // Check if queryValue has valid children properties value const hasValidValue = queryValue?.children1 ? Object.values(queryValue.children1).some( (child) => child.properties?.value?.[0] !== undefined && child.properties?.value?.[0] !== null ) : false; const { data: matchingTeamMembersWithResult, isPending } = trpc.viewer.attributes.findTeamMembersMatchingAttributeLogic.useQuery( { teamId, attributesQueryValue: queryValue, _enablePerf: true, }, { enabled: hasValidValue, } ); if (isPending) { return (
); } if (!matchingTeamMembersWithResult) return {t("something_went_wrong")}; const { result: matchingTeamMembers } = matchingTeamMembersWithResult; if (!matchingTeamMembers || !queryValue) { return (
{t("no_filter_set")}
); } return (
{t("x_matching_members", { x: matchingTeamMembers.length })}
); } export function Segment({ teamId, queryValue, onQueryValueChange, className, }: { teamId: number; queryValue: AttributesQueryValue | null; onQueryValueChange: ({ queryValue }: { queryValue: AttributesQueryValue }) => void; className?: string; }) { const { attributes, isPending } = useAttributes(teamId); const { t } = useLocale(); if (isPending) return Loading...; if (!attributes) { console.log("Error fetching attributes"); return {t("something_went_wrong")}; } return ( ); }