feat: client side pagination in open text questions in responses summary (#1422)

Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
Shubham Palriwala
2023-10-23 19:02:10 +05:30
committed by GitHub
parent 7bf0290d1c
commit b7d9999f4b
5 changed files with 42 additions and 5 deletions
@@ -1,3 +1,4 @@
import React, { useState } from "react";
import { getPersonIdentifier } from "@formbricks/lib/person/util";
import Headline from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/Headline";
import { timeSince } from "@formbricks/lib/time";
@@ -11,10 +12,16 @@ import { questionTypes } from "@/app/lib/questions";
interface OpenTextSummaryProps {
questionSummary: TSurveyQuestionSummary<TSurveyOpenTextQuestion>;
environmentId: string;
openTextResponsesPerPage: number;
}
export default function OpenTextSummary({ questionSummary, environmentId }: OpenTextSummaryProps) {
export default function OpenTextSummary({
questionSummary,
environmentId,
openTextResponsesPerPage,
}: OpenTextSummaryProps) {
const questionTypeInfo = questionTypes.find((type) => type.id === questionSummary.question.type);
const [displayCount, setDisplayCount] = useState(openTextResponsesPerPage);
return (
<div className="rounded-lg border border-slate-200 bg-slate-50 shadow-sm">
@@ -38,7 +45,7 @@ export default function OpenTextSummary({ questionSummary, environmentId }: Open
<div className="col-span-2 pl-4 md:pl-6">Response</div>
<div className="px-4 md:px-6">Time</div>
</div>
{questionSummary.responses.map((response) => {
{questionSummary.responses.slice(0, displayCount).map((response) => {
const displayIdentifier = getPersonIdentifier(response.person!);
return (
<div
@@ -72,6 +79,16 @@ export default function OpenTextSummary({ questionSummary, environmentId }: Open
</div>
);
})}
<div className="my-1 flex justify-center">
{displayCount < questionSummary.responses.length && (
<button
onClick={() => setDisplayCount((prevCount) => prevCount + openTextResponsesPerPage)}
className="my-2 flex h-8 items-center justify-center rounded-lg border border-gray-300 bg-white px-3 text-sm text-gray-500 hover:bg-gray-100 hover:text-gray-700">
Show more
</button>
)}
</div>
</div>
</div>
);
@@ -27,9 +27,15 @@ interface SummaryListProps {
environment: TEnvironment;
survey: TSurvey;
responses: TResponse[];
openTextResponsesPerPage: number;
}
export default function SummaryList({ environment, survey, responses }: SummaryListProps) {
export default function SummaryList({
environment,
survey,
responses,
openTextResponsesPerPage,
}: SummaryListProps) {
const getSummaryData = (): TSurveyQuestionSummary<TSurveyQuestion>[] =>
survey.questions.map((question) => {
const questionResponses = responses
@@ -66,6 +72,7 @@ export default function SummaryList({ environment, survey, responses }: SummaryL
key={questionSummary.question.id}
questionSummary={questionSummary as TSurveyQuestionSummary<TSurveyOpenTextQuestion>}
environmentId={environment.id}
openTextResponsesPerPage={openTextResponsesPerPage}
/>
);
}
@@ -28,6 +28,7 @@ interface SummaryPageProps {
profile: TProfile;
environmentTags: TTag[];
displayCount: number;
openTextResponsesPerPage: number;
}
const SummaryPage = ({
@@ -40,6 +41,7 @@ const SummaryPage = ({
profile,
environmentTags,
displayCount,
openTextResponsesPerPage,
}: SummaryPageProps) => {
const { selectedFilter, dateRange, resetState } = useResponseFilter();
const [showDropOffs, setShowDropOffs] = useState<boolean>(false);
@@ -81,7 +83,12 @@ const SummaryPage = ({
setShowDropOffs={setShowDropOffs}
/>
{showDropOffs && <SummaryDropOffs survey={survey} responses={responses} displayCount={displayCount} />}
<SummaryList responses={filterResponses} survey={survey} environment={environment} />
<SummaryList
responses={filterResponses}
survey={survey}
environment={environment}
openTextResponsesPerPage={openTextResponsesPerPage}
/>
</ContentWrapper>
);
};
@@ -4,7 +4,11 @@ import ResponsesLimitReachedBanner from "@/app/(app)/environments/[environmentId
import { getAnalysisData } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/data";
import SummaryPage from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SummaryPage";
import { authOptions } from "@formbricks/lib/authOptions";
import { REVALIDATION_INTERVAL, SURVEY_BASE_URL } from "@formbricks/lib/constants";
import {
OPEN_TEXT_RESPONSES_PER_PAGE,
REVALIDATION_INTERVAL,
SURVEY_BASE_URL,
} from "@formbricks/lib/constants";
import { getEnvironment } from "@formbricks/lib/environment/service";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
import { getTagsByEnvironmentId } from "@formbricks/lib/tag/service";
@@ -50,6 +54,7 @@ export default async function Page({ params }) {
profile={profile}
environmentTags={tags}
displayCount={displayCount}
openTextResponsesPerPage={OPEN_TEXT_RESPONSES_PER_PAGE}
/>
</>
);
+1
View File
@@ -61,6 +61,7 @@ export const MAIL_FROM = env.MAIL_FROM;
export const NEXTAUTH_SECRET = env.NEXTAUTH_SECRET;
export const NEXTAUTH_URL = env.NEXTAUTH_URL;
export const ITEMS_PER_PAGE = 50;
export const OPEN_TEXT_RESPONSES_PER_PAGE = 5;
// Storage constants
export const UPLOADS_DIR = path.resolve("./uploads");