forked from github/plane
fix: project identifier validation (#1643)
* fix: project identifier validation * feat: alphanumric identifier validation * chore: code refactor * refactor: project identifier change function --------- Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
This commit is contained in:
parent
9b531aca47
commit
ad410d134f
@ -75,7 +75,7 @@ const IsGuestCondition: React.FC<{
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user }) => {
|
export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user }) => {
|
||||||
const [isChangeIdentifierRequired, setIsChangeIdentifierRequired] = useState(true);
|
const [isChangeInIdentifierRequired, setIsChangeInIdentifierRequired] = useState(true);
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
@ -98,18 +98,9 @@ export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user })
|
|||||||
reValidateMode: "onChange",
|
reValidateMode: "onChange",
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectName = watch("name");
|
|
||||||
const projectIdentifier = watch("identifier");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (projectName && isChangeIdentifierRequired)
|
|
||||||
setValue("identifier", projectName.replace(/ /g, "").toUpperCase().substring(0, 3));
|
|
||||||
}, [projectName, projectIdentifier, setValue, isChangeIdentifierRequired]);
|
|
||||||
|
|
||||||
useEffect(() => () => setIsChangeIdentifierRequired(true), [isOpen]);
|
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
|
setIsChangeInIdentifierRequired(true);
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,6 +138,29 @@ export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user })
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const changeIdentifierOnNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (!isChangeInIdentifierRequired) return;
|
||||||
|
|
||||||
|
if (e.target.value === "") setValue("identifier", "");
|
||||||
|
else
|
||||||
|
setValue(
|
||||||
|
"identifier",
|
||||||
|
e.target.value
|
||||||
|
.replace(/[^a-zA-Z0-9]/g, "")
|
||||||
|
.toUpperCase()
|
||||||
|
.substring(0, 5)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleIdentifierChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const { value } = e.target;
|
||||||
|
|
||||||
|
const alphanumericValue = value.replace(/[^a-zA-Z0-9]/g, "");
|
||||||
|
|
||||||
|
setValue("identifier", alphanumericValue.toUpperCase());
|
||||||
|
setIsChangeInIdentifierRequired(false);
|
||||||
|
};
|
||||||
|
|
||||||
const options = workspaceMembers?.map((member) => ({
|
const options = workspaceMembers?.map((member) => ({
|
||||||
value: member.member.id,
|
value: member.member.id,
|
||||||
query:
|
query:
|
||||||
@ -265,6 +279,7 @@ export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user })
|
|||||||
name="name"
|
name="name"
|
||||||
type="name"
|
type="name"
|
||||||
placeholder="Project Title"
|
placeholder="Project Title"
|
||||||
|
onChange={changeIdentifierOnNameChange}
|
||||||
error={errors.name}
|
error={errors.name}
|
||||||
register={register}
|
register={register}
|
||||||
validations={{
|
validations={{
|
||||||
@ -287,11 +302,12 @@ export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user })
|
|||||||
placeholder="Identifier"
|
placeholder="Identifier"
|
||||||
error={errors.identifier}
|
error={errors.identifier}
|
||||||
register={register}
|
register={register}
|
||||||
onChange={() => setIsChangeIdentifierRequired(false)}
|
onChange={handleIdentifierChange}
|
||||||
validations={{
|
validations={{
|
||||||
required: "Identifier is required",
|
required: "Identifier is required",
|
||||||
validate: (value) =>
|
validate: (value) =>
|
||||||
/^[A-Z]+$/.test(value) || "Identifier must be in uppercase.",
|
/^[A-Z0-9]+$/.test(value.toUpperCase()) ||
|
||||||
|
"Identifier must be in uppercase.",
|
||||||
minLength: {
|
minLength: {
|
||||||
value: 1,
|
value: 1,
|
||||||
message: "Identifier must at least be of 1 character",
|
message: "Identifier must at least be of 1 character",
|
||||||
|
@ -145,6 +145,15 @@ const GeneralSettings: NextPage = () => {
|
|||||||
else await updateProject(payload);
|
else await updateProject(payload);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleIdentifierChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const { value } = event.target;
|
||||||
|
|
||||||
|
const alphanumericValue = value.replace(/[^a-zA-Z0-9]/g, "");
|
||||||
|
const formattedValue = alphanumericValue.toUpperCase();
|
||||||
|
|
||||||
|
setValue("identifier", formattedValue);
|
||||||
|
};
|
||||||
|
|
||||||
const currentNetwork = NETWORK_CHOICES.find((n) => n.key === projectDetails?.network);
|
const currentNetwork = NETWORK_CHOICES.find((n) => n.key === projectDetails?.network);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -303,10 +312,11 @@ const GeneralSettings: NextPage = () => {
|
|||||||
error={errors.identifier}
|
error={errors.identifier}
|
||||||
register={register}
|
register={register}
|
||||||
placeholder="Enter identifier"
|
placeholder="Enter identifier"
|
||||||
|
onChange={handleIdentifierChange}
|
||||||
validations={{
|
validations={{
|
||||||
required: "Identifier is required",
|
required: "Identifier is required",
|
||||||
validate: (value) =>
|
validate: (value) =>
|
||||||
/^[A-Z]+$/.test(value) || "Identifier must be uppercase text.",
|
/^[A-Z0-9]+$/.test(value.toUpperCase()) || "Identifier must be in uppercase.",
|
||||||
minLength: {
|
minLength: {
|
||||||
value: 1,
|
value: 1,
|
||||||
message: "Identifier must at least be of 1 character",
|
message: "Identifier must at least be of 1 character",
|
||||||
|
Loading…
Reference in New Issue
Block a user