Remove mandatory task from measure

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-01-15 18:06:56 +01:00
parent 51b31f81f4
commit 3c2be844e4
13 changed files with 151 additions and 17 deletions

View File

@@ -11,12 +11,14 @@ type Props<TFieldValues extends FieldValues = FieldValues, TName extends FieldPa
label?: string;
error?: string;
disabled?: boolean;
optional?: boolean;
} & ComponentProps<typeof Field>;
export function MeasureSelectField<TFieldValues extends FieldValues = FieldValues>({
organizationId,
control,
disabled,
optional,
...props
}: Props<TFieldValues>) {
return (
@@ -29,6 +31,7 @@ export function MeasureSelectField<TFieldValues extends FieldValues = FieldValue
control={control}
name={props.name}
disabled={disabled}
optional={optional}
/>
</Suspense>
</Field>
@@ -36,10 +39,10 @@ export function MeasureSelectField<TFieldValues extends FieldValues = FieldValue
}
function MeasureSelectWithQuery<TFieldValues extends FieldValues = FieldValues>(
props: Pick<Props<TFieldValues>, "organizationId" | "control" | "name" | "disabled">
props: Pick<Props<TFieldValues>, "organizationId" | "control" | "name" | "disabled" | "optional">
) {
const { __ } = useTranslate();
const { name, organizationId, control, disabled } = props;
const { name, organizationId, control, disabled, optional } = props;
const { data } = usePaginatedMeasures(organizationId);
const [search, setSearch] = useState("");
const measures = useMemo(() => {
@@ -54,20 +57,36 @@ function MeasureSelectWithQuery<TFieldValues extends FieldValues = FieldValues>(
);
}, [data?.measures.edges, search]);
const allMeasures = useMemo(() => {
return data?.measures.edges?.map((edge) => edge.node) ?? [];
}, [data?.measures.edges]);
return (
<div>
<Controller
control={control}
name={name}
render={({ field }) => {
const selectedMeasure = field.value ? allMeasures?.find((m) => m.id === field.value) : null;
return (
<Combobox
id={name}
placeholder={__("Select a measure")}
value={search}
value={selectedMeasure ? selectedMeasure.name : search}
onSearch={setSearch}
disabled={disabled}
>
{optional && (
<ComboboxItem
onClick={() => {
field.onChange(null);
setSearch("");
}}
>
{__("None")}
</ComboboxItem>
)}
{measures?.map((m) => (
<ComboboxItem
key={m.id}

View File

@@ -75,8 +75,8 @@ const createTaskSchema = z.object({
timeEstimate: z.string().optional().nullable(),
assignedToId: z.string().optional().nullable(),
measureId: z.preprocess(
(val) => (val === "" || val == null ? undefined : val),
z.string({ required_error: "Measure is required" }).min(1, "Measure is required")
(val) => (val === "" || val == null ? null : val),
z.string().nullable().optional()
),
deadline: z.string().optional().nullable(),
});
@@ -85,8 +85,14 @@ const updateTaskSchema = z.object({
name: z.string().min(1),
description: z.string().optional().nullable(),
timeEstimate: z.string().optional().nullable(),
assignedToId: z.string().optional().nullable(),
measureId: z.string().optional(),
assignedToId: z.preprocess(
(val) => (val === "" || val == null ? null : val),
z.string().nullable().optional()
),
measureId: z.preprocess(
(val) => (val === "" || val == null ? null : val),
z.string().nullable().optional()
),
deadline: z.string().optional().nullable(),
});
@@ -135,6 +141,7 @@ export default function TaskFormDialog(props: Props) {
timeEstimate: data.timeEstimate || null,
deadline: formatDatetime(data.deadline) ?? null,
assignedToId: data.assignedToId ?? null,
measureId: data.measureId || null,
},
},
});
@@ -148,7 +155,7 @@ export default function TaskFormDialog(props: Props) {
timeEstimate: data.timeEstimate || null,
deadline: formatDatetime(data.deadline) ?? null,
assignedToId: data.assignedToId || null,
measureId: data.measureId,
measureId: data.measureId || null,
},
connections: [props.connection!],
},
@@ -162,7 +169,7 @@ export default function TaskFormDialog(props: Props) {
}
dialogRef.current?.close();
});
const showMeasure = !props.measureId && !isUpdating;
const showMeasure = !props.measureId;
return (
<Dialog
@@ -215,6 +222,7 @@ export default function TaskFormDialog(props: Props) {
name="measureId"
control={control}
organizationId={organizationId}
optional={true}
/>
</PropertyRow>
)}

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<1d9eed2918f5f58de18ef4ea5f0058b7>>
* @generated SignedSource<<8efad26dafbead83a13b59703edc7493>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -15,6 +15,7 @@ export type UpdateTaskInput = {
assignedToId?: string | null | undefined;
deadline?: any | null | undefined;
description?: string | null | undefined;
measureId?: string | null | undefined;
name?: string | null | undefined;
state?: TaskState | null | undefined;
taskId: string;