fix: data collection for headless router (#9183)

Co-authored-by: Wesley <100464352+ologbonowiwi@users.noreply.github.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
This commit is contained in:
Hariom Balhara
2023-08-23 11:12:51 -04:00
committed by GitHub
co-authored by Wesley Carina Wollendorfer
parent 65e0c0e4c5
commit d3acf4160d
4 changed files with 51 additions and 16 deletions
@@ -5,8 +5,26 @@ export default function transformResponse({
value,
}: {
field: Field;
value: Response[string]["value"];
value: Response[string]["value"] | undefined;
}) {
if (!value) {
return "";
}
// type="number" still gives value as a string but we need to store that as number so that number operators can work.
return field.type === "number" && typeof value === "string" ? Number(value) : value;
if (field.type === "number") {
if (typeof value === "string") {
return Number(value);
}
return value;
}
if (field.type === "multiselect") {
if (value instanceof Array) {
return value;
}
return value
.toString()
.split(",")
.map((v) => v.trim());
}
return value;
}
@@ -1,7 +1,9 @@
import Head from "next/head";
import z from "zod";
import { getSlugOrRequestedSlug } from "@calcom/features/ee/organizations/lib/orgDomains";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import logger from "@calcom/lib/logger";
import type { AppGetServerSidePropsContext, AppPrisma } from "@calcom/types/AppGetServerSideProps";
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
@@ -11,6 +13,7 @@ import { processRoute } from "../../lib/processRoute";
import transformResponse from "../../lib/transformResponse";
import type { Response } from "../../types/types";
const log = logger.getChildLogger({ prefix: ["[routing-forms]", "[router]"] });
export default function Router({ form, message }: inferSSRProps<typeof getServerSideProps>) {
return (
<>
@@ -34,7 +37,7 @@ const querySchema = z
slug: z.string(),
pages: z.array(z.string()),
})
.catchall(z.string());
.catchall(z.string().or(z.array(z.string())));
export const getServerSideProps = async function getServerSideProps(
context: AppGetServerSidePropsContext,
@@ -42,6 +45,7 @@ export const getServerSideProps = async function getServerSideProps(
) {
const queryParsed = querySchema.safeParse(context.query);
if (!queryParsed.success) {
log.warn("Error parsing query", queryParsed.error);
return {
notFound: true,
};
@@ -54,11 +58,7 @@ export const getServerSideProps = async function getServerSideProps(
where: {
id: formId,
user: {
organization: isValidOrgDomain
? {
slug: currentOrgDomain,
}
: null,
organization: isValidOrgDomain && currentOrgDomain ? getSlugOrRequestedSlug(currentOrgDomain) : null,
},
},
});
@@ -70,13 +70,13 @@ export const getServerSideProps = async function getServerSideProps(
}
const serializableForm = await getSerializableForm({ form });
const response: Record<string, Pick<Response[string], "value">> = {};
const response: Response = {};
serializableForm.fields?.forEach((field) => {
const fieldResponse = fieldsResponses[getFieldIdentifier(field)] || "";
const value =
field.type === "multiselect" ? fieldResponse.split(",").map((r) => r.trim()) : fieldResponse;
response[field.id] = {
value: transformResponse({ field, value }),
label: field.label,
value: transformResponse({ field, value: fieldResponse }),
};
});
@@ -86,6 +86,18 @@ export const getServerSideProps = async function getServerSideProps(
throw new Error("No matching route could be found");
}
const { createContext } = await import("@calcom/trpc/server/createContext");
const ctx = await createContext(context);
const { default: trpcRouter } = await import("@calcom/app-store/routing-forms/trpc/_router");
const caller = trpcRouter.createCaller(ctx);
const { v4: uuidv4 } = await import("uuid");
await caller.public.response({
formId: form.id,
formFillerId: uuidv4(),
response: response,
});
//TODO: Maybe take action after successful mutation
if (decidedAction.type === "customPageMessage") {
return {
@@ -109,6 +121,7 @@ export const getServerSideProps = async function getServerSideProps(
},
};
}
return {
props: {
form: serializableForm,
@@ -20,6 +20,7 @@ import FormInputFields from "../../components/FormInputFields";
import getFieldIdentifier from "../../lib/getFieldIdentifier";
import { getSerializableForm } from "../../lib/getSerializableForm";
import { processRoute } from "../../lib/processRoute";
import transformResponse from "../../lib/transformResponse";
import type { Response, Route } from "../../types/types";
type Props = inferSSRProps<typeof getServerSideProps>;
@@ -303,8 +304,9 @@ const usePrefilledResponse = (form: Props["form"]) => {
const valuesFromQuery = searchParams?.getAll(getFieldIdentifier(field)).filter(Boolean);
// We only want to keep arrays if the field is a multi-select
const value = valuesFromQuery.length > 1 ? valuesFromQuery : valuesFromQuery[0];
prefillResponse[field.id] = {
value: value || "",
value: transformResponse({ field, value }),
label: field.label,
};
});
@@ -6,7 +6,6 @@ import logger from "@calcom/lib/logger";
import { WebhookTriggerEvents } from "@calcom/prisma/client";
import type { Ensure } from "@calcom/types/utils";
import ResponseEmail from "../emails/templates/response-email";
import type { Response, SerializableForm } from "../types/types";
export async function onFormSubmission(
@@ -58,8 +57,11 @@ export const sendResponseEmail = async (
ownerEmail: string
) => {
try {
const email = new ResponseEmail({ form: form, toAddresses: [ownerEmail], response: response });
await email.sendEmail();
if (typeof window === "undefined") {
const { default: ResponseEmail } = await import("../emails/templates/response-email");
const email = new ResponseEmail({ form: form, toAddresses: [ownerEmail], response: response });
await email.sendEmail();
}
} catch (e) {
logger.error("Error sending response email", e);
}