Skip to content

Commit

Permalink
issue #393: debounce form fields
Browse files Browse the repository at this point in the history
  • Loading branch information
k-allagbe committed Jan 24, 2025
1 parent 4d3425a commit b7012e8
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 99 deletions.
25 changes: 16 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"i18next-resources-to-backend": "^1.2.1",
"jest-environment-jsdom": "^29.7.0",
"js-cookie": "^3.0.5",
"lodash.debounce": "^4.0.8",
"next": "15.1.6",
"react": "^19",
"react-dom": "^19",
Expand Down
7 changes: 1 addition & 6 deletions src/app/label-data-validation/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,9 @@ function LabelDataValidationPage() {
};
}, [uploadedFiles, showAlert, router, storedLabelData, setLabelData]);

const getFiles = () => {
console.log("log uploadedFiles:", uploadedFiles);
return uploadedFiles.map((file) => file.getFile());
};

return (
<LabelDataValidator
files={getFiles()}
files={uploadedFiles.map((file) => file.getFile())}
labelData={labelData}
setLabelData={setLabelData}
loading={loading}
Expand Down
17 changes: 8 additions & 9 deletions src/components/BaseInformationForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FormComponentProps, LabelData, UNITS } from "@/types/types";
import useDebouncedSave from "@/utils/client/useDebouncedSave";
import { Box } from "@mui/material";
import { useEffect } from "react";
import { FormProvider, useForm, useWatch } from "react-hook-form";
Expand All @@ -12,30 +13,28 @@ const BaseInformationForm: React.FC<FormComponentProps> = ({
setLabelData,
}) => {
const { t } = useTranslation("labelDataValidator");
const sectionName = "baseInformation";
const methods = useForm<LabelData>({
defaultValues: labelData,
});

const watchedBaseInformation = useWatch({
control: methods.control,
name: "baseInformation",
name: sectionName,
});

const save = useDebouncedSave(setLabelData);

useEffect(() => {
const currentValues = methods.getValues();
if (JSON.stringify(currentValues) !== JSON.stringify(labelData)) {
methods.reset(labelData);
}
}, [labelData, methods]);

useEffect(() => {
if (watchedBaseInformation) {
setLabelData((prevLabelData) => ({
...prevLabelData,
baseInformation: watchedBaseInformation,
}));
}
}, [watchedBaseInformation, setLabelData]);
save(sectionName, watchedBaseInformation);
}, [watchedBaseInformation, save]);

return (
<FormProvider {...methods}>
Expand Down
17 changes: 8 additions & 9 deletions src/components/CautionsForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FormComponentProps, LabelData } from "@/types/types";
import useDebouncedSave from "@/utils/client/useDebouncedSave";
import { Box } from "@mui/material";
import { useEffect } from "react";
import { FormProvider, useForm, useWatch } from "react-hook-form";
Expand All @@ -12,12 +13,15 @@ const CautionsForm: React.FC<FormComponentProps> = ({
const methods = useForm<LabelData>({
defaultValues: labelData,
});
const sectionName = "cautions";

const watchedCautions = useWatch({
control: methods.control,
name: "cautions",
name: sectionName,
});

const save = useDebouncedSave(setLabelData);

useEffect(() => {
const currentValues = methods.getValues();
if (JSON.stringify(currentValues) !== JSON.stringify(labelData)) {
Expand All @@ -26,18 +30,13 @@ const CautionsForm: React.FC<FormComponentProps> = ({
}, [labelData, methods]);

useEffect(() => {
if (watchedCautions) {
setLabelData((prevLabelData) => ({
...prevLabelData,
cautions: watchedCautions,
}));
}
}, [watchedCautions, setLabelData]);
save(sectionName, watchedCautions);
}, [watchedCautions, save]);

return (
<FormProvider {...methods}>
<Box className="p-4" data-testid="cautions-form">
<VerifiedBilingualTable path={"cautions"} loading={loading} />
<VerifiedBilingualTable path={sectionName} loading={loading} />
</Box>
</FormProvider>
);
Expand Down
15 changes: 7 additions & 8 deletions src/components/GuaranteedAnalysisForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FormComponentProps, LabelData, UNITS } from "@/types/types";
import useDebouncedSave from "@/utils/client/useDebouncedSave";
import { Box, Typography } from "@mui/material";
import { useEffect } from "react";
import { FormProvider, useForm, useWatch } from "react-hook-form";
Expand All @@ -15,12 +16,15 @@ const GuaranteedAnalysisForm: React.FC<FormComponentProps> = ({
const methods = useForm<LabelData>({
defaultValues: labelData,
});
const sectionName = "guaranteedAnalysis";

const watchedGuaranteedAnalysis = useWatch({
control: methods.control,
name: "guaranteedAnalysis",
name: sectionName,
});

const save = useDebouncedSave(setLabelData);

useEffect(() => {
const currentValues = methods.getValues();
if (JSON.stringify(currentValues) !== JSON.stringify(labelData)) {
Expand All @@ -29,13 +33,8 @@ const GuaranteedAnalysisForm: React.FC<FormComponentProps> = ({
}, [labelData, methods]);

useEffect(() => {
if (watchedGuaranteedAnalysis) {
setLabelData((prevLabelData) => ({
...prevLabelData,
guaranteedAnalysis: watchedGuaranteedAnalysis,
}));
}
}, [watchedGuaranteedAnalysis, setLabelData]);
save(sectionName, watchedGuaranteedAnalysis);
}, [watchedGuaranteedAnalysis, save]);

return (
<FormProvider {...methods}>
Expand Down
19 changes: 2 additions & 17 deletions src/components/ImageViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ZoomOutIcon from "@mui/icons-material/ZoomOut";
import { Box, Button } from "@mui/material";
import Tooltip from "@mui/material/Tooltip";
import Image from "next/image";
import { useEffect, useState } from "react";
import { useState } from "react";
import type { ReactZoomPanPinchRef } from "react-zoom-pan-pinch";
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
import "swiper/css";
Expand All @@ -19,27 +19,12 @@ interface ImageViewerProps {
}

const ImageViewer: React.FC<ImageViewerProps> = ({ imageFiles }) => {
const [imageUrls, setImageUrls] = useState<string[]>([]);
const [swiperInstance, setSwiperInstance] = useState<SwiperClass | null>(
null,
);
const [zoomRefs, setZoomRefs] = useState<ReactZoomPanPinchRef[]>([]);
const [activeIndex, setActiveIndex] = useState(0);

useEffect(() => {
const urls = imageFiles.map((file) => URL.createObjectURL(file));
setImageUrls(urls);
setZoomRefs((prevRefs) =>
Array.from({ length: urls.length }, (_, i) => prevRefs[i] || null),
);
return () => {
urls.forEach((url) => URL.revokeObjectURL(url));
};
}, [imageFiles, setZoomRefs, setImageUrls, setActiveIndex]);

useEffect(() => {
zoomRefs.forEach((ref) => ref?.resetTransform());
}, [imageFiles, zoomRefs]);
const imageUrls = imageFiles.map((file) => URL.createObjectURL(file));

const handleInit = (index: number, ref: ReactZoomPanPinchRef) => {
setZoomRefs((prevRefs) => {
Expand Down
17 changes: 8 additions & 9 deletions src/components/IngredientsForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FormComponentProps, LabelData, UNITS } from "@/types/types";
import useDebouncedSave from "@/utils/client/useDebouncedSave";
import { Box } from "@mui/material";
import { useEffect } from "react";
import { FormProvider, useForm, useWatch } from "react-hook-form";
Expand All @@ -12,14 +13,17 @@ function IngredientsForm({
const methods = useForm<LabelData>({
defaultValues: labelData,
});
const sectionName = "ingredients";

const { control } = methods;

const watchedIngredients = useWatch({
control,
name: "ingredients",
name: sectionName,
});

const save = useDebouncedSave(setLabelData);

useEffect(() => {
const currentValues = methods.getValues();
if (JSON.stringify(currentValues) !== JSON.stringify(labelData)) {
Expand All @@ -28,19 +32,14 @@ function IngredientsForm({
}, [labelData, methods]);

useEffect(() => {
if (watchedIngredients) {
setLabelData((prevLabelData) => ({
...prevLabelData,
ingredients: watchedIngredients,
}));
}
}, [watchedIngredients, setLabelData]);
save(sectionName, watchedIngredients);
}, [watchedIngredients, save]);

return (
<FormProvider {...methods}>
<Box className="p-4" data-testid="ingredients-form">
<VerifiedBilingualTable
path={"ingredients"}
path={sectionName}
unitOptions={UNITS.ingredients}
valueColumn
loading={loading}
Expand Down
17 changes: 8 additions & 9 deletions src/components/InstructionsForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FormComponentProps, LabelData } from "@/types/types";
import useDebouncedSave from "@/utils/client/useDebouncedSave";
import { Box } from "@mui/material";
import { useEffect } from "react";
import { FormProvider, useForm, useWatch } from "react-hook-form";
Expand All @@ -12,12 +13,15 @@ const InstructionsForm: React.FC<FormComponentProps> = ({
const methods = useForm<LabelData>({
defaultValues: labelData,
});
const sectionName = "instructions";

const watchedInstructions = useWatch({
control: methods.control,
name: "instructions",
name: sectionName,
});

const save = useDebouncedSave(setLabelData);

useEffect(() => {
const currentValues = methods.getValues();
if (JSON.stringify(currentValues) !== JSON.stringify(labelData)) {
Expand All @@ -26,18 +30,13 @@ const InstructionsForm: React.FC<FormComponentProps> = ({
}, [labelData, methods]);

useEffect(() => {
if (watchedInstructions) {
setLabelData((prevLabelData) => ({
...prevLabelData,
instructions: watchedInstructions,
}));
}
}, [watchedInstructions, setLabelData]);
save(sectionName, watchedInstructions);
}, [watchedInstructions, save]);

return (
<FormProvider {...methods}>
<Box className="p-4" data-testid="instructions-form">
<VerifiedBilingualTable path={"instructions"} loading={loading} />
<VerifiedBilingualTable path={sectionName} loading={loading} />
</Box>
</FormProvider>
);
Expand Down
3 changes: 1 addition & 2 deletions src/components/LabelDataValidator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ function LabelDataValidator({
setLabelData,
}: LabelDataValidatorProps) {
const { t } = useTranslation("labelDataValidator");
const imageFiles = files;
const { isDownXs, isBetweenXsSm, isBetweenSmMd, isBetweenMdLg } =
useBreakpoints();
const isLgOrBelow =
Expand Down Expand Up @@ -199,7 +198,7 @@ function LabelDataValidator({
className="flex h-[500px] md:h-[720px] lg:size-full justify-center min-w-0 "
data-testid="image-viewer-container"
>
<ImageViewer imageFiles={imageFiles} />
<ImageViewer imageFiles={files} />
</Box>

{isLgOrBelow && (
Expand Down
Loading

0 comments on commit b7012e8

Please sign in to comment.