mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: input character limit error message improvement (#4271)
This commit is contained in:
parent
fc1cffd524
commit
87737dbfbe
@ -27,9 +27,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
|
|||||||
: mode === "true-transparent"
|
: mode === "true-transparent"
|
||||||
? "rounded border-none bg-transparent ring-0"
|
? "rounded border-none bg-transparent ring-0"
|
||||||
: ""
|
: ""
|
||||||
} ${hasError ? "border-red-500" : ""} ${hasError && mode === "primary" ? "bg-red-500/20" : ""} ${
|
} ${hasError ? "border-red-500" : ""} ${inputSize === "sm" ? "px-3 py-2" : inputSize === "md" ? "p-3" : ""}`,
|
||||||
inputSize === "sm" ? "px-3 py-2" : inputSize === "md" ? "p-3" : ""
|
|
||||||
}`,
|
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...rest}
|
{...rest}
|
||||||
|
@ -77,7 +77,7 @@ export const CycleForm: React.FC<Props> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="mt-2 space-y-3">
|
<div className="mt-2 space-y-3">
|
||||||
<div>
|
<div className="flex flex-col gap-1">
|
||||||
<Controller
|
<Controller
|
||||||
name="name"
|
name="name"
|
||||||
control={control}
|
control={control}
|
||||||
@ -85,7 +85,7 @@ export const CycleForm: React.FC<Props> = (props) => {
|
|||||||
required: "Name is required",
|
required: "Name is required",
|
||||||
maxLength: {
|
maxLength: {
|
||||||
value: 255,
|
value: 255,
|
||||||
message: "Name should be less than 255 characters",
|
message: "Title should be less than 255 characters",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
render={({ field: { value, onChange } }) => (
|
render={({ field: { value, onChange } }) => (
|
||||||
@ -103,6 +103,7 @@ export const CycleForm: React.FC<Props> = (props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<span className="text-xs text-red-500">{errors?.name?.message}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Controller
|
<Controller
|
||||||
|
@ -116,10 +116,16 @@ export const InboxIssueCreateRoot: FC<TInboxIssueCreateRoot> = observer((props)
|
|||||||
setFormSubmitting(false);
|
setFormSubmitting(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isTitleLengthMoreThan255Character = formData?.name ? formData.name.length > 255 : false;
|
||||||
|
|
||||||
if (!workspaceSlug || !projectId || !workspaceId) return <></>;
|
if (!workspaceSlug || !projectId || !workspaceId) return <></>;
|
||||||
return (
|
return (
|
||||||
<form className="relative space-y-4" onSubmit={handleFormSubmit}>
|
<form className="relative space-y-4" onSubmit={handleFormSubmit}>
|
||||||
<InboxIssueTitle data={formData} handleData={handleFormData} />
|
<InboxIssueTitle
|
||||||
|
data={formData}
|
||||||
|
handleData={handleFormData}
|
||||||
|
isTitleLengthMoreThan255Character={isTitleLengthMoreThan255Character}
|
||||||
|
/>
|
||||||
<InboxIssueDescription
|
<InboxIssueDescription
|
||||||
workspaceSlug={workspaceSlug}
|
workspaceSlug={workspaceSlug}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
@ -138,7 +144,13 @@ export const InboxIssueCreateRoot: FC<TInboxIssueCreateRoot> = observer((props)
|
|||||||
<Button variant="neutral-primary" size="sm" type="button" onClick={handleModalClose}>
|
<Button variant="neutral-primary" size="sm" type="button" onClick={handleModalClose}>
|
||||||
Discard
|
Discard
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="primary" size="sm" type="submit" loading={formSubmitting}>
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
size="sm"
|
||||||
|
type="submit"
|
||||||
|
loading={formSubmitting}
|
||||||
|
disabled={isTitleLengthMoreThan255Character}
|
||||||
|
>
|
||||||
{formSubmitting ? "Adding Issue..." : "Add Issue"}
|
{formSubmitting ? "Adding Issue..." : "Add Issue"}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -121,10 +121,16 @@ export const InboxIssueEditRoot: FC<TInboxIssueEditRoot> = observer((props) => {
|
|||||||
setFormSubmitting(false);
|
setFormSubmitting(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isTitleLengthMoreThan255Character = formData?.name ? formData.name.length > 255 : false;
|
||||||
|
|
||||||
if (!workspaceSlug || !projectId || !workspaceId || !formData) return <></>;
|
if (!workspaceSlug || !projectId || !workspaceId || !formData) return <></>;
|
||||||
return (
|
return (
|
||||||
<div className="relative space-y-4">
|
<div className="relative space-y-4">
|
||||||
<InboxIssueTitle data={formData} handleData={handleFormData} />
|
<InboxIssueTitle
|
||||||
|
data={formData}
|
||||||
|
handleData={handleFormData}
|
||||||
|
isTitleLengthMoreThan255Character={isTitleLengthMoreThan255Character}
|
||||||
|
/>
|
||||||
<InboxIssueDescription
|
<InboxIssueDescription
|
||||||
workspaceSlug={workspaceSlug}
|
workspaceSlug={workspaceSlug}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
@ -138,7 +144,14 @@ export const InboxIssueEditRoot: FC<TInboxIssueEditRoot> = observer((props) => {
|
|||||||
<Button variant="neutral-primary" size="sm" type="button" onClick={handleModalClose}>
|
<Button variant="neutral-primary" size="sm" type="button" onClick={handleModalClose}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="primary" size="sm" type="button" loading={formSubmitting} onClick={handleFormSubmit}>
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
size="sm"
|
||||||
|
type="button"
|
||||||
|
loading={formSubmitting}
|
||||||
|
disabled={isTitleLengthMoreThan255Character}
|
||||||
|
onClick={handleFormSubmit}
|
||||||
|
>
|
||||||
{formSubmitting ? "Adding..." : "Add to project"}
|
{formSubmitting ? "Adding..." : "Add to project"}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,10 +6,11 @@ import { Input } from "@plane/ui";
|
|||||||
type TInboxIssueTitle = {
|
type TInboxIssueTitle = {
|
||||||
data: Partial<TIssue>;
|
data: Partial<TIssue>;
|
||||||
handleData: (issueKey: keyof Partial<TIssue>, issueValue: Partial<TIssue>[keyof Partial<TIssue>]) => void;
|
handleData: (issueKey: keyof Partial<TIssue>, issueValue: Partial<TIssue>[keyof Partial<TIssue>]) => void;
|
||||||
|
isTitleLengthMoreThan255Character?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const InboxIssueTitle: FC<TInboxIssueTitle> = observer((props) => {
|
export const InboxIssueTitle: FC<TInboxIssueTitle> = observer((props) => {
|
||||||
const { data, handleData } = props;
|
const { data, handleData, isTitleLengthMoreThan255Character } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex flex-wrap gap-2 items-center">
|
<div className="relative flex flex-wrap gap-2 items-center">
|
||||||
@ -21,9 +22,11 @@ export const InboxIssueTitle: FC<TInboxIssueTitle> = observer((props) => {
|
|||||||
onChange={(e) => handleData("name", e.target.value)}
|
onChange={(e) => handleData("name", e.target.value)}
|
||||||
placeholder="Title"
|
placeholder="Title"
|
||||||
className="w-full resize-none text-xl"
|
className="w-full resize-none text-xl"
|
||||||
maxLength={255}
|
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
{isTitleLengthMoreThan255Character && (
|
||||||
|
<span className="text-xs text-red-500">Title should be less than 255 characters</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -391,6 +391,8 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<span className="text-xs text-red-500">{errors?.name?.message}</span>
|
||||||
|
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
{data?.description_html === undefined ? (
|
{data?.description_html === undefined ? (
|
||||||
<Loader className="min-h-[7rem] space-y-2 overflow-hidden rounded-md border border-custom-border-200 p-2 py-2">
|
<Loader className="min-h-[7rem] space-y-2 overflow-hidden rounded-md border border-custom-border-200 p-2 py-2">
|
||||||
|
@ -90,7 +90,7 @@ export const ModuleForm: React.FC<Props> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div>
|
<div className="flex flex-col gap-1">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="name"
|
name="name"
|
||||||
@ -109,13 +109,14 @@ export const ModuleForm: React.FC<Props> = (props) => {
|
|||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
hasError={Boolean(errors.name)}
|
hasError={Boolean(errors?.name)}
|
||||||
placeholder="Module Title"
|
placeholder="Module Title"
|
||||||
className="w-full resize-none placeholder:text-sm placeholder:font-medium focus:border-blue-400"
|
className="w-full resize-none placeholder:text-sm placeholder:font-medium focus:border-blue-400"
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<span className="text-xs text-red-500">{errors?.name?.message}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Controller
|
<Controller
|
||||||
|
@ -216,6 +216,10 @@ export const ProjectDetailsForm: FC<IProjectDetailsForm> = (props) => {
|
|||||||
name="name"
|
name="name"
|
||||||
rules={{
|
rules={{
|
||||||
required: "Name is required",
|
required: "Name is required",
|
||||||
|
maxLength: {
|
||||||
|
value: 255,
|
||||||
|
message: "Project name should be less than 255 characters",
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
render={({ field: { value, onChange, ref } }) => (
|
render={({ field: { value, onChange, ref } }) => (
|
||||||
<Input
|
<Input
|
||||||
@ -232,9 +236,7 @@ export const ProjectDetailsForm: FC<IProjectDetailsForm> = (props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<span className="text-xs text-red-500">
|
<span className="text-xs text-red-500">{errors?.name?.message}</span>
|
||||||
<>{errors?.name?.message}</>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
<h4 className="text-sm">Description</h4>
|
<h4 className="text-sm">Description</h4>
|
||||||
|
@ -112,7 +112,7 @@ export const ProjectViewForm: React.FC<Props> = observer((props) => {
|
|||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<h3 className="text-lg font-medium leading-6 text-custom-text-100">{data ? "Update" : "Create"} View</h3>
|
<h3 className="text-lg font-medium leading-6 text-custom-text-100">{data ? "Update" : "Create"} View</h3>
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div>
|
<div className="flex flex-col gap-1">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="name"
|
name="name"
|
||||||
@ -137,6 +137,7 @@ export const ProjectViewForm: React.FC<Props> = observer((props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<span className="text-xs text-red-500">{errors?.name?.message}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Controller
|
<Controller
|
||||||
|
@ -125,6 +125,7 @@ export const CreateWorkspaceForm: FC<Props> = observer((props) => {
|
|||||||
Workspace Name
|
Workspace Name
|
||||||
<span className="ml-0.5 text-red-500">*</span>
|
<span className="ml-0.5 text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="name"
|
name="name"
|
||||||
@ -154,6 +155,8 @@ export const CreateWorkspaceForm: FC<Props> = observer((props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<span className="text-xs text-red-500">{errors?.name?.message}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1 text-sm">
|
<div className="space-y-1 text-sm">
|
||||||
<label htmlFor="workspaceUrl">
|
<label htmlFor="workspaceUrl">
|
||||||
|
Loading…
Reference in New Issue
Block a user