cal.pub0.org/packages/app-store/ee/routing-forms/trpc-router.ts

458 lines
14 KiB
TypeScript
Raw Normal View History

import { App_RoutingForms_Form, Prisma, User, WebhookTriggerEvents } from "@prisma/client";
import { v4 as uuidv4 } from "uuid";
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
import { z } from "zod";
import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks";
import { sendGenericWebhookPayload } from "@calcom/features/webhooks/lib/sendPayload";
import logger from "@calcom/lib/logger";
import { RoutingFormSettings } from "@calcom/prisma/zod-utils";
import { TRPCError } from "@calcom/trpc/server";
import { authedProcedure, publicProcedure, router } from "@calcom/trpc/server/trpc";
import { Ensure } from "@calcom/types/utils";
import ResponseEmail from "./emails/templates/response-email";
import { jsonLogicToPrisma } from "./jsonLogicToPrisma";
import { getSerializableForm } from "./lib/getSerializableForm";
V2.0 - Routing Forms and Shell 2.0 everywhere (#3902) * Add duplicate form support * Fix duplication logic * Change to feathericons everywhere and other fixes * Dont allow routes for fallback route * Fix banner * Fix Empty Screen * Text area + embded window fixes * Semi fix avatar * Fix all TS issues * Fix tests * Troubleshoot container + Active on count * Support routing using query params * Improve mobile * NITS * Fix padding on input * Support multiselect in router endpoint * Fix the issue where app goes in embed mode after viewing embed once * Fix icons * Add router url tests * Add Responses download and form toggling tests * Add required validation test * Change Icons everywhere * App typeform app * Improvements in cli * Starting to move event types settings to tabs * Begin migration to single page form * Single page tabs * Limits Page * Advanced tab * Add RHF to dependancies * Add typeform how-to-use page * Add typeform how-to-use page and screenshots * Most of advanced tab * Solved RHF mismtach * Build fixes * RHF conditionals fixes * Improved legibility * Fix TS error * Add missing image * Update CliApp.tsx * Major refactor/organisation into optional V2 UI * Portal EditLocationModal * Fix dialoug form * Update imports * Auto Animate + custom inputs WIP * Custom Inputs * WIP Apps * Fixing stories imports * Stripe app * Remove duplicate dialog * Remove duplicate dialog * Major locations cleanup, 10s of bug fixes and app-store improvements * Fix missing pieces * More fixes * Fix embed URL * Fix app toggles + number of active apps * Fix container padding on disabledBorder prop * Removes strict * more fixes * EventType Team page WIP * Fix embed * Use new Shell * NIT * Add Darkmode gray color * V2 Shell WIP * Fix headings on shell V2 * Fix mobile layout with V2 shell * V2 create event type button * Checked Team Select * Hidden to happen on save - not on toggle * Team Attendee Select animation * Get form-edit page working * Get route-builder page working * Fix scheduling type and remove multi select label * Fix overflow on teams url * Get UI as per designs for form-edit * Make route-builder upto date with design * Add no responses banner * Update forms list as per designs * Button shouldnt decide where it would be positioned, users of it might have different requirements * A single select box in a row(when no other select boxes are present) wasnt taking the correct width in comparison to when it had other select boxes * Small missing pieces * Revert console * Revert api * Fixes * Fix Embed TS errors * Fix TS errors * Fix Eslint errors * Fix TS errors for UI * Fix ESLINT error * Fix TS errors * Add missing import * Fix CLI * Add a default placeholder * Remove hardcoded daily:integrations * Fix message for payment page * Revert api and console to main * Update README * Fix TS errors * Fix Lint warnings * Fix Tests * Streamline actions and make them easy to manage * A much more simplified approach to implementing actions * Fix embed * Fix most TS errors * Fix more TS errors * Reduce TS errors to zero * Fix tests * Fix UI * Fix UI * Self review fixes * TS failures caught merge issues * Security hardening * Use V2 Shell everywhere * Add missing file * Problems created by new shell fixed * Fix Shell * Fix Routing Form Card up and down positons * Fix Embed and other design fixes * Fix dropdown old event-types * Fix type errors * Fix allowed chek * Fix dropdown not closing on clicking EMbed button * Fix dropdown not closing on embed button * Fix event-type button group layout * Add label for switch * Fix dropdown in mobile mode * Remove useless comments * Login with pro for tests * Remove bg gray till App-Store pages are revamped Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com>
2022-09-02 19:00:41 +00:00
import { isAllowed } from "./lib/isAllowed";
import { Response, SerializableForm } from "./types/types";
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
import { zodFields, zodRoutes } from "./zod";
async function onFormSubmission(
form: Ensure<SerializableForm<App_RoutingForms_Form> & { user: User }, "fields">,
response: Response
) {
const fieldResponsesByName: Record<string, typeof response[keyof typeof response]["value"]> = {};
for (const [fieldId, fieldResponse] of Object.entries(response)) {
// Use the label lowercased as the key to identify a field.
const key =
form.fields.find((f) => f.id === fieldId)?.identifier ||
(fieldResponse.label as keyof typeof fieldResponsesByName);
fieldResponsesByName[key] = fieldResponse.value;
}
const subscriberOptions = {
userId: form.user.id,
// It isn't an eventType webhook
eventTypeId: -1,
triggerEvent: WebhookTriggerEvents.FORM_SUBMITTED,
};
const webhooks = await getWebhooks(subscriberOptions);
const promises = webhooks.map((webhook) => {
sendGenericWebhookPayload(
webhook.secret,
"FORM_SUBMITTED",
new Date().toISOString(),
webhook,
fieldResponsesByName
).catch((e) => {
console.error(`Error executing routing form webhook`, webhook, e);
});
});
await Promise.all(promises);
if (form.settings?.emailOwnerOnSubmission) {
logger.debug(
`Preparing to send Form Response email for Form:${form.id} to form owner: ${form.user.email}`
);
await sendResponseEmail(form, response, form.user.email);
}
}
const sendResponseEmail = async (
form: Pick<App_RoutingForms_Form, "id" | "name">,
response: Response,
ownerEmail: string
) => {
try {
const email = new ResponseEmail({ form: form, toAddresses: [ownerEmail], response: response });
await email.sendEmail();
} catch (e) {
logger.error("Error sending response email", e);
}
};
const appRoutingForms = router({
public: router({
response: publicProcedure
.input(
z.object({
formId: z.string(),
formFillerId: z.string(),
response: z.record(
z.object({
label: z.string(),
value: z.union([z.string(), z.array(z.string())]),
})
),
})
)
.mutation(async ({ ctx, input }) => {
const { prisma } = ctx;
try {
const { response, formId } = input;
const form = await prisma.app_RoutingForms_Form.findFirst({
where: {
id: formId,
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
},
include: {
user: true,
},
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
});
if (!form) {
throw new TRPCError({
code: "NOT_FOUND",
});
}
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
const serializableForm = getSerializableForm(form);
if (!serializableForm.fields) {
// There is no point in submitting a form that doesn't have fields defined
throw new TRPCError({
code: "BAD_REQUEST",
});
}
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
const serializableFormWithFields = {
...serializableForm,
fields: serializableForm.fields,
};
const missingFields = serializableFormWithFields.fields
.filter((field) => !(field.required ? response[field.id]?.value : true))
.map((f) => f.label);
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
if (missingFields.length) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `Missing required fields ${missingFields.join(", ")}`,
});
}
const invalidFields = serializableFormWithFields.fields
.filter((field) => {
const fieldValue = response[field.id]?.value;
// The field isn't required at this point. Validate only if it's set
if (!fieldValue) {
return false;
}
let schema;
if (field.type === "email") {
schema = z.string().email();
} else if (field.type === "phone") {
schema = z.any();
} else {
schema = z.any();
}
return !schema.safeParse(fieldValue).success;
})
.map((f) => ({ label: f.label, type: f.type }));
if (invalidFields.length) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `Invalid fields ${invalidFields.map((f) => `${f.label}: ${f.type}`)}`,
});
}
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
const dbFormResponse = await prisma.app_RoutingForms_FormResponse.create({
data: input,
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
});
await onFormSubmission(serializableFormWithFields, dbFormResponse.response as Response);
return dbFormResponse;
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === "P2002") {
throw new TRPCError({
code: "CONFLICT",
});
}
}
throw e;
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
}
}),
}),
forms: authedProcedure.query(async ({ ctx }) => {
const { prisma, user } = ctx;
const forms = await prisma.app_RoutingForms_Form.findMany({
where: {
userId: user.id,
},
orderBy: {
createdAt: "desc",
},
include: {
_count: {
select: {
responses: true,
},
},
},
});
const serializableForms = forms.map((form) => getSerializableForm(form));
return serializableForms;
}),
formQuery: authedProcedure
.input(
z.object({
id: z.string(),
})
)
.query(async ({ ctx, input }) => {
const { prisma, user } = ctx;
const form = await prisma.app_RoutingForms_Form.findFirst({
where: {
userId: user.id,
id: input.id,
},
include: {
_count: {
select: {
responses: true,
},
},
},
});
if (!form) {
return null;
}
return getSerializableForm(form);
}),
formMutation: authedProcedure
.input(
z.object({
id: z.string(),
name: z.string(),
description: z.string().nullable().optional(),
disabled: z.boolean().optional(),
fields: zodFields,
routes: zodRoutes,
addFallback: z.boolean().optional(),
duplicateFrom: z.string().nullable().optional(),
settings: RoutingFormSettings.optional(),
})
)
.mutation(async ({ ctx, input }) => {
const { user, prisma } = ctx;
const { name, id, description, settings, disabled, addFallback, duplicateFrom } = input;
if (!(await isAllowed({ userId: user.id, formId: id }))) {
throw new TRPCError({
code: "FORBIDDEN",
});
}
let { routes } = input;
let { fields } = input;
if (duplicateFrom) {
const sourceForm = await prisma.app_RoutingForms_Form.findFirst({
where: {
userId: user.id,
id: duplicateFrom,
},
select: {
fields: true,
routes: true,
},
});
if (!sourceForm) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `Form to duplicate: ${duplicateFrom} not found`,
});
}
const fieldParsed = zodFields.safeParse(sourceForm.fields);
const routesParsed = zodRoutes.safeParse(sourceForm.routes);
if (!fieldParsed.success || !routesParsed.success) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Could not parse source form's fields or routes",
});
}
// Duplicate just routes and fields
// We don't want name, description and responses to be copied
routes = routesParsed.data;
fields = fieldParsed.data;
}
fields = fields || [];
const form = await prisma.app_RoutingForms_Form.findUnique({
where: {
id: id,
},
select: {
id: true,
user: true,
name: true,
description: true,
userId: true,
disabled: true,
createdAt: true,
updatedAt: true,
routes: true,
fields: true,
settings: true,
},
});
// Add back deleted fields in the end. Fields can't be deleted, to make sure columns never decrease which hugely simplifies CSV generation
if (form) {
const serializedForm = getSerializableForm(form, true);
// Find all fields that are in DB(including deleted) but not in the mutation
const deletedFields =
serializedForm.fields?.filter((f) => !fields!.find((field) => field.id === f.id)) || [];
fields = fields.concat(
deletedFields.map((f) => {
f.deleted = true;
return f;
})
);
}
if (addFallback) {
const uuid = uuidv4();
routes = routes || [];
// Add a fallback route if there is none
if (!routes.find((route) => route.isFallback)) {
routes.push({
id: uuid,
isFallback: true,
action: {
type: "customPageMessage",
value: "Thank you for your interest! We will be in touch soon.",
},
queryValue: { id: uuid, type: "group" },
});
}
}
return await prisma.app_RoutingForms_Form.upsert({
where: {
id: id,
},
create: {
user: {
connect: {
id: user.id,
},
},
fields: fields,
name: name,
description,
// Prisma doesn't allow setting null value directly for JSON. It recommends using JsonNull for that case.
routes: routes === null ? Prisma.JsonNull : routes,
id: id,
},
update: {
disabled: disabled,
fields: fields,
name: name,
description,
settings: settings === null ? Prisma.JsonNull : settings,
routes: routes === null ? Prisma.JsonNull : routes,
},
});
}),
deleteForm: authedProcedure
.input(
z.object({
id: z.string(),
})
)
.mutation(async ({ ctx, input }) => {
const { user, prisma } = ctx;
if (!(await isAllowed({ userId: user.id, formId: input.id }))) {
throw new TRPCError({
code: "FORBIDDEN",
});
}
return await prisma.app_RoutingForms_Form.deleteMany({
where: {
id: input.id,
userId: user.id,
},
});
}),
report: authedProcedure
.input(
z.object({
formId: z.string(),
jsonLogicQuery: z.object({
logic: z.union([z.record(z.any()), z.null()]),
}),
cursor: z.number().nullish(), // <-- "cursor" needs to exist when using useInfiniteQuery, but can be any type
})
)
.query(async ({ ctx: { prisma }, input }) => {
// Can be any prisma `where` clause
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const prismaWhere: Record<string, any> = input.jsonLogicQuery
? jsonLogicToPrisma(input.jsonLogicQuery)
: {};
const skip = input.cursor ?? 0;
const take = 50;
logger.debug(
`Built Prisma where ${JSON.stringify(prismaWhere)} from jsonLogicQuery ${JSON.stringify(
input.jsonLogicQuery
)}`
);
const form = await prisma.app_RoutingForms_Form.findUnique({
where: {
id: input.formId,
},
});
if (!form) {
throw new TRPCError({
code: "NOT_FOUND",
message: "Form not found",
});
}
// TODO: Second argument is required to return deleted operators.
const serializedForm = getSerializableForm(form, true);
const rows = await prisma.app_RoutingForms_FormResponse.findMany({
where: {
formId: input.formId,
...prismaWhere,
},
take,
skip,
});
const fields = serializedForm?.fields || [];
const headers = fields.map((f) => f.label + (f.deleted ? "(Deleted)" : ""));
const responses: string[][] = [];
rows.forEach((r) => {
const rowResponses: string[] = [];
responses.push(rowResponses);
fields.forEach((field) => {
if (!r.response) {
return;
}
const response = r.response as Response;
const value = response[field.id]?.value || "";
let stringValue = "";
if (value instanceof Array) {
stringValue = value.join(", ");
} else {
stringValue = value;
}
rowResponses.push(stringValue);
});
});
const areThereNoResultsOrLessThanAskedFor = !rows.length || rows.length < take;
return {
headers,
responses,
nextCursor: areThereNoResultsOrLessThanAskedFor ? null : skip + rows.length,
};
}),
});
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
export default appRoutingForms;