diff --git a/public/img/unverifyIcon.svg b/public/img/unverifyIcon.svg new file mode 100644 index 00000000..e9abedc8 --- /dev/null +++ b/public/img/unverifyIcon.svg @@ -0,0 +1,8 @@ + + + + Layer 1 + + + + diff --git a/src/app/__tests__/HomePage.test.tsx b/src/app/__tests__/HomePage.test.tsx index 5fbe9709..916505ed 100644 --- a/src/app/__tests__/HomePage.test.tsx +++ b/src/app/__tests__/HomePage.test.tsx @@ -1,7 +1,7 @@ /* eslint-disable react/display-name */ /* eslint-disable react-hooks/rules-of-hooks */ import useUploadedFilesStore from "@/stores/fileStore"; -import { fireEvent, render, screen } from "@testing-library/react"; +import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { useTranslation } from "react-i18next"; import { Response } from "whatwg-fetch"; @@ -27,28 +27,6 @@ jest.mock("react-i18next", () => ({ })); const { t } = useTranslation("homePage"); -// Mock the FileElement component -jest.mock( - "../../components/FileElement", - () => - ({ - fileName, - fileUrl, - handleDelete, - }: { - fileName: string; - fileUrl: string; - handleDelete: (url: string) => void; - }) => ( -
- {fileName} - -
- ), -); - global.URL.createObjectURL = jest .fn() .mockImplementation(() => "blob:example/image.png"); @@ -98,18 +76,24 @@ describe("HomePage Component", () => { userEvent.upload(input, file); // Check that the file was uploaded and appears in the list. - const fileElement = await screen.findByTestId("file-element"); + const fileElement = await screen.findByTestId("file-element-hello.png"); expect(fileElement).toBeInTheDocument(); const fileName = await screen.findByTestId("file-name"); expect(fileName).toHaveTextContent("hello.png"); + fireEvent.mouseEnter(fileElement); + + await waitFor(() => { + // Find and click the delete button - const deleteButton = screen.getByTestId("delete"); + const deleteButton = screen.getByTestId("delete-hello.png"); fireEvent.click(deleteButton); + }); + // Check that the file was removed - expect(screen.queryByTestId("file-element")).not.toBeInTheDocument(); + expect(screen.queryByTestId("file-element-hello.png")).not.toBeInTheDocument(); }); it("should allow file uploads via drag and drop", async () => { @@ -159,21 +143,26 @@ describe("HomePage Component", () => { }); // Check that the file was uploaded and appears in the list. - const fileElement = await screen.findByTestId("file-element"); + const fileElement = await screen.findByTestId("file-element-hello.png"); expect(fileElement).toBeInTheDocument(); const fileName = await screen.findByTestId("file-name"); expect(fileName).toHaveTextContent("hello.png"); + fireEvent.mouseEnter(fileElement); + + await waitFor(() => { + // Find and click the delete button - const deleteButton = screen.getByTestId("delete"); + const deleteButton = screen.getByTestId("delete-hello.png"); fireEvent.click(deleteButton); + }); // Check that the file was removed - expect(screen.queryByTestId("file-element")).not.toBeInTheDocument(); + expect(screen.queryByTestId("file-element-hello.png")).not.toBeInTheDocument(); }); - it("should allow file upload via input", async () => { + it("should allow file upload via input and keep hover effect until delete button is clicked", async () => { render(); // Mock file @@ -184,18 +173,23 @@ describe("HomePage Component", () => { userEvent.upload(input, file); // Check that the file was uploaded and appears in the list. - const fileElement = await screen.findByTestId("file-element"); + const fileElement = await screen.findByTestId("file-element-hello.png"); expect(fileElement).toBeInTheDocument(); const fileName = await screen.findByTestId("file-name"); expect(fileName).toHaveTextContent("hello.png"); + fireEvent.mouseEnter(fileElement); + + await waitFor(() => { + // Find and click the delete button - const deleteButton = screen.getByTestId("delete"); + const deleteButton = screen.getByTestId("delete-hello.png"); fireEvent.click(deleteButton); + }); // Check that the file was removed - expect(screen.queryByTestId("file-element")).not.toBeInTheDocument(); + expect(screen.queryByTestId("file-element-hello.png")).not.toBeInTheDocument(); }); it("The button submit should be visible when a file is uploaded", async () => { @@ -209,7 +203,7 @@ describe("HomePage Component", () => { userEvent.upload(input, file); // Check that the file was uploaded and appears in the list. - const fileElement = await screen.findByTestId("file-element"); + const fileElement = await screen.findByTestId("file-element-hello.png"); expect(fileElement).toBeInTheDocument(); const fileName = await screen.findByTestId("file-name"); @@ -230,7 +224,7 @@ describe("HomePage Component", () => { userEvent.upload(input, file); // Check that the file was uploaded and appears in the list. - const fileElement = await screen.findByTestId("file-element"); + const fileElement = await screen.findByTestId("file-element-hello.png"); expect(fileElement).toBeInTheDocument(); const fileName = await screen.findByTestId("file-name"); @@ -254,11 +248,11 @@ describe("HomePage Component", () => { userEvent.upload(input, [file, file2]); // Check that the file was uploaded and appears in the list. - const fileElement = await screen.findByText("hello.png"); + const fileElement = await screen.findByTestId("file-element-hello.png"); expect(fileElement).toBeInTheDocument(); // Check that the file was uploaded and appears in the list. - const fileElement2 = await screen.findByText("hello2.png"); + const fileElement2 = await screen.findByTestId("file-element-hello2.png"); expect(fileElement2).toBeInTheDocument(); // Check that the file count is displayed @@ -301,7 +295,7 @@ describe("HomePage Component", () => { const input = screen.getByLabelText(t("dropzone.browseFile")); userEvent.upload(input, file); - const fileElement = await screen.findByTestId("file-element"); + const fileElement = await screen.findByTestId("file-element-hello.png"); expect(fileElement).toBeInTheDocument(); const submitButton = screen.getByTestId("submit-button"); diff --git a/src/app/page.tsx b/src/app/page.tsx index a1375d51..10f53823 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -58,11 +58,11 @@ function HomePage() { title={t("submitButtonDisabledHint")} disableHoverListener={uploadedFiles.length !== 0} placement="top" - className="w-[90%] max-w-full" + className="w-[90%] max-w-full min-w-[133.44px]" > + )} {uploadedFiles.map((file, index) => ( - handleDelete(file.getInfo().path)} - /> - ))} + + ))} diff --git a/src/components/QuantityInput.tsx b/src/components/QuantityInput.tsx index f6f5caac..f9568318 100644 --- a/src/components/QuantityInput.tsx +++ b/src/components/QuantityInput.tsx @@ -12,6 +12,7 @@ interface QuantityInputProps { unitRules?: RegisterOptions; onFocus?: () => void; onblur?: () => void; + verified?: boolean; } const QuantityInput = ({ @@ -22,6 +23,7 @@ const QuantityInput = ({ unitRules, onFocus, onblur, + verified, }: QuantityInputProps) => { const { t } = useTranslation("labelDataValidator"); @@ -79,7 +81,7 @@ const QuantityInput = ({ renderInput={(params) => ( { anchor="left" open={open} onClose={onClose} + transitionDuration={0} ModalProps={{ keepMounted: true, }} @@ -56,7 +57,7 @@ const SideNav = ({ open, onClose }: DrawerMenuProps) => { height="40" /> - + {t("sideNav.FertiScan")} diff --git a/src/components/StyledTextField.tsx b/src/components/StyledTextField.tsx index 74b86a3e..3fa6b4a5 100644 --- a/src/components/StyledTextField.tsx +++ b/src/components/StyledTextField.tsx @@ -9,6 +9,7 @@ const StyledTextField = React.forwardRef( ref={ref} variant="standard" fullWidth + autoComplete="off" slotProps={{ ...props.slotProps, input: { diff --git a/src/components/UserMenu.tsx b/src/components/UserMenu.tsx index c1543357..86683d93 100644 --- a/src/components/UserMenu.tsx +++ b/src/components/UserMenu.tsx @@ -3,7 +3,6 @@ import { usePlaceholder } from "@/classe/User"; import { AccountCircle, Logout } from "@mui/icons-material"; import DashboardIcon from "@mui/icons-material/Dashboard"; import { - Divider, ListItemIcon, Menu, MenuItem, @@ -94,6 +93,7 @@ const UserMenu = ({ className="min-w-[36px]" onClick={(event) => event.preventDefault()} data-testid="profile-menu-item" + style={{ pointerEvents: "none", backgroundColor: "inherit" }} > @@ -106,14 +106,12 @@ const UserMenu = ({ {t("userMenu.dashboard")} - {t("userMenu.logout")} - (null); const { t } = useTranslation("labelDataValidator"); const data = useWatch({ control, name: path }); @@ -60,7 +63,7 @@ const VerifiedBilingualTable = ({ }; const toggleVerify = async (index: number) => { - await handleVerify(index, Boolean(!data?.[index]?.verified)); + await handleVerify(index, !data?.[index]?.verified); }; const setAllVerified = async (value: boolean) => { @@ -71,11 +74,10 @@ const VerifiedBilingualTable = ({ - {/* Table Head */} @@ -83,7 +85,7 @@ const VerifiedBilingualTable = ({ @@ -92,7 +94,7 @@ const VerifiedBilingualTable = ({ {valueColumn && ( @@ -100,7 +102,10 @@ const VerifiedBilingualTable = ({ )} - + - + {valueColumn && ( - + )} - + ) : ( @@ -165,7 +181,9 @@ const VerifiedBilingualTable = ({ )} /> - + {valueColumn && ( - + )} - + remove(index)} - disabled={isVerified(index)} + disabled={isVerified(index) || fields.length <= 1} aria-label={t( "verifiedBilingualTable.accessibility.deleteButton", )} @@ -217,7 +242,13 @@ const VerifiedBilingualTable = ({ - + setHoverIndex(index)} + onMouseLeave={() => setHoverIndex(null)} > -