From 6707b93a0867b6ce17edcc1f6de53bca445102b3 Mon Sep 17 00:00:00 2001 From: Harman-singh-waraich Date: Wed, 23 Oct 2024 15:08:33 +0530 Subject: [PATCH 1/2] refactor(web): add-utility-to-check-empty-strings-with-whitespaces --- web/src/components/CasesDisplay/Search.tsx | 4 ++-- web/src/context/NewDisputeContext.tsx | 4 ++-- .../Notifications/FormContactDetails/FormContact.tsx | 3 ++- .../pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx | 4 ++-- web/src/pages/Resolver/NavigationButtons/NextButton.tsx | 3 ++- web/src/pages/Resolver/NavigationButtons/PreviousButton.tsx | 3 ++- web/src/utils/index.ts | 5 +++++ 7 files changed, 17 insertions(+), 9 deletions(-) diff --git a/web/src/components/CasesDisplay/Search.tsx b/web/src/components/CasesDisplay/Search.tsx index a33dce126..6d1d265e3 100644 --- a/web/src/components/CasesDisplay/Search.tsx +++ b/web/src/components/CasesDisplay/Search.tsx @@ -7,7 +7,7 @@ import { useDebounce } from "react-use"; import { Searchbar, DropdownCascader } from "@kleros/ui-components-library"; -import { isUndefined } from "utils/index"; +import { isEmpty, isUndefined } from "utils/index"; import { decodeURIFilter, encodeURIFilter, useRootPath } from "utils/uri"; import { rootCourtToItems, useCourtTree } from "queries/useCourtTree"; @@ -58,7 +58,7 @@ const Search: React.FC = () => { const navigate = useNavigate(); useDebounce( () => { - const newFilters = search === "" ? { ...filterObject } : { ...filterObject, id: search }; + const newFilters = isEmpty(search) ? { ...filterObject } : { ...filterObject, id: search }; const encodedFilter = encodeURIFilter(newFilters); navigate(`${location}/${page}/${order}/${encodedFilter}`); }, diff --git a/web/src/context/NewDisputeContext.tsx b/web/src/context/NewDisputeContext.tsx index e01b09c98..e4988ba5f 100644 --- a/web/src/context/NewDisputeContext.tsx +++ b/web/src/context/NewDisputeContext.tsx @@ -5,7 +5,7 @@ import { Address } from "viem"; import { DEFAULT_CHAIN } from "consts/chains"; import { klerosCoreAddress } from "hooks/contracts/generated"; import { useLocalStorage } from "hooks/useLocalStorage"; -import { isUndefined } from "utils/index"; +import { isEmpty, isUndefined } from "utils/index"; export type Answer = { id: string; @@ -133,7 +133,7 @@ const constructDisputeTemplate = (disputeData: IDisputeData) => { for (const answer of baseTemplate.answers) { answer.id = "0x" + BigInt(answer.id).toString(16); } - if (!isUndefined(baseTemplate.policyURI) && baseTemplate.policyURI === "") delete baseTemplate.policyURI; + if (!isUndefined(baseTemplate.policyURI) && isEmpty(baseTemplate.policyURI)) delete baseTemplate.policyURI; baseTemplate.arbitratorAddress = klerosCoreAddress[DEFAULT_CHAIN]; baseTemplate.arbitratorChainID = DEFAULT_CHAIN.toString(); diff --git a/web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx b/web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx index b28d3c4ce..e16a7ad72 100644 --- a/web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx +++ b/web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx @@ -2,6 +2,7 @@ import React, { Dispatch, SetStateAction, useMemo, useEffect } from "react"; import styled from "styled-components"; import { Field } from "@kleros/ui-components-library"; +import { isEmpty } from "src/utils"; const StyledLabel = styled.label` display: flex; @@ -47,7 +48,7 @@ const FormContact: React.FC = ({ }; const fieldVariant = useMemo(() => { - if (contactInput === "" || !isEditing) { + if (isEmpty(contactInput) || !isEditing) { return undefined; } return contactIsValid ? "success" : "error"; diff --git a/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx b/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx index 2ee9c0451..d9578377a 100644 --- a/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx +++ b/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx @@ -14,7 +14,7 @@ import { wrapWithToast, OPTIONS as toastOptions } from "utils/wrapWithToast"; import EnsureAuth from "components/EnsureAuth"; import { EnsureChain } from "components/EnsureChain"; -import { isUndefined } from "src/utils"; +import { isEmpty, isUndefined } from "src/utils"; const StyledModal = styled(Modal)` position: absolute; @@ -65,7 +65,7 @@ const SubmitEvidenceModal: React.FC<{ const [file, setFile] = useState(); const { uploadFile } = useAtlasProvider(); - const isDisabled = useMemo(() => isSending || message.trim() === "" || isUndefined(message), [isSending, message]); + const isDisabled = useMemo(() => isSending || isEmpty(message) || isUndefined(message), [isSending, message]); const submitEvidence = useCallback(async () => { try { diff --git a/web/src/pages/Resolver/NavigationButtons/NextButton.tsx b/web/src/pages/Resolver/NavigationButtons/NextButton.tsx index 499f26f0f..8e8d62a2f 100644 --- a/web/src/pages/Resolver/NavigationButtons/NextButton.tsx +++ b/web/src/pages/Resolver/NavigationButtons/NextButton.tsx @@ -5,6 +5,7 @@ import { useLocation, useNavigate } from "react-router-dom"; import { Button } from "@kleros/ui-components-library"; import { useNewDisputeContext } from "context/NewDisputeContext"; +import { isEmpty } from "src/utils"; interface INextButton { nextRoute: string; @@ -22,7 +23,7 @@ const NextButton: React.FC = ({ nextRoute }) => { //check if any filled address or ens is invalid const areFilledAddressesValid = disputeData?.aliasesArray?.every((alias) => - alias.address === "" && alias.name === "" ? true : alias.isValid + isEmpty(alias.address) && isEmpty(alias.name) ? true : alias.isValid ); const isButtonDisabled = diff --git a/web/src/pages/Resolver/NavigationButtons/PreviousButton.tsx b/web/src/pages/Resolver/NavigationButtons/PreviousButton.tsx index b51aa6d36..06b49a839 100644 --- a/web/src/pages/Resolver/NavigationButtons/PreviousButton.tsx +++ b/web/src/pages/Resolver/NavigationButtons/PreviousButton.tsx @@ -4,9 +4,10 @@ import styled from "styled-components"; import { useNavigate } from "react-router-dom"; import { Button } from "@kleros/ui-components-library"; +import { isEmpty } from "src/utils"; const StyledButton = styled(Button)<{ prevRoute: string }>` - display: ${({ prevRoute }) => (prevRoute === "" ? "none" : "flex")}; + display: ${({ prevRoute }) => (isEmpty(prevRoute) ? "none" : "flex")}; `; interface IReturnButton { diff --git a/web/src/utils/index.ts b/web/src/utils/index.ts index b0d6c5b33..460283d00 100644 --- a/web/src/utils/index.ts +++ b/web/src/utils/index.ts @@ -1,2 +1,7 @@ export const isUndefined = (maybeObject: any): maybeObject is undefined | null => typeof maybeObject === "undefined" || maybeObject === null; + +/** + * Checks if a string is empty or contains only whitespace. + */ +export const isEmpty = (str: string): boolean => str.trim() === ""; From a5f344c9c59946791248cd37d5db31a80317e30f Mon Sep 17 00:00:00 2001 From: Harman-singh-waraich Date: Wed, 23 Oct 2024 15:41:17 +0530 Subject: [PATCH 2/2] fix(web): address-coderabbit-feedback --- .../Notifications/FormContactDetails/FormContact.tsx | 2 +- .../Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx | 4 ++-- .../pages/Resolver/NavigationButtons/NextButton.tsx | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx b/web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx index e16a7ad72..073f53300 100644 --- a/web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx +++ b/web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx @@ -48,7 +48,7 @@ const FormContact: React.FC = ({ }; const fieldVariant = useMemo(() => { - if (isEmpty(contactInput) || !isEditing) { + if (!isEditing || isEmpty(contactInput)) { return undefined; } return contactIsValid ? "success" : "error"; diff --git a/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx b/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx index d9578377a..b310ed362 100644 --- a/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx +++ b/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx @@ -14,7 +14,7 @@ import { wrapWithToast, OPTIONS as toastOptions } from "utils/wrapWithToast"; import EnsureAuth from "components/EnsureAuth"; import { EnsureChain } from "components/EnsureChain"; -import { isEmpty, isUndefined } from "src/utils"; +import { isEmpty } from "src/utils"; const StyledModal = styled(Modal)` position: absolute; @@ -65,7 +65,7 @@ const SubmitEvidenceModal: React.FC<{ const [file, setFile] = useState(); const { uploadFile } = useAtlasProvider(); - const isDisabled = useMemo(() => isSending || isEmpty(message) || isUndefined(message), [isSending, message]); + const isDisabled = useMemo(() => isSending || isEmpty(message), [isSending, message]); const submitEvidence = useCallback(async () => { try { diff --git a/web/src/pages/Resolver/NavigationButtons/NextButton.tsx b/web/src/pages/Resolver/NavigationButtons/NextButton.tsx index 8e8d62a2f..e6d51f8bf 100644 --- a/web/src/pages/Resolver/NavigationButtons/NextButton.tsx +++ b/web/src/pages/Resolver/NavigationButtons/NextButton.tsx @@ -22,17 +22,17 @@ const NextButton: React.FC = ({ nextRoute }) => { disputeData.answers.every((answer) => answer.title !== "" && answer.description !== ""); //check if any filled address or ens is invalid - const areFilledAddressesValid = disputeData?.aliasesArray?.every((alias) => - isEmpty(alias.address) && isEmpty(alias.name) ? true : alias.isValid - ); - + const areAliasesValidOrEmpty = disputeData?.aliasesArray?.every((alias) => { + const isAliasEmpty = isEmpty(alias.address) && isEmpty(alias.name); + return isAliasEmpty || alias.isValid; + }); const isButtonDisabled = (location.pathname.includes("/resolver/title") && !disputeData.title) || (location.pathname.includes("/resolver/description") && !disputeData.description) || (location.pathname.includes("/resolver/court") && !disputeData.courtId) || (location.pathname.includes("/resolver/jurors") && !disputeData.arbitrationCost) || (location.pathname.includes("/resolver/voting-options") && !areVotingOptionsFilled) || - (location.pathname.includes("/resolver/notable-persons") && !areFilledAddressesValid) || + (location.pathname.includes("/resolver/notable-persons") && !areAliasesValidOrEmpty) || (location.pathname.includes("/resolver/policy") && (isPolicyUploading || !disputeData.policyURI)); return