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:
co-authored by
Wesley
Carina Wollendorfer
parent
65e0c0e4c5
commit
d3acf4160d
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user