From 2adc0e9c289fab5b31e53be80ec8f2c45d06abcb Mon Sep 17 00:00:00 2001 From: WittF Date: Sat, 23 Aug 2025 15:38:53 +0800 Subject: [PATCH] fix(storage-policy): fix blob unique validation tooltip display --- .../FormSections/StorageAndUploadSection.tsx | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/component/Admin/StoragePolicy/EditStoragePolicy/FormSections/StorageAndUploadSection.tsx b/src/component/Admin/StoragePolicy/EditStoragePolicy/FormSections/StorageAndUploadSection.tsx index 03d8328..fef0fe2 100644 --- a/src/component/Admin/StoragePolicy/EditStoragePolicy/FormSections/StorageAndUploadSection.tsx +++ b/src/component/Admin/StoragePolicy/EditStoragePolicy/FormSections/StorageAndUploadSection.tsx @@ -1,5 +1,5 @@ import { FormControl, FormControlLabel, InputAdornment, Link, MenuItem, Switch, Typography } from "@mui/material"; -import { useCallback, useContext, useMemo, useState } from "react"; +import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; import { Trans, useTranslation } from "react-i18next"; import { StoragePolicy } from "../../../../../api/dashboard"; import { PolicyType } from "../../../../../api/explorer"; @@ -15,10 +15,12 @@ import { fileMagicVars, pathMagicVars } from "./magicVars"; const StorageAndUploadSection = () => { const { t } = useTranslation("dashboard"); - const { values, setPolicy } = useContext(StoragePolicySettingContext); + const { values, setPolicy, formRef } = useContext(StoragePolicySettingContext); const [magicVarDialogOpen, setMagicVarDialogOpen] = useState(false); const [dialogType, setDialogType] = useState<"path" | "file">("path"); + const fileNameInputRef = useRef(null); + const policyProps = useMemo(() => { return PolicyPropsMap[values.type]; }, [values.type]); @@ -41,10 +43,31 @@ const StorageAndUploadSection = () => { [setPolicy], ); - // Combined value for validation - ensures at least one random placeholder exists - const combinedRulesValue = useMemo(() => { - return `${values.dir_name_rule || ""}|${values.file_name_rule || ""}`; - }, [values.dir_name_rule, values.file_name_rule]); + // Ensures at least one random placeholder exists + useEffect(() => { + if (!formRef?.current || !fileNameInputRef.current) return; + + const form = formRef.current; + const originalCheckValidity = form.checkValidity.bind(form); + + const hasUniqueVar = (value: string) => /(\{randomkey8\}|\{randomkey16\}|\{uuid\})/.test(value); + + form.checkValidity = () => { + const dirHasUnique = hasUniqueVar(values.dir_name_rule || ""); + const fileHasUnique = hasUniqueVar(values.file_name_rule || ""); + + fileNameInputRef.current!.setCustomValidity(""); + if (!dirHasUnique && !fileHasUnique && (values.dir_name_rule || values.file_name_rule)) { + fileNameInputRef.current!.setCustomValidity(t("policy.uniqueVarRequired")); + } + + return originalCheckValidity(); + }; + + return () => { + form.checkValidity = originalCheckValidity; + }; + }, [formRef, values.dir_name_rule, values.file_name_rule, t]); const handlePathMagicVarClick = useCallback((e: React.MouseEvent) => { e.preventDefault(); @@ -186,7 +209,12 @@ const StorageAndUploadSection = () => { - + { {t("policy.nameRuleImmutable")} - {/* Hidden input for combined validation */} -
- -