From d5fc45c5067861ede9c32e531c5e3ac5bc5a1010 Mon Sep 17 00:00:00 2001 From: Luke Vella Date: Sat, 26 Aug 2023 11:02:54 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Optimize=20participant=20q?= =?UTF-8?q?uery?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/participants-provider.tsx | 3 +- apps/web/src/components/poll-context.tsx | 4 +- .../poll/desktop-poll/participant-row.tsx | 3 +- .../poll/manage-poll/finalize-poll-dialog.tsx | 39 ++-- .../manage-poll/notify-participants-form.tsx | 209 ------------------ apps/web/src/contexts/current-event.ts | 32 --- apps/web/src/utils/trpc/types.ts | 7 +- .../trpc/routers/polls/participants.ts | 7 +- 8 files changed, 33 insertions(+), 271 deletions(-) delete mode 100644 apps/web/src/components/poll/manage-poll/notify-participants-form.tsx diff --git a/apps/web/src/components/participants-provider.tsx b/apps/web/src/components/participants-provider.tsx index 44f938629..00cafe367 100644 --- a/apps/web/src/components/participants-provider.tsx +++ b/apps/web/src/components/participants-provider.tsx @@ -1,9 +1,10 @@ import { trpc } from "@rallly/backend"; -import { Participant, Vote, VoteType } from "@rallly/database"; +import { Participant, VoteType } from "@rallly/database"; import * as React from "react"; import { useVisibility } from "@/components/visibility"; import { usePermissions } from "@/contexts/permissions"; +import { Vote } from "@/utils/trpc/types"; import { useRequiredContext } from "./use-required-context"; diff --git a/apps/web/src/components/poll-context.tsx b/apps/web/src/components/poll-context.tsx index 3bfa16af9..d16a91787 100644 --- a/apps/web/src/components/poll-context.tsx +++ b/apps/web/src/components/poll-context.tsx @@ -1,4 +1,4 @@ -import { Participant, Vote, VoteType } from "@rallly/database"; +import { Participant, VoteType } from "@rallly/database"; import { TrashIcon } from "@rallly/icons"; import { keyBy } from "lodash"; import { useTranslation } from "next-i18next"; @@ -10,7 +10,7 @@ import { ParsedTimeSlotOption, } from "@/utils/date-time-utils"; import { useDayjs } from "@/utils/dayjs"; -import { GetPollApiResponse } from "@/utils/trpc/types"; +import { GetPollApiResponse, Vote } from "@/utils/trpc/types"; import ErrorPage from "./error-page"; import { useParticipants } from "./participants-provider"; diff --git a/apps/web/src/components/poll/desktop-poll/participant-row.tsx b/apps/web/src/components/poll/desktop-poll/participant-row.tsx index 86fc3a0cb..b55ee6024 100644 --- a/apps/web/src/components/poll/desktop-poll/participant-row.tsx +++ b/apps/web/src/components/poll/desktop-poll/participant-row.tsx @@ -1,4 +1,4 @@ -import { Participant, Vote, VoteType } from "@rallly/database"; +import { Participant, VoteType } from "@rallly/database"; import { MoreHorizontalIcon } from "@rallly/icons"; import { Button } from "@rallly/ui/button"; import clsx from "clsx"; @@ -8,6 +8,7 @@ import { ParticipantDropdown } from "@/components/participant-dropdown"; import { usePoll } from "@/components/poll-context"; import { useUser } from "@/components/user-provider"; import { usePermissions } from "@/contexts/permissions"; +import { Vote } from "@/utils/trpc/types"; import UserAvatar from "../user-avatar"; import VoteIcon from "../vote-icon"; diff --git a/apps/web/src/components/poll/manage-poll/finalize-poll-dialog.tsx b/apps/web/src/components/poll/manage-poll/finalize-poll-dialog.tsx index f0a20fbfa..edee3251d 100644 --- a/apps/web/src/components/poll/manage-poll/finalize-poll-dialog.tsx +++ b/apps/web/src/components/poll/manage-poll/finalize-poll-dialog.tsx @@ -38,31 +38,22 @@ const useScoreByOptionId = () => { const { options } = usePoll(); return React.useMemo(() => { - const res = options.reduce>((acc, option) => { - acc[option.id] = { yes: [], ifNeedBe: [], no: [] }; - return acc; - }, {}); + const scoreByOptionId: Record = {}; + options.forEach((option) => { + scoreByOptionId[option.id] = { + yes: [], + ifNeedBe: [], + no: [], + }; + }); - const votes = responses.flatMap((response) => response.votes); + responses?.forEach((response) => { + response.votes.forEach((vote) => { + scoreByOptionId[vote.optionId][vote.type].push(response.id); + }); + }); - for (const vote of votes) { - if (!res[vote.optionId]) { - res[vote.optionId] = { yes: [], ifNeedBe: [], no: [] }; - } - - switch (vote.type) { - case "yes": - res[vote.optionId].yes.push(vote.participantId); - break; - case "ifNeedBe": - res[vote.optionId].ifNeedBe.push(vote.participantId); - break; - case "no": - res[vote.optionId].no.push(vote.participantId); - break; - } - } - return res; + return scoreByOptionId; }, [responses, options]); }; @@ -195,7 +186,7 @@ export const FinalizePollForm = ({ {max < options.length ? ( -
+
-
- ) : null} - - ); - }} - /> - - - ); -}; diff --git a/apps/web/src/contexts/current-event.ts b/apps/web/src/contexts/current-event.ts index 844ece026..dbca64d2f 100644 --- a/apps/web/src/contexts/current-event.ts +++ b/apps/web/src/contexts/current-event.ts @@ -25,38 +25,6 @@ export type OptionScore = { no: string[]; }; -export const useScoreByOptionId = () => { - const { data: responses = [] } = useCurrentPollResponses(); - const { data: options = [] } = useCurrentPollOptions(); - return React.useMemo(() => { - const res = options.reduce>((acc, option) => { - acc[option.id] = { yes: [], ifNeedBe: [], no: [] }; - return acc; - }, {}); - - const votes = responses.flatMap((response) => response.votes); - - for (const vote of votes) { - if (!res[vote.optionId]) { - res[vote.optionId] = { yes: [], ifNeedBe: [], no: [] }; - } - - switch (vote.type) { - case "yes": - res[vote.optionId].yes.push(vote.participantId); - break; - case "ifNeedBe": - res[vote.optionId].ifNeedBe.push(vote.participantId); - break; - case "no": - res[vote.optionId].no.push(vote.participantId); - break; - } - } - return res; - }, [responses, options]); -}; - export const useCurrentPollOptions = () => { const pollId = useCurrentEventId(); return trpc.polls.options.list.useQuery({ pollId }); diff --git a/apps/web/src/utils/trpc/types.ts b/apps/web/src/utils/trpc/types.ts index 15365ad34..b91d6cccc 100644 --- a/apps/web/src/utils/trpc/types.ts +++ b/apps/web/src/utils/trpc/types.ts @@ -1,4 +1,4 @@ -import { User } from "@rallly/database"; +import { User, VoteType } from "@rallly/database"; export type GetPollApiResponse = { id: string; @@ -16,3 +16,8 @@ export type GetPollApiResponse = { createdAt: Date; deleted: boolean; }; + +export type Vote = { + optionId: string; + type: VoteType; +}; diff --git a/packages/backend/trpc/routers/polls/participants.ts b/packages/backend/trpc/routers/polls/participants.ts index 2b976d23f..6f29a6575 100644 --- a/packages/backend/trpc/routers/polls/participants.ts +++ b/packages/backend/trpc/routers/polls/participants.ts @@ -21,7 +21,12 @@ export const participants = router({ pollId, }, include: { - votes: true, + votes: { + select: { + optionId: true, + type: true, + }, + }, }, orderBy: [ {