From c603e846c3f57ea8929e29787b99732b4970fbb8 Mon Sep 17 00:00:00 2001 From: Ciabas Date: Mon, 12 May 2025 17:16:24 +0200 Subject: [PATCH 1/3] fix(#3560): allow empty image in register drep form --- CHANGELOG.md | 2 ++ govtool/frontend/src/consts/dRepActions/fields.ts | 2 +- govtool/frontend/src/utils/isValidFormat.ts | 8 +++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d5f11335..abf219791 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ changes. ### Fixed +- Fix an issue where the submit button remained disabled after removing an invalid value from the IMAGE input field on DRrep form [Issue 3560](https://github.com/IntersectMBO/govtool/issues/3560) + ### Changed ### Removed diff --git a/govtool/frontend/src/consts/dRepActions/fields.ts b/govtool/frontend/src/consts/dRepActions/fields.ts index 367ef4468..068430d0e 100644 --- a/govtool/frontend/src/consts/dRepActions/fields.ts +++ b/govtool/frontend/src/consts/dRepActions/fields.ts @@ -77,6 +77,6 @@ export const Rules = { value: IMAGE_REGEX, message: i18n.t("registration.fields.validations.image"), }, - validate: isValidImageUrl, + validate: (value: string) => isValidImageUrl(value, { optional: true }), }, }; diff --git a/govtool/frontend/src/utils/isValidFormat.ts b/govtool/frontend/src/utils/isValidFormat.ts index dbb5a1c84..054bfa9ec 100644 --- a/govtool/frontend/src/utils/isValidFormat.ts +++ b/govtool/frontend/src/utils/isValidFormat.ts @@ -7,6 +7,10 @@ import i18n from "@/i18n"; import { adaHandleService } from "@/services/AdaHandle"; import { getImageSha } from "./getImageSha"; +type Options = { + optional: boolean; +}; + export const URL_REGEX = /^(?:(?:https?:\/\/)?(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,})(?:\/[^\s]*)?)|(?:ipfs:\/\/(?:[a-zA-Z0-9]+(?:\/[a-zA-Z0-9._-]+)*))$|^$/; export const HASH_REGEX = /^[0-9A-Fa-f]+$/; @@ -78,8 +82,10 @@ export async function isDRepView(view?: string) { return i18n.t("forms.errors.mustBeDRepView"); } -export async function isValidImageUrl(url: string) { +export async function isValidImageUrl(url: string, options?: Options) { + if (options?.optional && !url) return true; if (!url.length) return false; + try { if (URL_REGEX.test(url)) { await getImageSha(url); From 70e17dea32dc6c6924579054dc5303b9f49b1501 Mon Sep 17 00:00:00 2001 From: Ciabas Date: Tue, 13 May 2025 09:59:49 +0200 Subject: [PATCH 2/3] fix(#3560): add precise types to UncontrolledImageInput component for improved type safety --- .../organisms/UncontrolledImageInput.tsx | 24 ++++++++++++------- .../frontend/src/consts/dRepActions/fields.ts | 2 +- govtool/frontend/src/i18n/locales/en.json | 3 ++- govtool/frontend/src/utils/isValidFormat.ts | 5 +++- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/govtool/frontend/src/components/organisms/UncontrolledImageInput.tsx b/govtool/frontend/src/components/organisms/UncontrolledImageInput.tsx index 2d7867984..6ff4a2b88 100644 --- a/govtool/frontend/src/components/organisms/UncontrolledImageInput.tsx +++ b/govtool/frontend/src/components/organisms/UncontrolledImageInput.tsx @@ -1,23 +1,31 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ import { useRef } from "react"; -import { useController } from "react-hook-form"; +import { + Control, + FieldPath, + FieldValues, + RegisterOptions, + useController, +} from "react-hook-form"; import { FormErrorMessage } from "../atoms"; -type UncontrolledImageInputProps = { - name: string; - control: any; - rules?: any; +type UncontrolledImageInputProps< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath, +> = { + name: TName; + control: Control; + rules?: RegisterOptions; placeholder?: string; dataTestId?: string; }; -export const UncontrolledImageInput = ({ +export const UncontrolledImageInput = ({ name, control, rules, placeholder, dataTestId, -}: UncontrolledImageInputProps) => { +}: UncontrolledImageInputProps) => { const { field: { onChange }, fieldState, diff --git a/govtool/frontend/src/consts/dRepActions/fields.ts b/govtool/frontend/src/consts/dRepActions/fields.ts index 068430d0e..560988147 100644 --- a/govtool/frontend/src/consts/dRepActions/fields.ts +++ b/govtool/frontend/src/consts/dRepActions/fields.ts @@ -77,6 +77,6 @@ export const Rules = { value: IMAGE_REGEX, message: i18n.t("registration.fields.validations.image"), }, - validate: (value: string) => isValidImageUrl(value, { optional: true }), + validate: (value: unknown) => isValidImageUrl(value, { optional: true }), }, }; diff --git a/govtool/frontend/src/i18n/locales/en.json b/govtool/frontend/src/i18n/locales/en.json index 8e13dff3a..d1d56337d 100644 --- a/govtool/frontend/src/i18n/locales/en.json +++ b/govtool/frontend/src/i18n/locales/en.json @@ -389,7 +389,8 @@ "tooLongUrl": "Url must be less than 128 bytes", "mustBeStakeAddress": "It must be reward address in bech32 format", "mustBeReceivingAddress": "Invalid payment address", - "couldNotGenerateImageSha": "Could not generate image sha" + "couldNotGenerateImageSha": "Could not generate image sha", + "invalidValueType": "Invalid value type" } }, "proposalDiscussion": { diff --git a/govtool/frontend/src/utils/isValidFormat.ts b/govtool/frontend/src/utils/isValidFormat.ts index 054bfa9ec..770f9eee3 100644 --- a/govtool/frontend/src/utils/isValidFormat.ts +++ b/govtool/frontend/src/utils/isValidFormat.ts @@ -82,7 +82,10 @@ export async function isDRepView(view?: string) { return i18n.t("forms.errors.mustBeDRepView"); } -export async function isValidImageUrl(url: string, options?: Options) { +export async function isValidImageUrl(url: unknown, options?: Options) { + if (typeof url !== "string") { + return i18n.t("forms.errors.invalidValueType"); + } if (options?.optional && !url) return true; if (!url.length) return false; From 1d1d231c3507b7d51def1864170c71f0af44d4e2 Mon Sep 17 00:00:00 2001 From: Ciabas Date: Tue, 13 May 2025 10:05:50 +0200 Subject: [PATCH 3/3] fix(#3560): improve validation in UncontrolledImageInput by checking fieldState.error, ensuring users see input errors even with empty messages --- .../src/components/organisms/UncontrolledImageInput.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/govtool/frontend/src/components/organisms/UncontrolledImageInput.tsx b/govtool/frontend/src/components/organisms/UncontrolledImageInput.tsx index 6ff4a2b88..5532914a2 100644 --- a/govtool/frontend/src/components/organisms/UncontrolledImageInput.tsx +++ b/govtool/frontend/src/components/organisms/UncontrolledImageInput.tsx @@ -57,8 +57,8 @@ export const UncontrolledImageInput = ({ borderRadius: "50px", height: "50px", border: "1px solid", - borderColor: fieldState.error?.message ? "red" : "#6F99FF", - backgroundColor: fieldState.error?.message ? "#FAEAEB" : "white", + borderColor: fieldState.error ? "red" : "#6F99FF", + backgroundColor: fieldState.error ? "#FAEAEB" : "white", boxSizing: "border-box", margin: 0, display: "block",