fix: OpenTextSummary no longer has "Show more" button (#2427)

Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
Co-authored-by: Johannes <johannes@formbricks.com>
This commit is contained in:
Piyush Gupta
2024-04-12 20:58:05 +05:30
committed by GitHub
parent fa0cadb166
commit f07dffab07
10 changed files with 243 additions and 165 deletions

View File

@@ -23,44 +23,46 @@ export const AddressSummary = ({ questionSummary, environmentId }: AddressSummar
<div className="col-span-2 pl-4 md:pl-6">Response</div>
<div className="px-4 md:px-6">Time</div>
</div>
{questionSummary.samples.map((response) => {
return (
<div
key={response.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
<div className="pl-4 md:pl-6">
{response.person ? (
<Link
className="ph-no-capture group flex items-center"
href={`/environments/${environmentId}/people/${response.person.id}`}>
<div className="hidden md:flex">
<PersonAvatar personId={response.person.id} />
<div className="max-h-[62vh] w-full overflow-y-auto">
{questionSummary.samples.map((response) => {
return (
<div
key={response.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
<div className="pl-4 md:pl-6">
{response.person ? (
<Link
className="ph-no-capture group flex items-center"
href={`/environments/${environmentId}/people/${response.person.id}`}>
<div className="hidden md:flex">
<PersonAvatar personId={response.person.id} />
</div>
<p className="ph-no-capture break-all text-slate-600 group-hover:underline md:ml-2">
{getPersonIdentifier(response.person)}
</p>
</Link>
) : (
<div className="group flex items-center">
<div className="hidden md:flex">
<PersonAvatar personId="anonymous" />
</div>
<p className="break-all text-slate-600 md:ml-2">Anonymous</p>
</div>
<p className="ph-no-capture break-all text-slate-600 group-hover:underline md:ml-2">
{getPersonIdentifier(response.person)}
</p>
</Link>
) : (
<div className="group flex items-center">
<div className="hidden md:flex">
<PersonAvatar personId="anonymous" />
</div>
<p className="break-all text-slate-600 md:ml-2">Anonymous</p>
</div>
)}
</div>
{
<div className="ph-no-capture col-span-2 pl-6 font-semibold">
<AddressResponse value={response.value} />
)}
</div>
}
{
<div className="ph-no-capture col-span-2 pl-6 font-semibold">
<AddressResponse value={response.value} />
</div>
}
<div className="px-4 text-slate-500 md:px-6">
{timeSince(new Date(response.updatedAt).toISOString())}
<div className="px-4 text-slate-500 md:px-6">
{timeSince(new Date(response.updatedAt).toISOString())}
</div>
</div>
</div>
);
})}
);
})}
</div>
</div>
</div>
);

View File

@@ -1,10 +1,12 @@
import Link from "next/link";
import { useState } from "react";
import { getPersonIdentifier } from "@formbricks/lib/person/util";
import { timeSince } from "@formbricks/lib/time";
import { formatDateWithOrdinal } from "@formbricks/lib/utils/datetime";
import { TSurveyQuestionSummaryDate } from "@formbricks/types/surveys";
import { PersonAvatar } from "@formbricks/ui/Avatars";
import { Button } from "@formbricks/ui/Button";
import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
@@ -14,6 +16,15 @@ interface DateQuestionSummary {
}
export const DateQuestionSummary = ({ questionSummary, environmentId }: DateQuestionSummary) => {
const [visibleResponses, setVisibleResponses] = useState(10);
const handleLoadMore = () => {
// Increase the number of visible responses by 10, not exceeding the total number of responses
setVisibleResponses((prevVisibleResponses) =>
Math.min(prevVisibleResponses + 10, questionSummary.samples.length)
);
};
return (
<div className="rounded-lg border border-slate-200 bg-slate-50 shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
@@ -23,39 +34,48 @@ export const DateQuestionSummary = ({ questionSummary, environmentId }: DateQues
<div className="col-span-2 pl-4 md:pl-6">Response</div>
<div className="px-4 md:px-6">Time</div>
</div>
{questionSummary.samples.map((response) => (
<div
key={response.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
<div className="pl-4 md:pl-6">
{response.person ? (
<Link
className="ph-no-capture group flex items-center"
href={`/environments/${environmentId}/people/${response.person.id}`}>
<div className="hidden md:flex">
<PersonAvatar personId={response.person.id} />
<div className="max-h-[62vh] w-full overflow-y-auto">
{questionSummary.samples.slice(0, visibleResponses).map((response) => (
<div
key={response.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
<div className="pl-4 md:pl-6">
{response.person ? (
<Link
className="ph-no-capture group flex items-center"
href={`/environments/${environmentId}/people/${response.person.id}`}>
<div className="hidden md:flex">
<PersonAvatar personId={response.person.id} />
</div>
<p className="ph-no-capture break-all text-slate-600 group-hover:underline md:ml-2">
{getPersonIdentifier(response.person)}
</p>
</Link>
) : (
<div className="group flex items-center">
<div className="hidden md:flex">
<PersonAvatar personId="anonymous" />
</div>
<p className="break-all text-slate-600 md:ml-2">Anonymous</p>
</div>
<p className="ph-no-capture break-all text-slate-600 group-hover:underline md:ml-2">
{getPersonIdentifier(response.person)}
</p>
</Link>
) : (
<div className="group flex items-center">
<div className="hidden md:flex">
<PersonAvatar personId="anonymous" />
</div>
<p className="break-all text-slate-600 md:ml-2">Anonymous</p>
</div>
)}
</div>
<div className="ph-no-capture col-span-2 whitespace-pre-wrap pl-6 font-semibold">
{formatDateWithOrdinal(new Date(response.value as string))}
</div>
<div className="px-4 text-slate-500 md:px-6">
{timeSince(new Date(response.updatedAt).toISOString())}
)}
</div>
<div className="ph-no-capture col-span-2 whitespace-pre-wrap pl-6 font-semibold">
{formatDateWithOrdinal(new Date(response.value as string))}
</div>
<div className="px-4 text-slate-500 md:px-6">
{timeSince(new Date(response.updatedAt).toISOString())}
</div>
</div>
))}
</div>
{visibleResponses < questionSummary.samples.length && (
<div className="flex justify-center py-4">
<Button onClick={handleLoadMore} variant="secondary" size="sm">
Load more
</Button>
</div>
))}
)}
</div>
</div>
);

View File

@@ -1,11 +1,13 @@
import { DownloadIcon, FileIcon } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import { getPersonIdentifier } from "@formbricks/lib/person/util";
import { getOriginalFileNameFromUrl } from "@formbricks/lib/storage/utils";
import { timeSince } from "@formbricks/lib/time";
import { TSurveyQuestionSummaryFileUpload } from "@formbricks/types/surveys";
import { PersonAvatar } from "@formbricks/ui/Avatars";
import { Button } from "@formbricks/ui/Button";
import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
@@ -15,6 +17,15 @@ interface FileUploadSummaryProps {
}
export const FileUploadSummary = ({ questionSummary, environmentId }: FileUploadSummaryProps) => {
const [visibleResponses, setVisibleResponses] = useState(10);
const handleLoadMore = () => {
// Increase the number of visible responses by 10, not exceeding the total number of responses
setVisibleResponses((prevVisibleResponses) =>
Math.min(prevVisibleResponses + 10, questionSummary.files.length)
);
};
return (
<div className="rounded-lg border border-slate-200 bg-slate-50 shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
@@ -24,72 +35,81 @@ export const FileUploadSummary = ({ questionSummary, environmentId }: FileUpload
<div className="col-span-2 pl-4 md:pl-6">Response</div>
<div className="px-4 md:px-6">Time</div>
</div>
{questionSummary.files.map((response) => (
<div
key={response.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
<div className="pl-4 md:pl-6">
{response.person ? (
<Link
className="ph-no-capture group flex items-center"
href={`/environments/${environmentId}/people/${response.person.id}`}>
<div className="hidden md:flex">
<PersonAvatar personId={response.person.id} />
</div>
<p className="ph-no-capture break-all text-slate-600 group-hover:underline md:ml-2">
{getPersonIdentifier(response.person)}
</p>
</Link>
) : (
<div className="group flex items-center">
<div className="hidden md:flex">
<PersonAvatar personId="anonymous" />
</div>
<p className="break-all text-slate-600 md:ml-2">Anonymous</p>
</div>
)}
</div>
<div className="col-span-2 grid">
{Array.isArray(response.value) &&
(response.value.length > 0 ? (
response.value.map((fileUrl, index) => {
const fileName = getOriginalFileNameFromUrl(fileUrl);
return (
<div className="relative m-2 rounded-lg bg-slate-200" key={fileUrl}>
<a
href={fileUrl as string}
key={index}
download={fileName}
target="_blank"
rel="noopener noreferrer">
<div className="absolute right-0 top-0 m-2">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-slate-50 hover:bg-white">
<DownloadIcon className="h-6 text-slate-500" />
</div>
</div>
</a>
<div className="flex flex-col items-center justify-center p-2">
<FileIcon className="h-6 text-slate-500" />
<p className="mt-2 text-sm text-slate-500 dark:text-slate-400">{fileName}</p>
</div>
</div>
);
})
<div className="max-h-[62vh] w-full overflow-y-auto">
{questionSummary.files.slice(0, visibleResponses).map((response) => (
<div
key={response.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
<div className="pl-4 md:pl-6">
{response.person ? (
<Link
className="ph-no-capture group flex items-center"
href={`/environments/${environmentId}/people/${response.person.id}`}>
<div className="hidden md:flex">
<PersonAvatar personId={response.person.id} />
</div>
<p className="ph-no-capture break-all text-slate-600 group-hover:underline md:ml-2">
{getPersonIdentifier(response.person)}
</p>
</Link>
) : (
<div className="flex w-full flex-col items-center justify-center p-2">
<p className="mt-2 text-sm font-semibold text-slate-500 dark:text-slate-400">skipped</p>
<div className="group flex items-center">
<div className="hidden md:flex">
<PersonAvatar personId="anonymous" />
</div>
<p className="break-all text-slate-600 md:ml-2">Anonymous</p>
</div>
))}
</div>
)}
</div>
<div className="px-4 text-slate-500 md:px-6">
{timeSince(new Date(response.updatedAt).toISOString())}
<div className="col-span-2 grid">
{Array.isArray(response.value) &&
(response.value.length > 0 ? (
response.value.map((fileUrl, index) => {
const fileName = getOriginalFileNameFromUrl(fileUrl);
return (
<div className="relative m-2 rounded-lg bg-slate-200" key={fileUrl}>
<a
href={fileUrl as string}
key={index}
download={fileName}
target="_blank"
rel="noopener noreferrer">
<div className="absolute right-0 top-0 m-2">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-slate-50 hover:bg-white">
<DownloadIcon className="h-6 text-slate-500" />
</div>
</div>
</a>
<div className="flex flex-col items-center justify-center p-2">
<FileIcon className="h-6 text-slate-500" />
<p className="mt-2 text-sm text-slate-500 dark:text-slate-400">{fileName}</p>
</div>
</div>
);
})
) : (
<div className="flex w-full flex-col items-center justify-center p-2">
<p className="mt-2 text-sm font-semibold text-slate-500 dark:text-slate-400">skipped</p>
</div>
))}
</div>
<div className="px-4 text-slate-500 md:px-6">
{timeSince(new Date(response.updatedAt).toISOString())}
</div>
</div>
))}
</div>
{visibleResponses < questionSummary.files.length && (
<div className="flex justify-center py-4">
<Button onClick={handleLoadMore} variant="secondary" size="sm">
Load more
</Button>
</div>
))}
)}
</div>
</div>
);

View File

@@ -1,18 +1,27 @@
import { InboxIcon, Link, MessageSquareTextIcon } from "lucide-react";
import { FC } from "react";
import { useState } from "react";
import { getPersonIdentifier } from "@formbricks/lib/person/util";
import { timeSince } from "@formbricks/lib/time";
import { TEnvironment } from "@formbricks/types/environment";
import { TSurveyQuestionSummaryHiddenFields } from "@formbricks/types/surveys";
import { PersonAvatar } from "@formbricks/ui/Avatars";
import { Button } from "@formbricks/ui/Button";
interface HiddenFieldsSummaryProps {
environment: TEnvironment;
questionSummary: TSurveyQuestionSummaryHiddenFields;
}
export const HiddenFieldsSummary: FC<HiddenFieldsSummaryProps> = ({ environment, questionSummary }) => {
export const HiddenFieldsSummary = ({ environment, questionSummary }: HiddenFieldsSummaryProps) => {
const [visibleResponses, setVisibleResponses] = useState(10);
const handleLoadMore = () => {
// Increase the number of visible responses by 10, not exceeding the total number of responses
setVisibleResponses((prevVisibleResponses) =>
Math.min(prevVisibleResponses + 10, questionSummary.samples.length)
);
};
return (
<div className="rounded-lg border border-slate-200 bg-slate-50 shadow-sm">
<div className="space-y-2 px-4 pb-5 pt-6 md:px-6">
@@ -37,7 +46,7 @@ export const HiddenFieldsSummary: FC<HiddenFieldsSummaryProps> = ({ environment,
<div className="col-span-2 pl-4 md:pl-6">Response</div>
<div className="px-4 md:px-6">Time</div>
</div>
{questionSummary.samples.map((response) => (
{questionSummary.samples.slice(0, visibleResponses).map((response) => (
<div
key={response.value}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
@@ -70,6 +79,13 @@ export const HiddenFieldsSummary: FC<HiddenFieldsSummaryProps> = ({ environment,
</div>
</div>
))}
{visibleResponses < questionSummary.samples.length && (
<div className="flex justify-center py-4">
<Button onClick={handleLoadMore} variant="secondary" size="sm">
Load more
</Button>
</div>
)}
</div>
</div>
);

View File

@@ -1,9 +1,11 @@
import Link from "next/link";
import { useState } from "react";
import { getPersonIdentifier } from "@formbricks/lib/person/util";
import { timeSince } from "@formbricks/lib/time";
import { TSurveyQuestionSummaryOpenText } from "@formbricks/types/surveys";
import { PersonAvatar } from "@formbricks/ui/Avatars";
import { Button } from "@formbricks/ui/Button";
import { QuestionSummaryHeader } from "./QuestionSummaryHeader";
@@ -13,6 +15,15 @@ interface OpenTextSummaryProps {
}
export const OpenTextSummary = ({ questionSummary, environmentId }: OpenTextSummaryProps) => {
const [visibleResponses, setVisibleResponses] = useState(10);
const handleLoadMore = () => {
// Increase the number of visible responses by 10, not exceeding the total number of responses
setVisibleResponses((prevVisibleResponses) =>
Math.min(prevVisibleResponses + 10, questionSummary.samples.length)
);
};
return (
<div className="rounded-lg border border-slate-200 bg-slate-50 shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} />
@@ -22,39 +33,48 @@ export const OpenTextSummary = ({ questionSummary, environmentId }: OpenTextSumm
<div className="col-span-2 pl-4 md:pl-6">Response</div>
<div className="px-4 md:px-6">Time</div>
</div>
{questionSummary.samples.map((response) => (
<div
key={response.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
<div className="pl-4 md:pl-6">
{response.person ? (
<Link
className="ph-no-capture group flex items-center"
href={`/environments/${environmentId}/people/${response.person.id}`}>
<div className="hidden md:flex">
<PersonAvatar personId={response.person.id} />
<div className="max-h-[62vh] w-full overflow-y-auto">
{questionSummary.samples.slice(0, visibleResponses).map((response) => (
<div
key={response.id}
className="grid grid-cols-4 items-center border-b border-slate-100 py-2 text-sm text-slate-800 md:text-base">
<div className="pl-4 md:pl-6">
{response.person ? (
<Link
className="ph-no-capture group flex items-center"
href={`/environments/${environmentId}/people/${response.person.id}`}>
<div className="hidden md:flex">
<PersonAvatar personId={response.person.id} />
</div>
<p className="ph-no-capture break-all text-slate-600 group-hover:underline md:ml-2">
{getPersonIdentifier(response.person)}
</p>
</Link>
) : (
<div className="group flex items-center">
<div className="hidden md:flex">
<PersonAvatar personId="anonymous" />
</div>
<p className="break-all text-slate-600 md:ml-2">Anonymous</p>
</div>
<p className="ph-no-capture break-all text-slate-600 group-hover:underline md:ml-2">
{getPersonIdentifier(response.person)}
</p>
</Link>
) : (
<div className="group flex items-center">
<div className="hidden md:flex">
<PersonAvatar personId="anonymous" />
</div>
<p className="break-all text-slate-600 md:ml-2">Anonymous</p>
</div>
)}
</div>
<div className="ph-no-capture col-span-2 whitespace-pre-wrap pl-6 font-semibold">
{response.value}
</div>
<div className="px-4 text-slate-500 md:px-6">
{timeSince(new Date(response.updatedAt).toISOString())}
)}
</div>
<div className="ph-no-capture col-span-2 whitespace-pre-wrap pl-6 font-semibold">
{response.value}
</div>
<div className="px-4 text-slate-500 md:px-6">
{timeSince(new Date(response.updatedAt).toISOString())}
</div>
</div>
))}
</div>
{visibleResponses < questionSummary.samples.length && (
<div className="flex justify-center py-4">
<Button onClick={handleLoadMore} variant="secondary" size="sm">
Load more
</Button>
</div>
))}
)}
</div>
</div>
);

View File

@@ -685,7 +685,7 @@ export const getQuestionWiseSummary = (
survey: TSurvey,
responses: TResponse[]
): TSurveySummary["summary"] => {
const VALUES_LIMIT = 10;
const VALUES_LIMIT = 50;
let summary: TSurveySummary["summary"] = [];
survey.questions.forEach((question) => {

View File

@@ -50,7 +50,7 @@ export default function CalEmbed({ question, onSuccessfulBooking }: CalEmbedProp
return (
<div className="relative mt-4 max-h-[33vh] overflow-auto">
<div id="fb-cal-embed" className={cn("rounded-lg border border-slate-200")} />
<div id="fb-cal-embed" className={cn("border-border rounded-lg border")} />
</div>
);
}

View File

@@ -254,7 +254,7 @@ export default function FileInput({
<div>
{isUploading && (
<div className="inset-0 flex animate-pulse items-center justify-center rounded-lg py-4">
<label htmlFor="selectedFile" className="text-sm font-medium text-slate-500">
<label htmlFor="selectedFile" className="text-subheading text-sm font-medium">
Uploading...
</label>
</div>

View File

@@ -83,7 +83,7 @@ export default function ThankYouCard({
window.location.replace(buttonLink);
}}
/>
<p class="text-xs">Press Enter </p>
<p class="text-subheading text-xs">Press Enter </p>
</div>
)}
</div>

View File

@@ -125,21 +125,21 @@ export default function WelcomeCard({
</div>
{timeToFinish && !showResponseCount ? (
<div className="item-center mt-4 flex text-slate-500">
<div className="item-center text-subheading mt-4 flex">
<TimerIcon />
<p className="pt-1 text-xs">
<span> Takes {calculateTimeToComplete()} </span>
</p>
</div>
) : showResponseCount && !timeToFinish && responseCount && responseCount > 3 ? (
<div className="item-center mt-4 flex text-slate-500">
<div className="item-center text-subheading mt-4 flex">
<UsersIcon />
<p className="pt-1 text-xs">
<span>{`${responseCount} people responded`}</span>
</p>
</div>
) : timeToFinish && showResponseCount ? (
<div className="item-center mt-4 flex text-slate-500">
<div className="item-center text-subheading mt-4 flex">
<TimerIcon />
<p className="pt-1 text-xs">
<span> Takes {calculateTimeToComplete()} </span>