fix: fixes multiple issues in routing form (#4676)
* feat: update forms procedure to match getServerSideProps * feat: init react query and use prefetched data * feat: invalidate onSettled while creating a form * feat: use optimistic updates when deleting * fix: add optional chaining * feat: add server-side translation * feat: add correct translation key Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
10ab86b332
commit
ef611e2360
4 files changed
+39
-8
No files matched your search
@@ -62,12 +62,14 @@ function NewFormDialog({ appUrl }: { appUrl: string }) {
|
||||
|
||||
const mutation = trpc.useMutation("viewer.app_routing_forms.formMutation", {
|
||||
onSuccess: (_data, variables) => {
|
||||
utils.invalidateQueries("viewer.app_routing_forms.forms");
|
||||
router.push(`${appUrl}/form-edit/${variables.id}`);
|
||||
},
|
||||
onError: () => {
|
||||
showToast(`Something went wrong`, "error");
|
||||
},
|
||||
onSettled: () => {
|
||||
utils.invalidateQueries("viewer.app_routing_forms.forms");
|
||||
},
|
||||
});
|
||||
|
||||
const hookForm = useForm<{
|
||||
@@ -163,6 +165,15 @@ function Dialogs({
|
||||
const utils = trpc.useContext();
|
||||
const router = useRouter();
|
||||
const deleteMutation = trpc.useMutation("viewer.app_routing_forms.deleteForm", {
|
||||
onMutate: async ({ id: formId }) => {
|
||||
await utils.cancelQuery(["viewer.app_routing_forms.forms"]);
|
||||
const previousValue = utils.getQueryData(["viewer.app_routing_forms.forms"]);
|
||||
if (previousValue) {
|
||||
const filtered = previousValue.filter(({ id }) => id !== formId);
|
||||
utils.setQueryData(["viewer.app_routing_forms.forms"], filtered);
|
||||
}
|
||||
return { previousValue };
|
||||
},
|
||||
onSuccess: () => {
|
||||
showToast("Form deleted", "success");
|
||||
setDeleteDialogOpen(false);
|
||||
@@ -172,7 +183,10 @@ function Dialogs({
|
||||
utils.invalidateQueries(["viewer.app_routing_forms.forms"]);
|
||||
setDeleteDialogOpen(false);
|
||||
},
|
||||
onError: () => {
|
||||
onError: (err, newTodo, context) => {
|
||||
if (context?.previousValue) {
|
||||
utils.setQueryData(["viewer.app_routing_forms.forms"], context.previousValue);
|
||||
}
|
||||
showToast("Something went wrong", "error");
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// TODO: i18n
|
||||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||
|
||||
import useApp from "@calcom/lib/hooks/useApp";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { AppGetServerSidePropsContext, AppPrisma, AppUser } from "@calcom/types/AppGetServerSideProps";
|
||||
import { Icon } from "@calcom/ui/Icon";
|
||||
import { ButtonGroup, DropdownMenuSeparator, Tooltip } from "@calcom/ui/v2";
|
||||
@@ -15,10 +18,12 @@ import { FormAction, FormActionsDropdown, FormActionsProvider } from "../../comp
|
||||
import { getSerializableForm } from "../../lib/getSerializableForm";
|
||||
|
||||
export default function RoutingForms({
|
||||
forms,
|
||||
forms: forms_,
|
||||
appUrl,
|
||||
}: inferSSRProps<typeof getServerSideProps> & { appUrl: string }) {
|
||||
const { t } = useLocale();
|
||||
const { data: forms } = trpc.useQuery(["viewer.app_routing_forms.forms"], { initialData: forms_ });
|
||||
|
||||
const { data: typeformApp } = useApp("typeform");
|
||||
|
||||
function NewFormButton() {
|
||||
@@ -33,7 +38,7 @@ export default function RoutingForms({
|
||||
<FormActionsProvider appUrl={appUrl}>
|
||||
<div className="-mx-4 md:-mx-8">
|
||||
<div className="mb-10 w-full px-4 pb-2 sm:px-6 md:px-8">
|
||||
{!forms.length ? (
|
||||
{!forms?.length ? (
|
||||
<EmptyScreen
|
||||
Icon={Icon.FiGitMerge}
|
||||
headline={t("create_your_first_form")}
|
||||
@@ -41,7 +46,7 @@ export default function RoutingForms({
|
||||
buttonRaw={<NewFormButton />}
|
||||
/>
|
||||
) : null}
|
||||
{forms.length ? (
|
||||
{forms?.length ? (
|
||||
<div className="mb-16 overflow-hidden bg-white">
|
||||
<List data-testid="routing-forms-list">
|
||||
{forms.map((form, index) => {
|
||||
@@ -201,6 +206,7 @@ export const getServerSideProps = async function getServerSideProps(
|
||||
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(context.locale ?? "", ["common"])),
|
||||
forms: serializableForms,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import { sendGenericWebhookPayload } from "@calcom/lib/webhooks/sendPayload";
|
||||
import { TRPCError } from "@calcom/trpc/server";
|
||||
import { createProtectedRouter, createRouter } from "@calcom/trpc/server/createRouter";
|
||||
|
||||
import { getSerializableForm } from "./lib/getSerializableForm";
|
||||
import { isAllowed } from "./lib/isAllowed";
|
||||
import { zodFields, zodRoutes } from "./zod";
|
||||
|
||||
@@ -144,14 +145,24 @@ const app_RoutingForms = createRouter()
|
||||
createProtectedRouter()
|
||||
.query("forms", {
|
||||
async resolve({ ctx: { user, prisma } }) {
|
||||
return await prisma.app_RoutingForms_Form.findMany({
|
||||
const forms = await prisma.app_RoutingForms_Form.findMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: "asc",
|
||||
createdAt: "desc",
|
||||
},
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
responses: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const serializableForms = forms.map((form) => getSerializableForm(form));
|
||||
return serializableForms;
|
||||
},
|
||||
})
|
||||
.query("formQuery", {
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"type": "raycast_other"
|
||||
},
|
||||
{
|
||||
"dirName": "n8n",
|
||||
"dirName": "n8n",
|
||||
"categories": ["automation"],
|
||||
"slug": "n8n",
|
||||
"type": "n8n_automation"
|
||||
|
||||
Reference in new issue
Block a user