forked from github/plane
9075f9441c
* style: added cta at the bottom of sidebar, added missing icons as well, showing dynamic workspace member count on workspace dropdown * refractor: running parallel request, made create/edit label function to async function * fix: sidebar dropdown content going below kanban items outside click detection in need help dropdown * refractor: making parallel api calls fix: create state input comes at bottom, create state input gets on focus automatically, form is getting submitted on enter click * refactoring file structure and signin page * style: changed text and added spinner for signing in loading * refractor: removed unused type * fix: my issue cta in profile page sending to 404 page * fix: added new s3 bucket url in next.config.js file increased image modal height * packaging UI components * eslint config * eslint fixes * refactoring changes * build fixes * minor fixes * adding todo comments for reference * refactor: cleared unused imports and re ordered imports * refactor: removed unused imports * fix: added workspace argument to useissues hook * refactor: removed api-routes file, unnecessary constants * refactor: created helpers folder, removed unnecessary constants * refactor: new context for issue view * refactoring issues page * build fixes * refactoring * refactor: create issue modal * refactor: module ui * fix: sub-issues mutation * fix: create more option in create issue modal * description form debounce issue * refactor: global component for assignees list * fix: link module interface * fix: priority icons and sub-issues count added * fix: cycle mutation in issue details page * fix: remove issue from cycle mutation * fix: create issue modal in home page * fix: removed unnecessary props * fix: updated create issue form status * fix: settings auth breaking * refactor: issue details page Co-authored-by: Dakshesh Jain <dakshesh.jain14@gmail.com> Co-authored-by: Dakshesh Jain <65905942+dakshesh14@users.noreply.github.com> Co-authored-by: venkatesh-soulpage <venkatesh.marreboyina@soulpageit.com> Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com> Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia1001@gmail.com>
77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
// react
|
|
import React from "react";
|
|
|
|
const isEmailValid = (email: string) =>
|
|
String(email)
|
|
.toLowerCase()
|
|
.match(
|
|
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
);
|
|
|
|
const MultiInput = ({ label, name, placeholder, setValue, watch }: any) => {
|
|
const handleKeyDown = (e: any) => {
|
|
if (e.key !== "Enter") return;
|
|
const value = e.target.value;
|
|
if (!value.trim()) return;
|
|
if (isEmailValid(value) && !watch(name)?.find((item: any) => item.email === value)) {
|
|
setValue(name, [...(watch(name) || []), { email: value }]);
|
|
e.target.value = "";
|
|
}
|
|
};
|
|
|
|
const handleBlur = (e: React.FocusEvent<HTMLInputElement, Element>) => {
|
|
const value = e.target.value;
|
|
if (!value.trim()) return;
|
|
if (isEmailValid(value) && !watch(name)?.find((item: any) => item.email === value)) {
|
|
setValue(name, [...(watch(name) || []), { email: value }]);
|
|
e.target.value = "";
|
|
} else {
|
|
e.target.value = "";
|
|
}
|
|
};
|
|
|
|
const handleChange = (e: any) => {
|
|
const value = e.target.value.trim();
|
|
if (!value) return;
|
|
if (value.includes(",")) {
|
|
const tags = value.split(",");
|
|
tags.forEach((tag: string) => {
|
|
if (isEmailValid(tag) && !watch(name)?.find((item: any) => item.email === tag)) {
|
|
setValue(name, [...(watch(name) || []), { email: tag }]);
|
|
}
|
|
});
|
|
e.target.value = "";
|
|
}
|
|
};
|
|
|
|
const removeTag = (index: Number) => {
|
|
setValue(
|
|
name,
|
|
watch(name).filter((_: string, i: any) => i !== index)
|
|
);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{label && <label className="mb-2 text-gray-500">{label}</label>}
|
|
<div className="rounded-md border p-2">
|
|
{watch(name)?.map((tag: any, index: number) => (
|
|
<button type="button" className="m-1.5 rounded-full bg-slate-300 p-1.5" key={index}>
|
|
{tag.email} <span onClick={() => removeTag(index)}>×</span>
|
|
</button>
|
|
))}
|
|
<input
|
|
onKeyDown={handleKeyDown}
|
|
onBlur={handleBlur}
|
|
onChange={handleChange}
|
|
type="text"
|
|
placeholder={placeholder}
|
|
className="block w-full rounded-md bg-transparent p-1.5 text-sm focus:outline-none"
|
|
/>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default MultiInput;
|