From 662d29a19962b6c6d6213f002827254941392ec2 Mon Sep 17 00:00:00 2001 From: hpkoh Date: Sat, 22 Oct 2022 20:53:30 +0800 Subject: [PATCH] [questions][feat] pagination --- .../questions-question-encounter-router.ts | 5 ++ .../router/questions-question-router.ts | 75 ++++++++++++++++--- apps/portal/src/types/questions.d.ts | 5 +- 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/apps/portal/src/server/router/questions-question-encounter-router.ts b/apps/portal/src/server/router/questions-question-encounter-router.ts index 2894fdf4..3d8d4245 100644 --- a/apps/portal/src/server/router/questions-question-encounter-router.ts +++ b/apps/portal/src/server/router/questions-question-encounter-router.ts @@ -24,9 +24,13 @@ export const questionsQuestionEncounterRouter = createProtectedRouter() const locationCounts: Record = {}; const roleCounts:Record = {}; + const latestSeenAt = questionEncountersData[0].seenAt; + for (let i = 0; i < questionEncountersData.length; i++) { const encounter = questionEncountersData[i]; + latestSeenAt = latestSeenAt < encounter.seenAt ? encounter.seenAt : latestSeenAt; + if (!(encounter.company!.name in companyCounts)) { companyCounts[encounter.company!.name] = 1; } @@ -46,6 +50,7 @@ export const questionsQuestionEncounterRouter = createProtectedRouter() const questionEncounter:AggregatedQuestionEncounter = { companyCounts, + latestSeenAt, locationCounts, roleCounts, } diff --git a/apps/portal/src/server/router/questions-question-router.ts b/apps/portal/src/server/router/questions-question-router.ts index 52c8017c..4ecf9ca8 100644 --- a/apps/portal/src/server/router/questions-question-router.ts +++ b/apps/portal/src/server/router/questions-question-router.ts @@ -14,6 +14,8 @@ export const questionsQuestionRouter = createProtectedRouter() input: z.object({ companyNames: z.string().array(), endDate: z.date().default(new Date()), + idCursor: z.string().optional(), + lastSeenCursor: z.date().optional(), locations: z.string().array(), pageSize: z.number().default(50), questionTypes: z.nativeEnum(QuestionsQuestionType).array(), @@ -21,18 +23,43 @@ export const questionsQuestionRouter = createProtectedRouter() sortOrder: z.nativeEnum(SortOrder), sortType: z.nativeEnum(SortType), startDate: z.date().default(new Date(Date.now() - TWO_WEEK_IN_MS)), + upvoteCursor: z.string().optional(), }), async resolve({ ctx, input }) { const sortCondition = + input.sortType === SortType.TOP + ? [ + { + upvotes: input.sortOrder + }, + { + id: input.sortOrder + } + ] + : [ + { + lastSeenAt: input.sortOrder, + }, + { + id: input.sortOrder + } + ]; + + const cursorCondition = input.sortType === SortType.TOP ? { - upvotes: input.sortOrder, + id: input.idCursor, + upvotes: input.upvoteCursor, } : { - lastSeenAt: input.sortOrder, + id: input.idCursor, + lastSeenAt: input.lastSeenCursor, }; const questionsData = await ctx.prisma.questionsQuestion.findMany({ + cursor: { + ...cursorCondition, + }, include: { _count: { select: { @@ -55,9 +82,8 @@ export const questionsQuestionRouter = createProtectedRouter() }, votes: true, }, - orderBy: { - ...sortCondition, - }, + orderBy: sortCondition, + take: input.pageSize, where: { ...(input.questionTypes.length > 0 ? { @@ -117,16 +143,47 @@ export const questionsQuestionRouter = createProtectedRouter() 0, ); + const companyCounts: Record = {}; + const locationCounts: Record = {}; + const roleCounts:Record = {}; + + let latestSeenAt = data.encounters[0].seenAt; + + for (let i = 0; i < data.encounters.length; i++) { + const encounter = data.encounters[i]; + + latestSeenAt = latestSeenAt < encounter.seenAt ? encounter.seenAt : latestSeenAt; + + if (!(encounter.company!.name in companyCounts)) { + companyCounts[encounter.company!.name] = 1; + } + companyCounts[encounter.company!.name] += 1; + + if (!(encounter.location in locationCounts)) { + locationCounts[encounter.location] = 1; + } + locationCounts[encounter.location] += 1; + + if (!(encounter.role in roleCounts)) { + roleCounts[encounter.role] = 1; + } + roleCounts[encounter.role] += 1; + } + + const question: Question = { - company: data.encounters[0].company!.name ?? 'Unknown company', + aggregatedQuestionEncounters: { + companyCounts, + latestSeenAt, + locationCounts, + roleCounts, + }, content: data.content, id: data.id, - location: data.encounters[0].location ?? 'Unknown location', numAnswers: data._count.answers, numComments: data._count.comments, numVotes: votes, - role: data.encounters[0].role ?? 'Unknown role', - seenAt: data.encounters[0].seenAt, + seenAt: latestSeenAt, type: data.questionType, updatedAt: data.updatedAt, user: data.user?.name ?? '', diff --git a/apps/portal/src/types/questions.d.ts b/apps/portal/src/types/questions.d.ts index d75d82de..1a6ae1e3 100644 --- a/apps/portal/src/types/questions.d.ts +++ b/apps/portal/src/types/questions.d.ts @@ -1,15 +1,13 @@ import type { QuestionsQuestionType } from '@prisma/client'; export type Question = { + aggregatedQuestionEncounters: AggregatedQuestionEncounter; // TODO: company, location, role maps - company: string; content: string; id: string; - location: string; numAnswers: number; numComments: number; numVotes: number; - role: string; seenAt: Date; type: QuestionsQuestionType; updatedAt: Date; @@ -18,6 +16,7 @@ export type Question = { export type AggregatedQuestionEncounter = { companyCounts: Record; + latestSeenAt: Date; locationCounts: Record; roleCounts: Record; };