perf: migrate listHandler to AttributeRepository + cache attributes fetching in RSCs (#21552)
* refactor: migrate listHandler to AttributeRepository Co-Authored-By: benny@cal.com <benny@cal.com> * cache attributes list --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: benny@cal.com <benny@cal.com> Co-authored-by: hbjORbj <sldisek783@gmail.com>
This commit is contained in:
co-authored by
benny@cal.com
hbjORbj
parent
c3add4bae8
commit
e115095198
@@ -1,11 +1,5 @@
|
||||
import { createRouterCaller } from "app/_trpc/context";
|
||||
import { _generateMetadata } from "app/_utils";
|
||||
|
||||
import { attributesRouter } from "@calcom/trpc/server/routers/viewer/attributes/_router";
|
||||
import { viewerOrganizationsRouter } from "@calcom/trpc/server/routers/viewer/organizations/_router";
|
||||
|
||||
import { MembersView } from "~/members/members-view";
|
||||
|
||||
export const generateMetadata = async ({ params }: { params: Promise<{ id: string }> }) =>
|
||||
await _generateMetadata(
|
||||
(t) => t("organization_members"),
|
||||
@@ -15,20 +9,4 @@ export const generateMetadata = async ({ params }: { params: Promise<{ id: strin
|
||||
`/settings/organizations/${(await params).id}/members`
|
||||
);
|
||||
|
||||
const ServerPageWrapper = async () => {
|
||||
const [orgCaller, attributesCaller] = await Promise.all([
|
||||
createRouterCaller(viewerOrganizationsRouter),
|
||||
createRouterCaller(attributesRouter),
|
||||
]);
|
||||
const [org, teams, facetedTeamValues, attributes] = await Promise.all([
|
||||
orgCaller.listCurrent(),
|
||||
orgCaller.getTeams(),
|
||||
orgCaller.getFacetedValues(),
|
||||
attributesCaller.list(),
|
||||
]);
|
||||
return (
|
||||
<MembersView org={org} teams={teams} facetedTeamValues={facetedTeamValues} attributes={attributes} />
|
||||
);
|
||||
};
|
||||
|
||||
export default ServerPageWrapper;
|
||||
export { default } from "../../members/page";
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
"use server";
|
||||
|
||||
import { revalidateTag } from "next/cache";
|
||||
|
||||
export async function revalidateAttributesList() {
|
||||
revalidateTag("viewer.attributes.list");
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import { createRouterCaller } from "app/_trpc/context";
|
||||
import { _generateMetadata } from "app/_utils";
|
||||
import { unstable_cache } from "next/cache";
|
||||
|
||||
import { attributesRouter } from "@calcom/trpc/server/routers/viewer/attributes/_router";
|
||||
import { AttributeRepository } from "@calcom/lib/server/repository/attribute";
|
||||
import { viewerOrganizationsRouter } from "@calcom/trpc/server/routers/viewer/organizations/_router";
|
||||
|
||||
import { MembersView } from "~/members/members-view";
|
||||
@@ -15,18 +16,22 @@ export const generateMetadata = async () =>
|
||||
"/settings/organizations/members"
|
||||
);
|
||||
|
||||
const getCachedAttributes = unstable_cache(
|
||||
async (orgId: number) => {
|
||||
return await AttributeRepository.findAllByOrgIdWithOptions({ orgId });
|
||||
},
|
||||
["viewer.attributes.list"],
|
||||
{ revalidate: 3600 } // Cache for 1 hour
|
||||
);
|
||||
|
||||
const Page = async () => {
|
||||
const [orgCaller, attributesCaller] = await Promise.all([
|
||||
createRouterCaller(viewerOrganizationsRouter),
|
||||
createRouterCaller(attributesRouter),
|
||||
]);
|
||||
const [org, teams, facetedTeamValues, attributes] = await Promise.all([
|
||||
const orgCaller = await createRouterCaller(viewerOrganizationsRouter);
|
||||
const [org, teams, facetedTeamValues] = await Promise.all([
|
||||
orgCaller.listCurrent(),
|
||||
orgCaller.getTeams(),
|
||||
orgCaller.getFacetedValues(),
|
||||
attributesCaller.list(),
|
||||
]);
|
||||
|
||||
const attributes = await getCachedAttributes(org.id);
|
||||
return (
|
||||
<MembersView org={org} teams={teams} facetedTeamValues={facetedTeamValues} attributes={attributes} />
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { ConfirmationDialogContent } from "@calcom/ui/components/dialog";
|
||||
import { showToast } from "@calcom/ui/components/toast";
|
||||
import { revalidateAttributesList } from "@calcom/web/app/(use-page-wrapper)/settings/organizations/members/actions";
|
||||
|
||||
type AttributeItemProps = RouterOutputs["viewer"]["attributes"]["list"][number];
|
||||
|
||||
@@ -23,6 +24,7 @@ export function DeleteAttributeModal({
|
||||
onSuccess: () => {
|
||||
showToast(t("attribute_deleted_successfully"), "success");
|
||||
utils.viewer.attributes.list.invalidate();
|
||||
revalidateAttributesList();
|
||||
},
|
||||
onError: (err) => {
|
||||
showToast(err.message, "error");
|
||||
|
||||
+3
-1
@@ -7,8 +7,9 @@ import { z } from "zod";
|
||||
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { showToast } from "@calcom/ui/components/toast";
|
||||
import { Button } from "@calcom/ui/components/button";
|
||||
import { showToast } from "@calcom/ui/components/toast";
|
||||
import { revalidateAttributesList } from "@calcom/web/app/(use-page-wrapper)/settings/organizations/members/actions";
|
||||
|
||||
import { AttributeForm } from "./AttributesForm";
|
||||
|
||||
@@ -37,6 +38,7 @@ function CreateAttributesPage() {
|
||||
id,
|
||||
});
|
||||
utils.viewer.attributes.list.invalidate();
|
||||
revalidateAttributesList();
|
||||
},
|
||||
onError: (err) => {
|
||||
showToast(err.message, "error");
|
||||
|
||||
@@ -42,4 +42,15 @@ export class AttributeRepository {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static async findAllByOrgIdWithOptions({ orgId }: { orgId: number }) {
|
||||
return await prisma.attribute.findMany({
|
||||
where: {
|
||||
teamId: orgId,
|
||||
},
|
||||
include: {
|
||||
options: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import prisma from "@calcom/prisma";
|
||||
import { AttributeRepository } from "@calcom/lib/server/repository/attribute";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
@@ -20,14 +20,7 @@ const listHandler = async (opts: GetOptions) => {
|
||||
});
|
||||
}
|
||||
|
||||
return await prisma.attribute.findMany({
|
||||
where: {
|
||||
teamId: org.id,
|
||||
},
|
||||
include: {
|
||||
options: true,
|
||||
},
|
||||
});
|
||||
return await AttributeRepository.findAllByOrgIdWithOptions({ orgId: org.id });
|
||||
};
|
||||
|
||||
export default listHandler;
|
||||
|
||||
Reference in New Issue
Block a user