mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-08 02:43:06 -05:00
chore: response page optimization (#6843)
Co-authored-by: igor-srdoc <igor@srdoc.si>
This commit is contained in:
committed by
GitHub
parent
6999abba3b
commit
00a61f7abe
+26
-13
@@ -26,6 +26,7 @@ interface ResponsePageProps {
|
|||||||
isReadOnly: boolean;
|
isReadOnly: boolean;
|
||||||
isQuotasAllowed: boolean;
|
isQuotasAllowed: boolean;
|
||||||
quotas: TSurveyQuota[];
|
quotas: TSurveyQuota[];
|
||||||
|
initialResponses?: TResponseWithQuotas[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ResponsePage = ({
|
export const ResponsePage = ({
|
||||||
@@ -39,11 +40,12 @@ export const ResponsePage = ({
|
|||||||
isReadOnly,
|
isReadOnly,
|
||||||
isQuotasAllowed,
|
isQuotasAllowed,
|
||||||
quotas,
|
quotas,
|
||||||
|
initialResponses = [],
|
||||||
}: ResponsePageProps) => {
|
}: ResponsePageProps) => {
|
||||||
const [responses, setResponses] = useState<TResponseWithQuotas[]>([]);
|
const [responses, setResponses] = useState<TResponseWithQuotas[]>(initialResponses);
|
||||||
const [page, setPage] = useState<number>(1);
|
const [page, setPage] = useState<number | null>(null);
|
||||||
const [hasMore, setHasMore] = useState<boolean>(true);
|
const [hasMore, setHasMore] = useState<boolean>(initialResponses.length >= responsesPerPage);
|
||||||
const [isFetchingFirstPage, setFetchingFirstPage] = useState<boolean>(true);
|
const [isFetchingFirstPage, setIsFetchingFirstPage] = useState<boolean>(false);
|
||||||
const { selectedFilter, dateRange, resetState } = useResponseFilter();
|
const { selectedFilter, dateRange, resetState } = useResponseFilter();
|
||||||
|
|
||||||
const filters = useMemo(
|
const filters = useMemo(
|
||||||
@@ -56,6 +58,7 @@ export const ResponsePage = ({
|
|||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
|
|
||||||
const fetchNextPage = useCallback(async () => {
|
const fetchNextPage = useCallback(async () => {
|
||||||
|
if (page === null) return;
|
||||||
const newPage = page + 1;
|
const newPage = page + 1;
|
||||||
|
|
||||||
let newResponses: TResponseWithQuotas[] = [];
|
let newResponses: TResponseWithQuotas[] = [];
|
||||||
@@ -94,9 +97,14 @@ export const ResponsePage = ({
|
|||||||
}, [searchParams, resetState]);
|
}, [searchParams, resetState]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchInitialResponses = async () => {
|
const fetchFilteredResponses = async () => {
|
||||||
try {
|
try {
|
||||||
setFetchingFirstPage(true);
|
// skip call for initial mount
|
||||||
|
if (page === null) {
|
||||||
|
setPage(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setIsFetchingFirstPage(true);
|
||||||
let responses: TResponseWithQuotas[] = [];
|
let responses: TResponseWithQuotas[] = [];
|
||||||
|
|
||||||
const getResponsesActionResponse = await getResponsesAction({
|
const getResponsesActionResponse = await getResponsesAction({
|
||||||
@@ -110,19 +118,24 @@ export const ResponsePage = ({
|
|||||||
|
|
||||||
if (responses.length < responsesPerPage) {
|
if (responses.length < responsesPerPage) {
|
||||||
setHasMore(false);
|
setHasMore(false);
|
||||||
|
} else {
|
||||||
|
setHasMore(true);
|
||||||
}
|
}
|
||||||
setResponses(responses);
|
setResponses(responses);
|
||||||
} finally {
|
} finally {
|
||||||
setFetchingFirstPage(false);
|
setIsFetchingFirstPage(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fetchInitialResponses();
|
|
||||||
}, [surveyId, filters, responsesPerPage]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
// Only fetch if filters are applied (not on initial mount with no filters)
|
||||||
setPage(1);
|
const hasFilters =
|
||||||
setHasMore(true);
|
(selectedFilter && Object.keys(selectedFilter).length > 0) ||
|
||||||
}, [filters]);
|
(dateRange && (dateRange.from || dateRange.to));
|
||||||
|
|
||||||
|
if (hasFilters) {
|
||||||
|
fetchFilteredResponses();
|
||||||
|
}
|
||||||
|
}, [filters, responsesPerPage, selectedFilter, dateRange, surveyId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
+5
-1
@@ -3,7 +3,7 @@ import { ResponsePage } from "@/app/(app)/environments/[environmentId]/surveys/[
|
|||||||
import { SurveyAnalysisCTA } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SurveyAnalysisCTA";
|
import { SurveyAnalysisCTA } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/summary/components/SurveyAnalysisCTA";
|
||||||
import { IS_FORMBRICKS_CLOUD, IS_STORAGE_CONFIGURED, RESPONSES_PER_PAGE } from "@/lib/constants";
|
import { IS_FORMBRICKS_CLOUD, IS_STORAGE_CONFIGURED, RESPONSES_PER_PAGE } from "@/lib/constants";
|
||||||
import { getPublicDomain } from "@/lib/getPublicUrl";
|
import { getPublicDomain } from "@/lib/getPublicUrl";
|
||||||
import { getResponseCountBySurveyId } from "@/lib/response/service";
|
import { getResponseCountBySurveyId, getResponses } from "@/lib/response/service";
|
||||||
import { getSurvey } from "@/lib/survey/service";
|
import { getSurvey } from "@/lib/survey/service";
|
||||||
import { getTagsByEnvironmentId } from "@/lib/tag/service";
|
import { getTagsByEnvironmentId } from "@/lib/tag/service";
|
||||||
import { getUser } from "@/lib/user/service";
|
import { getUser } from "@/lib/user/service";
|
||||||
@@ -56,6 +56,9 @@ const Page = async (props) => {
|
|||||||
const isQuotasAllowed = await getIsQuotasEnabled(organizationBilling.plan);
|
const isQuotasAllowed = await getIsQuotasEnabled(organizationBilling.plan);
|
||||||
const quotas = isQuotasAllowed ? await getQuotas(survey.id) : [];
|
const quotas = isQuotasAllowed ? await getQuotas(survey.id) : [];
|
||||||
|
|
||||||
|
// Fetch initial responses on the server to prevent duplicate client-side fetch
|
||||||
|
const initialResponses = await getResponses(params.surveyId, RESPONSES_PER_PAGE, 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContentWrapper>
|
<PageContentWrapper>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
@@ -87,6 +90,7 @@ const Page = async (props) => {
|
|||||||
isReadOnly={isReadOnly}
|
isReadOnly={isReadOnly}
|
||||||
isQuotasAllowed={isQuotasAllowed}
|
isQuotasAllowed={isQuotasAllowed}
|
||||||
quotas={quotas}
|
quotas={quotas}
|
||||||
|
initialResponses={initialResponses}
|
||||||
/>
|
/>
|
||||||
</PageContentWrapper>
|
</PageContentWrapper>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user