forked from github/plane
chore: number field validations
This commit is contained in:
parent
529a286954
commit
fff07a2353
@ -124,6 +124,8 @@ export const AttributeForm: React.FC<Props> = ({
|
|||||||
)}
|
)}
|
||||||
<div className="mt-8 flex items-center justify-between">
|
<div className="mt-8 flex items-center justify-between">
|
||||||
<div className="flex-shrink-0 flex items-center gap-2">
|
<div className="flex-shrink-0 flex items-center gap-2">
|
||||||
|
{data.type !== "checkbox" && (
|
||||||
|
<>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="is_required"
|
name="is_required"
|
||||||
@ -132,6 +134,8 @@ export const AttributeForm: React.FC<Props> = ({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<span className="text-xs">Mandatory field</span>
|
<span className="text-xs">Mandatory field</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<button
|
<button
|
||||||
|
@ -111,12 +111,12 @@ export const NumberAttributeForm: React.FC<FormComponentProps> = ({ control, wat
|
|||||||
placeholder="Maximum value"
|
placeholder="Maximum value"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
className="hide-arrows"
|
||||||
|
min={0}
|
||||||
step={1}
|
step={1}
|
||||||
|
required
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
rules={{
|
|
||||||
required: "This field is required",
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@ -125,9 +125,15 @@ export const NumberAttributeForm: React.FC<FormComponentProps> = ({ control, wat
|
|||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="extra_settings.color"
|
name="color"
|
||||||
render={({ field: { onChange, value } }) => (
|
render={({ field: { onChange, value } }) => (
|
||||||
<Input type="text" placeholder="Accent color" value={value} onChange={onChange} />
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="Accent color"
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,7 @@ import { Controller, useForm } from "react-hook-form";
|
|||||||
import { Props } from "./types";
|
import { Props } from "./types";
|
||||||
|
|
||||||
export const CustomEmailAttribute: React.FC<Props & { value: string | undefined }> = ({
|
export const CustomEmailAttribute: React.FC<Props & { value: string | undefined }> = ({
|
||||||
|
attributeDetails,
|
||||||
onChange,
|
onChange,
|
||||||
value,
|
value,
|
||||||
}) => {
|
}) => {
|
||||||
@ -57,6 +58,7 @@ export const CustomEmailAttribute: React.FC<Props & { value: string | undefined
|
|||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
className="text-xs px-2 py-0.5 bg-custom-background-80 rounded w-full outline-none"
|
className="text-xs px-2 py-0.5 bg-custom-background-80 rounded w-full outline-none"
|
||||||
|
required={attributeDetails.is_required}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -61,8 +61,8 @@ export const CustomNumberAttribute: React.FC<Props & { value: number | undefined
|
|||||||
<div
|
<div
|
||||||
className="absolute top-0 left-0 h-full"
|
className="absolute top-0 left-0 h-full"
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: extraSettings?.color ?? "rgb(var(--color-primary-100))",
|
backgroundColor: attributeDetails.color ?? "rgb(var(--color-primary-100))",
|
||||||
width: `${(value / parseInt(extraSettings.divided_by, 10)) * 100}%`,
|
width: `${(value / parseInt(extraSettings.divided_by ?? 100, 10)) * 100}%`,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -73,9 +73,9 @@ export const CustomNumberAttribute: React.FC<Props & { value: number | undefined
|
|||||||
<span className="flex-shrink-0 font-medium">{value}</span>
|
<span className="flex-shrink-0 font-medium">{value}</span>
|
||||||
)}
|
)}
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
activeStrokeColor={extraSettings?.color ?? "rgb(var(--color-primary-100))"}
|
activeStrokeColor={attributeDetails.color ?? "rgb(var(--color-primary-100))"}
|
||||||
value={value}
|
value={value}
|
||||||
maxValue={parseInt(extraSettings.divided_by, 10)}
|
maxValue={parseInt(extraSettings.divided_by ?? 100, 10)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@ -96,6 +96,10 @@ export const CustomNumberAttribute: React.FC<Props & { value: number | undefined
|
|||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
className="hide-arrows text-xs px-2 py-0.5 bg-custom-background-80 rounded w-full outline-none"
|
className="hide-arrows text-xs px-2 py-0.5 bg-custom-background-80 rounded w-full outline-none"
|
||||||
|
step={1}
|
||||||
|
min={extraSettings.divided_by ? 0 : undefined}
|
||||||
|
max={extraSettings.divided_by ?? undefined}
|
||||||
|
required={attributeDetails.is_required}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -6,6 +6,7 @@ import { Controller, useForm } from "react-hook-form";
|
|||||||
import { Props } from "./types";
|
import { Props } from "./types";
|
||||||
|
|
||||||
export const CustomTextAttribute: React.FC<Props & { value: string | undefined }> = ({
|
export const CustomTextAttribute: React.FC<Props & { value: string | undefined }> = ({
|
||||||
|
attributeDetails,
|
||||||
onChange,
|
onChange,
|
||||||
value,
|
value,
|
||||||
}) => {
|
}) => {
|
||||||
@ -57,6 +58,7 @@ export const CustomTextAttribute: React.FC<Props & { value: string | undefined }
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="text-xs px-2 py-0.5 bg-custom-background-80 rounded w-full outline-none"
|
className="text-xs px-2 py-0.5 bg-custom-background-80 rounded w-full outline-none"
|
||||||
|
required={attributeDetails.is_required}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -6,6 +6,7 @@ import { Controller, useForm } from "react-hook-form";
|
|||||||
import { Props } from "./types";
|
import { Props } from "./types";
|
||||||
|
|
||||||
export const CustomUrlAttribute: React.FC<Props & { value: string | undefined }> = ({
|
export const CustomUrlAttribute: React.FC<Props & { value: string | undefined }> = ({
|
||||||
|
attributeDetails,
|
||||||
onChange,
|
onChange,
|
||||||
value,
|
value,
|
||||||
}) => {
|
}) => {
|
||||||
@ -57,6 +58,7 @@ export const CustomUrlAttribute: React.FC<Props & { value: string | undefined }>
|
|||||||
<input
|
<input
|
||||||
type="url"
|
type="url"
|
||||||
className="text-xs px-2 py-0.5 bg-custom-background-80 rounded w-full outline-none"
|
className="text-xs px-2 py-0.5 bg-custom-background-80 rounded w-full outline-none"
|
||||||
|
required={attributeDetails.is_required}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// icons
|
// icons
|
||||||
import {
|
import {
|
||||||
AtSign,
|
AtSign,
|
||||||
Baseline,
|
|
||||||
CaseSensitive,
|
CaseSensitive,
|
||||||
CheckCircle,
|
CheckCircle,
|
||||||
Clock4,
|
Clock4,
|
||||||
@ -91,10 +90,10 @@ export const CUSTOM_ATTRIBUTES_LIST: {
|
|||||||
},
|
},
|
||||||
number: {
|
number: {
|
||||||
defaultFormValues: {
|
defaultFormValues: {
|
||||||
|
color: "#000000",
|
||||||
default_value: "",
|
default_value: "",
|
||||||
display_name: "",
|
display_name: "",
|
||||||
extra_settings: {
|
extra_settings: {
|
||||||
color: "Blue",
|
|
||||||
divided_by: 100,
|
divided_by: 100,
|
||||||
representation: "numerical",
|
representation: "numerical",
|
||||||
show_number: true,
|
show_number: true,
|
||||||
@ -109,10 +108,6 @@ export const CUSTOM_ATTRIBUTES_LIST: {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
option: {
|
|
||||||
icon: Baseline,
|
|
||||||
label: "Option",
|
|
||||||
},
|
|
||||||
relation: {
|
relation: {
|
||||||
defaultFormValues: { display_name: "", is_multi: false, is_required: false, unit: "cycle" },
|
defaultFormValues: { display_name: "", is_multi: false, is_required: false, unit: "cycle" },
|
||||||
icon: Forward,
|
icon: Forward,
|
||||||
|
@ -63,7 +63,7 @@ class CustomAttributeValuesStore {
|
|||||||
|
|
||||||
newChildren.map((child) => {
|
newChildren.map((child) => {
|
||||||
if (attributesToUpdate.includes(child.id) && child)
|
if (attributesToUpdate.includes(child.id) && child)
|
||||||
child.prop_value = [{ type: "", value: data.issue_properties[child.id] }];
|
child.prop_value = [{ type: 0, value: data.issue_properties[child.id] }];
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
});
|
});
|
||||||
|
39
web/types/custom-attributes.d.ts
vendored
39
web/types/custom-attributes.d.ts
vendored
@ -14,6 +14,37 @@ export type TCustomAttributeTypes =
|
|||||||
|
|
||||||
export type TCustomAttributeUnits = "cycle" | "issue" | "module" | "user" | null;
|
export type TCustomAttributeUnits = "cycle" | "issue" | "module" | "user" | null;
|
||||||
|
|
||||||
|
// export type TCustomAttributeExtraSettings =
|
||||||
|
// | {
|
||||||
|
// type: "checkbox";
|
||||||
|
// extra_settings: {
|
||||||
|
// representation: "check" | "toggle_switch";
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// | {
|
||||||
|
// type: "datetime";
|
||||||
|
// extra_settings: {
|
||||||
|
// date_format: "DD-MM-YYYY" | "MM-DD-YYYY" | "YYYY-MM-DD";
|
||||||
|
// hide_date: boolean;
|
||||||
|
// hide_time: boolean;
|
||||||
|
// time_format: "12" | "24";
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// | {
|
||||||
|
// type: "files";
|
||||||
|
// extra_settings: {
|
||||||
|
// file_formats: string[];
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// | {
|
||||||
|
// type: "number";
|
||||||
|
// extra_settings: {
|
||||||
|
// divided_by: number;
|
||||||
|
// representation: "numerical" | "bar" | "ring";
|
||||||
|
// show_number: boolean;
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
|
||||||
export interface ICustomAttribute {
|
export interface ICustomAttribute {
|
||||||
children: ICustomAttribute[];
|
children: ICustomAttribute[];
|
||||||
color: string;
|
color: string;
|
||||||
@ -40,10 +71,16 @@ export interface ICustomAttributeValue {
|
|||||||
name: string;
|
name: string;
|
||||||
prop_value:
|
prop_value:
|
||||||
| {
|
| {
|
||||||
type: string;
|
type: 0 | 1;
|
||||||
value: string;
|
value: string;
|
||||||
}[]
|
}[]
|
||||||
| null;
|
| null;
|
||||||
|
prop_extra:
|
||||||
|
| {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[]
|
||||||
|
| null;
|
||||||
type: TCustomAttributeTypes;
|
type: TCustomAttributeTypes;
|
||||||
unit: TCustomAttributeUnits;
|
unit: TCustomAttributeUnits;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user